当前位置: 首页 > news >正文

OpenCV Python——图像查找(特征匹配 + 单应性矩阵)

  • 1 图像查找(单应性矩阵)
  • 2 单应性矩阵 应用举例
  • 3 单应性矩阵 代码示例

P87 11

1 图像查找(单应性矩阵)

特征匹配作为输入,获得单应性矩阵
在这里插入图片描述

X在img1和img2中的成像分别为x,x'

图中H即为单应性矩阵
在这里插入图片描述

2 单应性矩阵 应用举例

获取一个矩阵,通过与图像1就算可以得到图像2对应点的位置;
图像二通过计算可以得到点原始位置,同样图像一也可以经过计算得到点原始位置;

自动转正

在这里插入图片描述
更换广告牌中的内容
在这里插入图片描述

3 单应性矩阵 代码示例

在一节FLANN特征匹配的基础上增加了,单应性矩阵、透视变换、框图

#获取的单应性矩阵
#srcPts从匹配点good中获取,每次遍历都可以从kp1[m.queryIdx]中获取一个关键点
#关键点需要转成浮点型
#对获取到的关键点要重新变换reshape(-1, 1, 2),x值随意,y值1,z值2,即无数行,每行一个元素,每个元素有2个子元素
#queryIdx,trainIdx分别是第一幅图,第二幅图的描述子索引值
if len(good) >= 4:#单应性矩阵要求匹配点要大于等于4srcPts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)#原关键点dstPts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)#目标关键点#单应性矩阵H, mask = cv2.findHomography(srcPts, dstPts, cv2.RANSAC, 5.0)#cv2.RANSAC对错误匹配点过滤,阈值1~10,这里是5#透视变换#获取要搜索的图的四个角点(左上,左下,右下,右上),同样需要转成浮点型,然后reshapeh, w = img1.shape[:2]pts = np.float32([[0,0], [0, h-1], [w-1, h-1], [w-1, 0]]).reshape(-1, 1, 2)dst = cv2.perspectiveTransform(pts, H)#多边形绘制,将找到的子图在原图中框出来吧cv2.polylines(img2, [np.int32(dst)], True, (0, 0, 255))#目标图,32位整形,TRUE封口,
else:print('the number of good is less than 4.')exit()

效果如下:

在这里插入图片描述

完整代码

import cv2
import numpy as np#读文件
img1 = cv2.imread('opencv_search.png')
img2 = cv2.imread('opencv_orig.png')#灰度化
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)#创建sift对象                                                       
sift= cv2.xfeatures2d.SIFT_create()#进行检测关键点,同时计算描述子
kp1 ,des1= sift.detectAndCompute(gray1, None)#掩码设置为NONE,即对整张图检测
kp2 ,des2= sift.detectAndCompute(gray2, None)#掩码设置为NONE,即对整张图检测#创建flann匹配器
index_params=dict(algorithm=1,tree=5)
search_params=dict(checks=50)flann=cv2.FlannBasedMatcher(index_params,search_params)#对描述子进行特征匹配
matches=flann.knnMatch(des1,des2,k=2)#对匹配点优化过滤
good=[]
for i,(m,n) in enumerate(matches):#对img1,img2中的匹配点进行遍历if m.distance < 0.7* n.distance:#越小越精准good.append(m)#获取的单应性矩阵
#srcPts从匹配点good中获取,每次遍历都可以从kp1[m.queryIdx]中获取一个关键点
#关键点需要转成浮点型
#对获取到的关键点要重新变换reshape(-1, 1, 2),x值随意,y值1,z值2,即无数行,每行一个元素,每个元素有2个子元素
#queryIdx,trainIdx分别是第一幅图,第二幅图的描述子索引值
if len(good) >= 4:#单应性矩阵要求匹配点要大于等于4srcPts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)#原关键点dstPts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)#目标关键点#单应性矩阵H, mask = cv2.findHomography(srcPts, dstPts, cv2.RANSAC, 5.0)#cv2.RANSAC对错误匹配点过滤,阈值1~10,这里是5#透视变换#获取要搜索的图的四个角点(左上,左下,右下,右上),同样需要转成浮点型,然后reshapeh, w = img1.shape[:2]pts = np.float32([[0,0], [0, h-1], [w-1, h-1], [w-1, 0]]).reshape(-1, 1, 2)dst = cv2.perspectiveTransform(pts, H)#多边形绘制,将找到的子图在原图中框出来吧cv2.polylines(img2, [np.int32(dst)], True, (0, 0, 255))#目标图,32位整形,TRUE封口,
else:print('the number of good is less than 4.')exit()#绘制匹配结果
img3=cv2.drawMatchesKnn(img1,kp1,img2,kp2,[good],None)cv2.imshow('img3', img3)
cv2.waitKey(0)
http://www.lryc.cn/news/621712.html

相关文章:

  • 【解决笔记】MyBatis-Plus 中无 selectList 方法
  • Linux815 shell:while
  • 鸿蒙任务调度机制深度解析:优先级、时间片、多核与分布式的流畅秘密
  • 我的学习认知、高效方法与知识积累笔记
  • Ubuntu20.04下Px4使用UORB发布消息
  • 风场可视化 - 双分量数据
  • python30-正则表达式
  • Kotlin作用域函数全解:run/with/apply/let/also与this/it的魔法对决
  • shell脚本实现sha256sum校验并拷贝校验通过的文件
  • 【Spring框架】SpringIOC
  • 代码随想录二刷之“字符串”~GO
  • 状态管理中应用进程和宿主进程的概念及相互关系
  • 初识CNN02——认识CNN2
  • Jeecg后端经验汇总
  • redis-sentinel基础概念及部署
  • JVM执行引擎深入理解
  • 异步开发:协程、线程、Unitask
  • 关于C++的#include的超超超详细讲解
  • LCR 076. 数组中的第 K 个最大元素
  • IStoreOS(OpenWrt)开启IPV6
  • 【已解决】在Spring Boot工程中,若未识别到resources/db文件夹下的SQL文件
  • 10--C++模板参数与特化详解
  • Linux Namespace隔离实战:dd/mkfs/mount/unshare构建终极沙箱
  • 基于CodeBuddy的2D游戏开发实践:炫酷大便超人核心机制解析
  • 云手机存储和本地存储的区别
  • Ant-Design AUpload如何显示缩略图;自定义哪些类型的数据可以使用img预览
  • 用3D打印重新定义骑行-中科米堆CASAIM自行车座椅个性化设计
  • Spring Ai 如何配置以及如何搭建
  • Cursor CLI 技术解析:免费调用 GPT-5 的命令行方案
  • Flink的状态管理