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

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.xdnf.cn/news/17868.html

相关文章:

  • Kotlin作用域函数全解:run/with/apply/let/also与this/it的魔法对决
  • fs模块_写入文件
  • Layers(图层)
  • OpenSCA开源社区每日安全漏洞及投毒情报资讯|14th Aug. , 2025
  • 【车联网kafka】常用参数及其命令总结(第八篇)
  • Backblaze 2025 Q2硬盘故障率报告解读
  • Web攻防-大模型应用LLM安全提示词注入不安全输出代码注入直接间接数据投毒
  • CAXA电子图板2026(国产CAD之光)
  • C# 中的 string / StringBuilder / 值类型 / 引用类型 / CLR 总结
  • Design Compiler:使用IC Compiler II Link
  • Tasking编译问题: E207: syntax error - token “<integer>“ delete的解决方案
  • 【机器学习】核心分类及详细介绍
  • 电视同轴电缆全面指南:从基础到应用,批量测量一键计量
  • 【博客系统测试报告】---web界面自动化测试
  • 使用PyTorch实现手写数字识别系统:从理论到实践
  • 附045.Kubernetes_v1.33.2高可用部署架构二
  • 介绍大根堆小根堆
  • C++——分布式
  • 从 0 到 1 玩转Claude code(蓝耘UI界面版本):AI 编程助手的服务器部署与实战指南
  • Unity 绳子插件 ObjRope 使用简记
  • C#文件复制异常深度剖析:解决“未能找到文件“之谜
  • 硬件开发_基于STM32单片机的热水壶系统
  • 领域防腐层(ACL)在遗留系统改造中的落地
  • 疯狂星期四文案网第40天运营日记
  • 分布式锁那些事
  • AI浪潮之巅:解码技术革命、重塑产业生态与构建责任未来
  • 超高车辆碰撞预警系统如何帮助提升城市立交隧道安全?
  • uniApp App 端日志本地存储方案:实现可靠的日志记录功能
  • 【python实用小脚本-187】Python一键批量改PDF文字:拖进来秒出新文件——再也不用Acrobat来回导
  • RH134 管理存储堆栈知识点