前言:
本文是实验GMS匹配算法的一些论文阅读和源码笔记。在使用ORB特征的前提下,相机姿态变化较大情况下,实验效果明显优于暴力匹配,无明显错配。
放一张论文原图:
一、论文笔记
最近为了完成一个项目,对两视图之间的特征点匹配关系要求较为精确,实验了一些匹配算法,其中包括了GMS。
论文题目《GMS: Grid-based Motion Statistics for Fast, Ultra-robust Feature Correspondence》,源码可以从较新的OpenCV扩展模块找到。
注:此部分没有深究算法原理,这是充分理解,便于后面修改和使用相关代码。
1. 原理
论文摘要:结合平滑性约束到特征匹配中已知可以实现超级鲁棒的匹配。但是,这种方法是复杂和耗时的。这篇论文提出了GMS(基于方格的运动统计),一种阐述运动平滑性作为一个区域内一定数量的匹配统计可能性的的简单方法。GMS使得有位移的高数量匹配有着较高的匹配质量。这提供了一种实时,很鲁棒的匹配系统。在低纹理,模糊和宽基线(可以认为是旋转位移较大的一对图像)的视频上的评估,显示GMS均超过了其它实时匹配方法,并且与更复杂,更慢的匹配方法达到同样的效果。
什么是运动光滑性?一般来说,如果运动是平滑的,临近的像素和特征一起移动。这种思想实际上和另外一种新的匹配算法,叫做LOGOS,在openCV4.2扩展模块中可以找到。为了阐述运动光滑性,作者提出了几个假设:
假设1: | 运动平滑会导致真实匹配周围的邻域有着相同的3D位置。 同样,错误匹配周围的邻域可则会看到几何上不同的3D位置。 |
假设2: | 如果fa匹配错误,则其最近邻可以位于M个可能的位置中的任何一个。 |
假设3: | 如果运动在一个区域上是平滑的,则真正的匹配可以预测看到同一3D位置的多个小区域对。 在错误匹配中使用相同的预测功能将导致实际上不同的3D位置。 |
作者通过假设1就是运动平滑性引出,作者再通过假设2和3建立了匹配的概率模型和打分的模型。
2. GMS网格化框架和快速打分
运动平滑性作为一种匹配的约束条件在前面简单介绍了,为了实际使用,论文引入了网格的框架来实现快速打分。这里主要解决了几个问题,见下表
问题 | 解决方案 |
网格化打分 | 划分图像为20*20,O(N)计算量变为O(1) |
鲁棒近邻分组 | 一个方格周围的8个方格作为近邻;提供了旋转和尺度。 |
合适的网格数量 | 20*20适用于10000个特征点,更多特征点可以划分更多网格 |
通过阈值划分正确和错误匹配 | 阈值由预设阈值和近邻9个方格的平均特征数量决定。 |
算法流程如下图所示。对于一对匹配图,先计算每个方格及其近邻在另一幅图中最大的匹配数量,然后计算Sij和阈值。计算公式如下,
这个公式计算网格对应近邻(9个网格)在另一幅图像对应的网格对应近邻,这些近邻中总的匹配数量之和。
用来划分准确和错误匹配,其中ni即为上面表格中提到的平均特征数量。
二、源码笔记
1. matchGMS使用方法
GMS模块在openCV扩展模块中可以找到,如何编译扩展模块在此不做解释,也可以直接取出代码修改或者找到作者代码修改,在此也不做解释。
GMS匹配的用法如下图所示,值得注意的时,提取到特征点后先做一次暴力匹配,得到的结果再输入到GMS得到正确匹配对。论文中强调使用ORB特征提取方法较好,时间较快,数量较多,论文也是在这个基础上做的实验。
void matchGMS( const Size& size1, const Size& size2, //两幅图像的大小
//特征点
const vector<KeyPoint>& keypoints1, const vector<KeyPoint>& keypoints2,
const vector<DMatch>& matches1to2, //输入通过暴力匹配或者其它方法的获得匹配对
vector<DMatch>& matchesGMS, //输出匹配对
const bool withRotation, //旋转
const bool withScale, //尺度
const double thresholdFactor ) //预设阈值
2. 代码工作框图
简单画了一个框图,供参考。
3. 旋转和尺度变换处理方法
对于旋转,论文认为不同旋转会导致一个网格的最近邻分布变化,在代码中设置了几种旋转导致的变化形式,用此来设置右图的网格。循环这些pattern,当返回的匹配数量最大时,输出这种结果。理论上来说,这种处理方式对于旋转可能不太稳定,但是经过实验后,对于旋转的图像,效果还是不错,说明作者做的近似已经适用大部分场景了。
对于尺度,代码中设置了不同的尺度因子,来初始化右图时,使用了不同的网格大小。同样地,循环这些尺度因子计算,当返回的匹配数量最大时,输出这种结果。