在OpenCV里使用特征匹配和单映射变换的代码详解


Posted in Python onOctober 23, 2019

前面已经学习特征查找和对应匹配,接着下来在特征匹配之后,再使用findHomography函数来找出对应图像的投影矩阵。首先使用一个查询图片,然后在另外一张图片里找到目标对象,其实就是想在图片里查找所需要目标的一部分区域。为了实现这样的功能,需要使用calib3d库里的一个函数cv.findHomography(),把从两张图片里找到的特征点当作参数,传送给这个函数,然后这个函数返回一个投影变换矩阵,我们就可以使用 cv.perspectiveTransform()函数来对查找的目标进行投影,这样就可以在复杂图片里标记出相应的目标位置。

我们已经看到,在匹配时可能会有一些错误,这可能会影响结果。为了解决这个问题,需要使用RANSAC 或 LEAST_MEDIAN算法。所以提供正确估计的良好匹配称为内聚,其余的称为外联。cv.findHomography()函数返回一个值表示内聚还是外联的点。

在例子里,先使用ORB来寻找两个图片的特征点,接着根据设置条件为10个匹配特征,如果满足就会计算投影变换矩阵,一旦获得3x3的矩阵,就可以把寻找的目标对象在图片里标记出来。最后在复杂的图片里用白色线条标记出来。

在OpenCV里使用特征匹配和单映射变换的代码详解

参数详解:

srcPoints 源平面中点的坐标矩阵,可以是CV_32FC2类型,也可以是vector<Point2f>类型

dstPoints 目标平面中点的坐标矩阵,可以是CV_32FC2类型,也可以是vector<Point2f>类型

method 计算单应矩阵所使用的方法。不同的方法对应不同的参数,具体如下:

0 - 利用所有点的常规方法

RANSAC - RANSAC-基于RANSAC的鲁棒算法

LMEDS - 最小中值鲁棒算法

RHO - PROSAC-基于PROSAC的鲁棒算法

ransacReprojThreshold

将点对视为内点的最大允许重投影错误阈值(仅用于RANSAC和RHO方法)。如果

则点被认为是个外点(即错误匹配点对)。若srcPoints和dstPoints是以像素为单位的,则该参数通常设置在1到10的范围内。

mask

可选输出掩码矩阵,通常由鲁棒算法(RANSAC或LMEDS)设置。 请注意,输入掩码矩阵是不需要设置的。

maxIters RANSAC算法的最大迭代次数,默认值为2000。

confidence 可信度值,取值范围为0到1.

该函数能够找到并返回源平面和目标平面之间的转换矩阵H,以便于反向投影错误率达到最小。

在OpenCV里使用特征匹配和单映射变换的代码详解

演示使用的例子如下:

#python 3.7.4,opencv4.1
#蔡军生 https://blog.csdn.net/caimouse/article/details/51749579
#
import numpy as np
import cv2
from matplotlib import pyplot as plt
 
MIN_MATCH_COUNT = 10
 
#读取文件
img1 = cv2.imread('rmb3.png')
img2 = cv2.imread('rmb4.png')
 
#初始化ORB检测器
orb = cv2.ORB_create()
 
#用ORB查找关键点
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)
 
# FLANN参数
FLANN_INDEX_LSH = 6
index_params = dict(algorithm = FLANN_INDEX_LSH,
          table_number = 6, 
          key_size = 12,   
          multi_probe_level = 1)
search_params = dict(checks=50)  #或者使用一个空的字典
flann = cv2.FlannBasedMatcher(index_params,search_params)
 
matches = flann.knnMatch(des1,des2,k=2)
 
# 比率
good = []
for m,n in matches:
  if m.distance < 0.7*n.distance:
    good.append(m)
if len(good)>MIN_MATCH_COUNT:
  src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
  dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
  #找到投影变换矩阵
  M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
  matchesMask = mask.ravel().tolist()
  #进行投影变换
  h,w,d = img1.shape
  pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
  dst = cv2.perspectiveTransform(pts,M)
  #画变换后的外形
  img2 = cv2.polylines(img2,[np.int32(dst)],True,(255,255,255),3, cv2.LINE_AA)
 
else:
  print( "Not enough matches are found - {}/{}".format(len(good), MIN_MATCH_COUNT) )
  matchesMask = Non
 
draw_params = dict(matchColor = (0,255,0), # draw matches in green color
          singlePointColor = None,
          matchesMask = matchesMask, # draw only inliers
          flags = 2)
 
img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params)
 
#显示图片
cv2.imshow('img3',img3)
      
