【总结】FLANN特征匹配

工作需要用到FLANN特征匹配技术,在这里记录一些关键知识点。

ORB (Oriented FAST and Rotated BRIEF)  算法简介

   分为两部分:

  • 特征点提取 -由FAST(Features from Accelerated Segment Test)算法发展来的
  • 特征点描述 -根据BRIEF(Binary Robust IndependentElementary Features)特征描述算法改进的

暴力匹配(cv2.BFMatcher)

即两两匹配。该算法不做任何优化,假设ORB算法从图片A中提取了m个特征描述符,从图片B中提取了n个特征描述符。暴力匹配器将图片A中m个描述符逐一和图片B中的n个特征描述符求距离,然后对得到的距离排序,取距离最近的一个作为最佳匹配点,这种方法简单粗暴,其结果也是显而易见的,会有大量的错误匹配,这就需要使用一些机制来过滤掉错误的匹配(比如下面的Lowe’s算法

 

cv2.BFMatcher参数说明:

 normType:它是用来指定要使用的距离测试类型。默认值为cv2.Norm_L2。这很适合SIFT和SURF等(c2.NORM_L1也可)。对于使用二进制描述符的ORB、BRIEF和BRISK算法等,要使用cv2.NORM_HAMMING,这样就会返回两个测试对象之间的汉明距离。如果ORB算法的参数设置为WTA_K==3或4,normType就应该设置成cv2.NORM_HAMMING2。
crossCheck:使用交叉匹配的方法来滤除错误匹配,默认值为False。若设置为True,匹配条件就会更加严格,只有到图片A中的第i个特征点与图片B中的第j个特征点距离最近,反过来,还要图片B中的第j个特征点到图片A中的第i个特征点也是最近,才会认为他们是最佳匹配(i,j)并返回,即:这两个特征点要互相匹配才行。(你喜欢我,我也喜欢你,单恋可不行...)
 

暴力匹配器BFMatcher有两个重要的方法,分别是BFMatcher.match() BFMatcher.knnMatch()。送入查询图片A和目标图片B

match() 方法会为图片A从图片B中找到最佳的单个匹配点;

knnMatch()方法会为图片A从图片B中找到最佳的前k个匹配点,k值由用户指定。当我们需要做一些额外的工作时,这种方法会很有用。

 

Lowe’s算法:

为了进一步筛选匹配点,获取优秀的匹配点,即“去粗取精”。为了排除因为图像遮挡和背景混乱而产生的无匹配关系的关键点,SIFT的作者Lowe提出了比较最近邻距离与次近邻距离的SIFT匹配方式:

取一幅图像中的一个SIFT关键点,并找出其与另一幅图像中欧式距离最近的前两个关键点,在这两个关键点中,如果最近的距离除以次近的距离得到的比率ratio少于某个阈值T,则接受这一对匹配点。因为对于错误匹配,由于特征空间的高维性,相似的距离可能有大量其他的错误匹配,从而它的ratio值比较高。显然降低这个比例阈值T,SIFT匹配点数目会减少,但更加稳定,反之亦然。
  Lowe推荐ratio的阈值为0.8;

有网友对大量存在任意尺度、旋转和亮度变化的两幅图片进行匹配,结果表明ratio取值在0. 4~0. 6 之间最佳,小于0. 4的很少有匹配点,大于0. 6的则存在大量错误匹配点,所以建议ratio的取值原则如下(仅供参考):

ratio=0. 4:对于准确度要求高的匹配;

ratio=0. 6:对于匹配点数目要求比较多的匹配;

ratio=0. 5:一般情况下。

Lowe's改进:可以反过来使用最近邻比次近邻,在匹配中可以作为置信度来使用,当满足最近邻比次近邻大于某个值的时候,作为某个条件的判别置信度;比如可以应用在双目视觉立体匹配中的视差选择与优化环节中(论文正在编写中);

下面博客提到了ORB(二值特征编码)如何跟FLANN结合使用(很详细)

https://www.jianshu.com/p/42b61d42e0bc

需要修改的关键代码如下:

FLANN_INDEX_LSH=6
indexParams=dict(algorithm=FLANN_INDEX_LSH, 
                 table_number = 6, #12
                 key_size = 12,    #20
                 multi_probe_level = 1)#2
searchParams=dict(checks=100)

GPU加速的orb算法相关博客(c++):

https://blog.csdn.net/bisheng250/article/details/53691099

https://blog.csdn.net/dlphay/article/details/79021472

 

PyCUDA官方教程:

https://documen.tician.de/pycuda/ (英文)

https://blog.cycleuser.org/pycuda-tutorial-zhong-wen-ban.html  (中文)

https://www.cnblogs.com/noluye/p/11517489.html

https://blog.csdn.net/qq_36387683/article/details/81075870 (pycuda和numba的比较)

https://blog.csdn.net/u013390476/article/details/82194709

 

利用深度学习来做特征匹配:

论文笔记之:MatchNet: Unifying Feature and Metric Learning for Patch-Based Matching

https://www.cnblogs.com/wangxiaocvpr/p/5515181.html

里面关键一句:双塔的输出串联在一起作为度量网络的输入!

基于深度学习的图像匹配技术专题

https://blog.csdn.net/aaron121211/article/details/78707215

 

  • 2
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
### 回答1: SIFT(尺度不变特征转换)是一种图像特征提取算法,而RANSAC(随机抽样一致性)是一种用于剔除误匹配点的算法。下面是关于如何在OpenCV 3.0中实现这两种算法的简要步骤。 首先,打开一个图像并加载其所需的库: ``` import cv2 import numpy as np ``` 然后,我们可以从图像中提取SIFT特征: ``` # 加载图像 img = cv2.imread('image.jpg',0) # 创建SIFT对象 sift = cv2.xfeatures2d.SIFT_create() # 检测并计算SIFT特征 keypoints, descriptors = sift.detectAndCompute(img, None) ``` 接下来,我们可以使用RANSAC算法来剔除误匹配点: ``` # 创建FLANN匹配器对象 FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) search_params = dict(checks=50) flann = cv2.FlannBasedMatcher(index_params, search_params) # 在两幅图像之间匹配特征点 matches = flann.knnMatch(descriptors1, descriptors2, k=2) # 进行RANSAC过滤 good_matches = [] for m, n in matches: if m.distance < 0.7 * n.distance: good_matches.append(m) # 绘制匹配结果 result = cv2.drawMatches(img1, keypoints1, img2, keypoints2, good_matches, None, flags=2) cv2.imshow('Matches', result) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上述代码中,我们首先创建了一个FLANN(快速最近邻搜索)匹配器对象,然后使用`knnMatch`函数在两幅图像之间进行特征点匹配。最后,我们使用RANSAC算法对匹配点进行过滤,并将结果绘制出来。 以上是在OpenCV 3.0中实现SIFT特征提取和RANSAC误匹配点剔除的简要步骤。实际操作中还可以进行更详细的参数设置和优化,以便得到更好的匹配结果。 ### 回答2: OpenCV 3.0 是一个非常强大的计算机视觉库,它提供了许多功能来处理图像处理和计算机视觉任务。其中包括使用SIFT算法进行特征提取和使用RANSAC算法进行误匹配点的剔除。 首先,SIFT(尺度不变特征变换)是一种用于在图像中检测和描述关键点的算法。在OpenCV 3.0中,你可以使用`cv2.xfeatures2d.SIFT_create()`来创建一个SIFT对象。然后,你可以使用`detectAndCompute()`方法来检测并计算图像的关键点和特征描述符。通过调用这个方法,你将得到检测到的关键点和对应的特征描述符。 接下来,我们可以使用RANSAC(随机样本一致性)算法来剔除误匹配点。RANSAC算法能够通过随机选择样本子集并估计模型参数来寻找数据中的局内点。在OpenCV 3.0中,你可以使用`cv2.RANSAC`作为参数来创建一个RANSAC对象。然后,你可以使用`findHomography()`方法来计算通过RANSAC算法筛选后的匹配点之间的透视变换矩阵。这个矩阵可以用来剔除误匹配点。 总结一下,OpenCV 3.0可以通过`cv2.xfeatures2d.SIFT_create()`方法进行SIFT特征提取,并使用RANSAC算法来剔除误匹配点。这两个功能都是非常有用的计算机视觉任务,能够帮助我们更好地处理和分析图像。 ### 回答3: 在OpenCV 3.0中,可以使用SIFT算法进行图像的特征提取,并采用RANSAC算法剔除误匹配点。 SIFT(Scale-Invariant Feature Transform)特征提取算法是一种基于尺度空间的特征提取方法,它可以提取图像中的稳定特征点和其对应的描述子。在OpenCV中,可以使用sift.detectAndCompute()函数来提取图像的SIFT特征点和描述子。 RANSAC(Random Sample Consensus)算法是一种鲁棒的参数估计算法,它可以从一组数据中剔除异常点,从而得到准确的模型参数。在特征匹配中,可以使用RANSAC算法来剔除误匹配点,以提高匹配的准确性。 具体实现的步骤如下: 1. 导入OpenCV和Numpy库,并读取需要进行特征匹配的两幅图像。 ```python import cv2 import numpy as np img1 = cv2.imread('image1.jpg', 0) img2 = cv2.imread('image2.jpg', 0) ``` 2. 创建SIFT对象,并使用sift.detectAndCompute()函数提取图像的SIFT特征点和描述子。 ```python sift = cv2.SIFT_create() kp1, des1 = sift.detectAndCompute(img1, None) kp2, des2 = sift.detectAndCompute(img2, None) ``` 3. 使用FLANN匹配器对两幅图像的描述子进行匹配。 ```python FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) search_params = dict(checks=50) flann = cv2.FlannBasedMatcher(index_params, search_params) matches = flann.knnMatch(des1, des2, k=2) ``` 4. 运用RANSAC算法剔除误匹配点。 ```python good_matches = [] for m, n in matches: if m.distance < 0.7 * n.distance: good_matches.append(m) src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2) dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2) M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) ``` 通过以上步骤,我们可以得到经过RANSAC算法筛选后的匹配点,并且可以通过M矩阵获取图像的对应关系。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

轩辕十四

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值