opencv4 图像特征匹配_openCV - 图像特征匹配
目标
本章节中
- 我们将实现如何不同图像之间匹配特征.
- 将使用两种匹配器,openCV提供了Brute-Force 和 FLANN
Brute-Force 匹配器的基本原理
Brute-Force匹配器很简单。它采用第一个集合中一个特征的描述符,并通过距离计算与第二个集合中的所有其他特征匹配,返回最近的一个。对于BF匹配器,首先必须使用cv.BFMatcher()创建BFMatcher对象。它需要两个可选参数。第一个是normType。它指定要使用的距离度量。默认情况下,它是cv.NORM_L2。适用于SIFT、SURF等。cv.NORM_L1也在那里)。对于基于二进制字符串的描述符,如ORB、BRIEF、lively等,使用cv.NORM_HAMMING,它使用Hamming distance作为度量。如果ORB使用WTA_K == 3或4,则使用cv.NORM_HAMMING2。
第二个参数是布尔变量crossCheck,默认为false。如果为真,Matcher只返回值为(i,j)的匹配项,以便集合A中的第i个描述符与集合B中的第j个描述符具有最佳匹配,反之亦然。也就是说,两个集合中的两个特性应该相互匹配。它可以得到可靠的结果,是D.Lowe的论文中提出的一个比值检验很好的替代法。创建之后,两个重要的方法是BFMatcher.match()和BFMatcher.knnMatch()。第一个返回最佳匹配。第二个方法返回由用户指定的k的最佳匹配。当我们需要在这方面做额外的工作时,它可能是有用的。
就像我们使用了cv.drawKeypoints()来绘制关键点一样,cv.drawMatches()帮助我们绘制匹配项。它水平地堆叠两个图像,并从第一个图像到第二个图像绘制线,以显示最佳匹配。还有cv.drawMatchesKnn可以画出所有k个最佳匹配项。如果k=2,它将为每个关键点绘制两条匹配线。所以我们必须传递一个蒙版如果我们想有选择地画它。让我们来分别看看用SURF和ORB的示例 (它们都使用不同的距离测量)。
BF 匹配 ORB 描述子
在这里,我们将看到一个关于如何在两个图像之间匹配特性的简单示例。在本例中,我有一个queryImage和一个trainImage。我们将尝试使用特征匹配在trainImage中找到queryImage。
( 实例图像 /samples/c/box.png and /samples/c/box_in_scene.png)
我们使用ORB描述符来匹配特性。让我们从加载图像开始,寻找描述符等等。
import numpy as npimport cv2 as cvimport matplotlib.pyplot as pltimg1 = cv.imread('box.png',0) # queryImageimg2 = cv.imread('box_in_scene.png',0) # trainImage# Initiate ORB detectororb = cv.ORB_create()# find the keypoints and descriptors with ORBkp1, des1 = orb.detectAndCompute(img1,None)kp2, des2 = orb.detectAndCompute(img2,None)
接下来,我们创建一个带有距离测量的BFMatcher对象。cv.NORM_HAMMING(因为我们使用ORB)和crossCheck被打开以获得更好的结果。然后我们使用Matcher.match()方法在两个图像中获得最佳匹配。我们按照它们之间距离的升序对它们进行排序,以便最好的匹配(低距离)出现在前面。然后我们只绘制前10个匹配项(只是为了便于查看)。你可以随意增加)
# create BFMatcher objectbf = cv.BFMatcher(cv.NORM_HAMMING, crossCheck=True)# Match descriptors.matches = bf.match(des1,des2)# Sort them in the order of their distance.matches = sorted(matches, key = lambda x:x.distance)# Draw first 10 matches.img3 = cv.drawMatches(img1,kp1,img2,kp2,matches[:10], flags=2)plt.imshow(img3),plt.show()
以下就是我们得到的结果:
什么是匹配器对象?
代码行中 matches = bf.match(des1,des2) 返回的结果是 DMatch 对象的列表. 这个DMatch 对象有以下属性:
- DMatch.distance - 描述子之间的距离. 越小越好.
- DMatch.trainIdx - 训练集中的描述子的索引
- DMatch.queryIdx - 检索集中的描述子的索引
- DMatch.imgIdx - 训练集图像的索引.
BF 匹配 SIFT 描述子和比值检测
这次,我们将使用BFMatcher.knnMatch()获得k个最佳匹配。在这个例子中,我们取k=2,这样我们就可以应用D.Lowe在论文中解释的比值检验。
import numpy as npimport cv2 as cvfrom matplotlib import pyplot as pltimg1 = cv.imread('box.png',0) # queryImageimg2 = cv.imread('box_in_scene.png',0) # trainImage# Initiate SIFT detectorsift = cv.SIFT()# find the keypoints and descriptors with SIFTkp1, des1 = sift.detectAndCompute(img1,None)kp2, des2 = sift.detectAndCompute(img2,None)# BFMatcher with default paramsbf = cv.BFMatcher()matches = bf.knnMatch(des1,des2, k=2)# Apply ratio testgood = []for m,n in matches: if m.distance < 0.75*n.distance: good.append([m])# cv.drawMatchesKnn expects list of lists as matches.img3 = cv.drawMatchesKnn(img1,kp1,img2,kp2,good,flags=2)plt.imshow(img3),plt.show()
以下得到结果:
基于FLANN 匹配器
FLANN是Fast Library for Approximate Nearest Neighbors的缩写。它包含一组优化算法,用于在大型数据集中快速搜索最近邻和高维特性。对于大型数据集,它比BFMatcher工作得更快。我们将看到基于FLANN的匹配器的第二个例子。
对于基于FLANN的匹配器,我们需要通过两个字典来指定要使用的算法及其相关参数等。第一个是IndexParams。对于各种算法,要传递的信息在FLANN文档中进行了解释。作为总结,对于SIFT、SURF等算法,您可以通过以下步骤:
FLANN_INDEX_KDTREE = 1index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
在使用ORB时,您可以传递以下内容。注释值是根据文档推荐的,但在某些情况下它没有提供所需的结果。其他的值可能会更好:
FLANN_INDEX_LSH = 6index_params= dict(algorithm = FLANN_INDEX_LSH, table_number = 6, # 12 key_size = 12, # 20 multi_probe_level = 1) #2
第二个字典是SearchParams。它指定应该递归遍历索引中的树的次数。数值越大,精度越高,但也需要更多的时间。如果要更改值,请传递search_params = dict(check =100)。有了这些信息,我们可以开始了。
import numpy as npimport cv2 as cvfrom matplotlib import pyplot as pltimg1 = cv.imread('box.png',0) # queryImageimg2 = cv.imread('box_in_scene.png',0) # trainImage# Initiate SIFT detectorsift = cv.SIFT()# find the keypoints and descriptors with SIFTkp1, des1 = sift.detectAndCompute(img1,None)kp2, des2 = sift.detectAndCompute(img2,None)# FLANN parametersFLANN_INDEX_KDTREE = 1index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)search_params = dict(checks=50) # or pass empty dictionaryflann = cv.FlannBasedMatcher(index_params,search_params)matches = flann.knnMatch(des1,des2,k=2)# Need to draw only good matches, so create a maskmatchesMask = [[0,0] for i in xrange(len(matches))]# ratio test as per Lowe's paperfor i,(m,n) in enumerate(matches): if m.distance < 0.7*n.distance: matchesMask[i]=[1,0]draw_params = dict(matchColor = (0,255,0), singlePointColor = (255,0,0), matchesMask = matchesMask, flags = 0)img3 = cv.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,**draw_params)plt.imshow(img3,),plt.show()
请看结果如下:
opencv4 图像特征匹配_openCV - 图像特征匹配相关推荐
- python图像特征提取与匹配_图像特征特点及其常用的特征提取与匹配方法
常用的图像特征有颜色特征.纹理特征.形状特征.空间关系特征. 一颜色特征 (一)特点:颜色特征是一种全局特征,描述了图像或图像区域所对应的景物的表面性质.一般颜色特征是基于像素点的特征,此时所有属于图 ...
- OpenCV—python 模板匹配与图像特征匹配
文章目录 一.理论介绍与算法 二.算法代码 单目标匹配 多目标匹配 三 多尺度模板匹配 一.理论介绍与算法 模板匹配是在一幅图像中寻找一个特定目标的方法之一,这种方法的原理非常简单,遍历图像中的每一个 ...
- getvalue参数计数不匹配_OpenCV开发笔记(六十八):红胖子8分钟带你使用特征点Flann最邻近差值匹配识别...
若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/ ...
- Java OpenCV-4.0.0 图像处理22 图像模板匹配
Java OpenCV-4.0.0 图像处理22 图像模板匹配 参考链接:https://blog.csdn.net/qq_34814092/article/details/95813654 Java ...
- Nature科学报告:根据大脑思维意图来生成对应匹配的图像
点击上面"脑机接口社区"关注我们 更多技术干货第一时间送达 导读 脑机接口可以进行主动通信并执行一组预定义的命令,例如键入字母或移动光标.但是,到目前为止,他们还无法根据大脑信号推 ...
- opencv上gpu版surf特征点与orb特征点提取及匹配实例
opencv上gpu版surf特征点与orb特征点提取及匹配实例 标签: gpu版surfgpu orbsurf和orbgpu surf及orbsurf orb gpu 2016-09-25 23:4 ...
- 图像相似度测量与模板匹配总结
摘要 本文主要总结了进行目标跟踪.检测中经常使用到的图像相似度测量和模板匹配方法,并给出了具体的基于OpenCV的代码实现. 引言 模板匹配是一种在源图像中寻找与图像patch最相似的技术,常常用来进 ...
- 【图像处理】——特征匹配(SIFT特征检测器+FLANN特征匹配方法+KNN近邻最优匹配筛选)——cv.xfeatures2d.SIFT_create()sift.detectAndCompute
转载请注明地址 目录 1.特征检测和特征匹配方法 (1)特征检测算法 (2)特征匹配算法 (3)各种特征检测算法的比较 2.特征匹配的基本步骤(附带主要的函数) (1)图像预处理--灰度化(模板--查 ...
- OpenCV与图像处理学习十二——图像形状特征之HOG特征
OpenCV与图像处理学习十二--图像形状特征之HOG特征 一.图像特征理解 1.1 颜色特征 1.2 纹理特征 1.3 形状特征 1.4 空间关系特征 二.形状特征描述 2.1 HOG特征 2.1. ...
最新文章
- Java面试题之一 (转)
- Java调用WebService接口实现发送手机短信验证码功能
- 建造者模式 coding
- sphinx和coreseek
- poj 1325 Machine Schedule 最小顶点覆盖
- rtklib 后处理_RTKLIB 手册解读及代码调试知识总结
- Quartz 2.x 任务调度使用(CronTrigger)
- 太硬核了,50年前的登月程序和程序员绝对超乎你的想象
- 烂泥:KVM虚拟机的关机与开启
- 正则判断手机号地区_匹配中国大陆所有手机号正则表达式
- 程序员的成长之路——道和术的思考
- 如何快速通过信息系统管理工程师考试
- 计算机硬盘容量越大运行速度越快,你是不是也感觉电脑内存越大运行速度越快?...
- 一步一步实现STM32-FOTA系列教程之BIN文件解包C语言实现
- python小操作——读取文件夹内的任意格式文件到txt并排序
- K8s Liveness/Readiness/Startup 探针机制
- 【揭密:刘强东9年密谋的商业布局—京东快物流背后的核心技术盘点】
- IPsec IKE第一阶段主模式和野蛮模式
- C++标准库中的数学函数
- Ajax保姆级使用攻略
热门文章
- java long类型报错:error: integer number too large
- OpenGL ES简介(一)
- 十大经典算法总结(JavaScript描述)
- 人脸方向学习(十):Face Detection-MobileNet_SSD解读
- Educoder 机器学习之随机森林算法 第3关:手写数字识别
- Zabbix(简介和ubuntu安装步骤)
- 简单叙述tcp/ip的工作原理和主要的协议_802.11协议精读3:CSMA/CD与CSMA/CA
- 大学python作业_2020年大学moocPython编程基础作业答案
- 外星人进化_外星人真的比人类强大吗?科学家给出几种猜想,你认同吗?
- quarts集群 运维_Quartz.Net分布式运用