GMS: Grid-based Motion Statistics for Fast, Ultra-robust Feature Correspondence 代码解读
论文原文地址:GMS: Grid-based Motion Statistics for Fast, Ultra-robust Feature Correspondence
代码地址:github
1 论文核心思路
论文认为:匹配对应该是平滑的,对于true match pair(l1,r1),l1附近的特征点对应的匹配点也应该在r1附近.
① 利用上面的平滑性质,建立统计分析模型(二项分布),过滤ORB matches中的false matches;
② 通过划分栅格来加速真假判断过程,两张图像各划分成m * m块,只需要对各块内及邻块的Feature统计,m建议是20;
③ 对于匹配块(pl1,pr1),对相邻的n * n块,分别进行统计,比如统计pl1的左上块与pr1的左上块的匹配数目,其他类似,以共同验证(pl1,pr1)是否是正确匹配块.这里n建议是3.
④ 论文验证了这个思路的可行性.
2 代码详细讲解
- 2.1
gms_matcher gms(kp1, img1.size(), kp2, img2.size(), matches_all);,构建gms_matcher对象,在默认构造器中:
①NormalizePoints(vkp1, size1, mvP1);归一化点的坐标到(0,1)区间;
②ConvertMatches(vDMatches, mvMatches);把opencv的matches转换成vector形式的matches;
③InitalizeNiehbors(mGridNeighborLeft, mGridSizeLeft);,mGridNeighborLeft为400 * 9的Mat,400对应20 * 20 块,9对应每一块的邻块的序号.
- 2.2
gms.GetInlierMask(vbInliers, false, false);, 开始做GMS匹配筛选,第一个false表示不做多尺度(代码定义了5中尺度)缩放筛选,第二个false表示不做多旋转方向上(代码定义了8中旋转)的筛选,筛选后的结果保存在vbInliers中.
①void SetScale(int Scale),对不同Scale,缩放图片大小,再InitalizeNiehbors(mGridNeighborLeft, mGridSizeLeft);,这个函数参照上面2.1中的③.
- 2.3
int gms_matcher::run(int RotationType),正式进入筛选,参数RotationType为1~8的旋转编号.
①AssignMatchPairs(int GridType),该函数主要是为了统计两个参数—Mat mMotionStatistics和vector<int> mNumberPointsInPerCellLeft.
对于前者,mMotionStatistics.at<int>(lgidx, rgidx)的值表示,在区块lgidx和rgidx中的匹配对的数目;
对于后者,mNumberPointsInPerCellLeft[lgidx]的值表示区块lgidx和右图所有的匹配对的数目,不一定在rgidx中.
②VerifyCellPairs(int RotationType),核心函数,判断匹配的区块是否是inlier块.
1) 遍历左图每一区块,对每一区块i,遍历右图区块找到与i匹配对最多的块j;
2) 同时遍历i和j的3 * 3邻块,统计每对邻块的匹配点数;
3) 计算阈值,,滤除小于阈值的点,其中经验值为6,表示第i区块加上3 * 3邻块的平均每块的匹配数量.