Freak特征描述+BruteForceMatcher匹配+RANSAC剔除误匹配
时间一晃飞快,前几日的广州之行让人难忘,置身炎热的户外仿佛蒸桑拿一样。这一段时间一直在研究一种从一幅图片中找到给定目标的方法,而基于局部特征提取并且进行特征的匹配可以实现。
目前局部特征描述子有以下几种,
- 2004年发展成熟的SIFT
- 后来改进的SURF,它们的描述符是高维度整型的数字。
- 2010年出现的BRIEF是一种二进制的描述符,这种描述符在提高计算速度方面给出了不错的思路,但是不具备旋转不变,尺度不变,对噪声也比较敏感(虽然它采用了高斯平滑来抗噪声)
- 2011年出现的ORB算法同样是二进制,但是解决了旋转不变和噪声敏感的问题,但是不具备尺度不变性。
- 2011年同时出现了BRISK算法,解决旋转不变,尺度不变和抗噪声问题,网上有视频,实时性也不错,先有个直观认识,爽死。链接[(http://v.youku.com/v_show/id_XMTI5MzI3Mzk0OA==.html)]
- 2012年提出FREAK算法,其实是在BRISK上的改进。具备BRISK的优点。这篇论文中作者表示FREAK算法可以outperform以前所有的描述子。(注意:这里是特征描述子,因为论文中没有给出特征点检测方法,只有特征点的描述子)
看完了综述,我决定用FREAK来实现。足足耗了我15天,今天我这一段所得写下,勉励自己,服务他人。
先贴上代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
一:
首先说说特征点检测,为什么我用surf,而不用速度很快的fast或者Brisk,我自己做了测试,发现用fast和brisk的话,再用freak描述,最终匹配效果并不好,比sift要差…我其实不太明白为什么,因为有一些后期的论文对比效果说freak综合效果最好,然而我却得不到这样的结果。要继续钻研了,大家有想法欢迎交流,哦不,欢迎指点!
二:
RANSAC的这个算法,请用opencv库中的cvFindHomography,不要用cvFindFundamentalMat,因为这两个是不一样的,字面上简单看一个是找到单应性矩阵,一个是找到基础矩阵,这两个到底有神马区别???
《计算机视觉中的多视图几何》中这样描述:
- 2D单应:一幅2D图像中点集到另一幅图像中点集的射影变换。
- 基本矩阵:它使一个队所有的点都是的x`Fx=0成立的奇异矩阵F。这是一个3*3的奇异矩阵,而且秩为2,不可逆。它是2维图像上的点通过对极线束约束的映射,是2维到1维的映射。
具体的大家可以看书或者百度,或者等以后我有空了,再具体描述。其实我也没有太懂哈哈哈!还要再看看!慎言慎言!
之前,我曾经自己编写过一个RANSAC的算法啊,但是效果不是特别理想,由于RANSAC算法本身也比较耗时,各路大神们也都提出了很多改进方法,不知道opencv跟进这些改进算法没有?推荐综述型文章《A Universal Framework for Random
Sample Consensus》,里面提到的prosac,lo-ransac速度提升很多!大家自行汲取,我想以后再写一些关于RANSAC的博文。
三:
代码中用到BFMatcher这个类,对象的参数有两个BFMatcher::BFMatcher(int normType=NORM_L2, bool crossCheck=false )。第一个指的是距离,如果是sift或者surf描述的话,就选择NORM_L2和NORM_L2;ORB,BRISK,FREAK这种二进制的描述子就用汉明距离,也就是NORM_HAMMING;NORM_HAMMING2是用作ORB的。第二个参数是是否crossCheck,最好选择true,这个也经过我实验验证,选择true相当于knn匹配中将k置1,也就是只返回最好的那一组匹配,而不是多个近邻。(注意:如果要用knnmatch的话,这个crossCheck的参数就选择false)。这种只返回最好的一组匹配的方式可以作为ratio test的一种替代选择。实验证明,如果选择false,那么将会返回一对多匹配,和多对一的匹配,后期用ransac的效果可能非常不理想。crossCheck就是交叉匹配,剔除不好的匹配。有论文支撑,大家感兴趣可以去搜