cv2.waitKey(0)
cv2.destroyAllWindows()

结果输出如下:

在OpenCV里使用特征匹配和单映射变换的代码详解

总结

以上所述是小编给大家介绍的在OpenCV里使用特征匹配和单映射变换的代码详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
python操作MongoDB基础知识
Nov 01 Python
Python中的对象,方法,类,实例,函数用法分析
Jan 15 Python
Python实现删除时保留特定文件夹和文件的示例
Apr 27 Python
Atom的python插件和常用插件说明
Jul 08 Python
Linux下安装python3.6和第三方库的教程详解
Nov 09 Python
详解如何在Apache中运行Python WSGI应用
Jan 02 Python
Python3.5模块的定义、导入、优化操作图文详解
Apr 27 Python
详解numpy矩阵的创建与数据类型
Oct 18 Python
Python类反射机制使用实例解析
Dec 30 Python
pytorch绘制并显示loss曲线和acc曲线,LeNet5识别图像准确率
Jan 02 Python
Tensorflow 定义变量,函数,数值计算等名字的更新方式
Feb 10 Python
python dict乱码如何解决
Jun 07 Python
手把手教你Python yLab的绘制折线图的画法
Oct 23 #Python
Python之Numpy的超实用基础详细教程
Oct 23 #Python
Python从列表推导到zip()函数的5种技巧总结
Oct 23 #Python
Python箱型图绘制与特征值获取过程解析
Oct 22 #Python
Python使用贪婪算法解决问题
Oct 22 #Python
python元组和字典的内建函数实例详解
Oct 22 #Python
Python List列表对象内置方法实例详解
Oct 22 #Python
You might like
特详细的PHPMYADMIN简明安装教程
2008/08/01 PHP
php根据身份证号码计算年龄的实例代码
2014/01/18 PHP
PHP中使用正则表达式提取中文实现笔记
2015/01/20 PHP
动态表单验证的操作方法和TP框架里面的ajax表单验证
2017/07/19 PHP
javascript中&quot;/&quot;运算符常见错误
2010/10/13 Javascript
js去除重复字符串两种实现方法
2013/01/09 Javascript
表单元素的submit()方法和onsubmit事件应用概述
2013/02/01 Javascript
判断ie的两种简单方法
2013/08/12 Javascript
利用jquery包将字符串生成二维码图片
2013/09/12 Javascript
JavaScript获取某年某月的最后一天附截图
2014/06/23 Javascript
用模版生成HTML的的框架jquery.tmpl使用详解
2015/01/07 Javascript
基于javascript实现浏览器滚动条快到底部时自动加载数据
2015/11/30 Javascript
js HTML5多媒体影音播放
2016/10/17 Javascript
NodeJS使用formidable实现文件上传
2016/10/27 NodeJs
浅谈webpack打包之后的文件过大的解决方法
2018/03/07 Javascript
通过一次报错详细谈谈Point事件
2018/05/17 Javascript
引入外部js脚本加载慢与页面白屏问题的解决
2018/12/10 Javascript
详解微信小程序-canvas绘制文字实现自动换行
2019/04/26 Javascript
vuex实现数据状态持久化
2019/11/11 Javascript
微信小程序wxs实现吸顶效果
2020/01/08 Javascript
jquery.validate自定义验证用法实例分析【成功提示与择要提示】
2020/06/06 jQuery
微信小程序实现购物车小功能
2020/12/30 Javascript
[02:37]TI8勇士令状不朽珍藏II视频展示
2018/06/23 DOTA
python3批量删除豆瓣分组下的好友的实现代码
2016/06/07 Python
Python爬取数据并写入MySQL数据库的实例
2018/06/21 Python
Python深拷贝与浅拷贝用法实例分析
2019/05/05 Python
libreoffice python 操作word及excel文档的方法
2019/07/04 Python
python GUI库图形界面开发之PyQt5图片显示控件QPixmap详细使用方法与实例
2020/02/27 Python
HTML5中视频音频的使用详解
2017/07/07 HTML / CSS
html5 canvas 实现光线沿不规则路径运动
2020/04/20 HTML / CSS
DC Shoes澳大利亚官方网上商店:购买DC鞋子
2019/10/25 全球购物
小学生安全演讲稿
2014/04/25 职场文书
小摄影师教学反思
2014/04/27 职场文书
中学生自我评价范文
2015/03/03 职场文书
家长会主持词开场白
2015/05/29 职场文书
蔬果开业典礼发言稿应该怎么写?
2019/09/03 职场文书