GMS算法简要介绍
经典的特征匹配算法(SIFT、SURF、ORB等)存在的问题是鲁棒的算法速度较慢,快速的算法鲁棒性较差。局部特征匹配算法的核心问题在于邻域一致性的运用,稀疏邻域一致性特征又不能很好的定义邻域,因此导致特征匹配算法计算量大。Grid-based Motion Statistics(GMS)通过网格划分、运动统计特性的方法可以迅速剔除错误匹配,以此来提高匹配的稳定性。GMS核心思想在于:根据运动平滑性,在正确匹配的特征点附加的正确匹配点对数应该大于错误匹配点的特征点附近的正确匹配点对数。GMS算法主要流程如下:
1 检测两幅图像特征点和计算描述子;
2 通过BF暴力匹配算法进行匹配;
3 将图像划分成G个网格;
4 通过计算BF匹配好的特征点 X i X_i Xi附近的正确匹配个数n与阈值来判断是否该点被正确匹配;
OpenCV-GMS代码
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/flann.hpp>
#include <opencv2/xfeatures2d.hpp>
using namespace cv;
using namespace cv::xfeatures2d;
// This program demonstrates the GMS matching strategy.
int main(int argc, char* argv[])
{
const char* keys =
"{ h help | | print help message }"
"{ l left | | specify left (reference) image }"
"{ r right | | specify right (query) image }"
"{ camera | 0 | specify the camera device number }"
"{ nfeatures | 10000 | specify the maximum number of ORB features }"
"{ fastThreshold | 20 | specify the FAST threshold }"
"{ drawSimple | true | do not draw not matched keypoints }"
"{ withRotation | false | take rotation into account }"
"{ withScale | false | take scale into account }";
CommandLineParser cmd(argc, argv, keys);
//if (cmd.has("help"))
//{
// std::cout << "Usage: gms_matcher [options]" << std::endl;
// std::cout << "Available options:" << std::endl;
// cmd.printMessage();
// return EXIT_SUCCESS;
//}
Ptr<Feature2D> orb = ORB::create(1000); // cmd.get<int>("nfeatures")
orb.dynamicCast<cv::ORB>()->setFastThreshold(20); // cmd.get<int>("fastThreshold")
Ptr<DescriptorMatcher> matcher = DescriptorMatcher: