工作需要用到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