Feature Matching with FLANN

    xiaoxiao2023-11-15  159

    Feature Matching with FLANN

    一.基础知识

    1.Lowe’s算法

    ​ 为了进一步筛选匹配点,来获取优秀的匹配点,这就是所谓的“去粗取精”。一般会采用Lowe’s算法来进一步获取优秀匹配点。为了排除因为图像遮挡和背景混乱而产生的无匹配关系的关键点,SIFT的作者Lowe提出了比较最近邻距离与次近邻距离的SIFT匹配方式:取一幅图像中的一个SIFT关键点,并找出其与另一幅图像中欧式距离最近的前两个关键点,在这两个关键点中,如果最近的距离除以次近的距离得到的比率ratio少于某个阈值T,则接受这一对匹配点。因为对于错误匹配,由于特征空间的高维性,相似的距离可能有大量其他的错误匹配,从而它的ratio值比较高。显然降低这个比例阈值T,SIFT匹配点数目会减少,但更加稳定,反之亦然。

    参考博客:

    https://blog.csdn.net/u010368556/article/details/82939404

    2.k近邻算法

    ​ K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

    参考网址:

    https://baike.baidu.com/item/k近邻算法/9512781?fr=aladdin

    https://www.jianshu.com/p/bad83a08b1a8

    3.此外,还有一些概念需要了解,感兴趣的可以进行了解(强烈推荐了解)

    https://www.cnblogs.com/wangguchangqing/p/4333873.html

    https://www.cnblogs.com/cgjdemo/p/4117400.html?utm_source=tuicool&utm_medium=referral

    二.代码实现

    #include <iostream> #include "opencv2/core.hpp" #ifdef HAVE_OPENCV_XFEATURES2D #include "opencv2/highgui.hpp" #include "opencv2/features2d.hpp" #include "opencv2/xfeatures2d.hpp" using namespace cv; using namespace cv::xfeatures2d; using std::cout; using std::endl; const char* keys = "{ help h | | Print help message. }" "{ input1 | ../data/box.png | Path to input image 1. }" "{ input2 | ../data/box_in_scene.png | Path to input image 2. }"; int main( int argc, char* argv[] ) { CommandLineParser parser( argc, argv, keys ); Mat img1 = imread( parser.get<String>("input1"), IMREAD_GRAYSCALE );//读取第一张图片 Mat img2 = imread( parser.get<String>("input2"), IMREAD_GRAYSCALE );//读取第二张图片 if ( img1.empty() || img2.empty() )//判断图片是否读取成功 { cout << "Could not open or find the image!\n" << endl; parser.printMessage(); return -1; } //-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors int minHessian = 400;//黑塞矩阵最小值 Ptr<SURF> detector = SURF::create( minHessian );//创建SURF std::vector<KeyPoint> keypoints1, keypoints2; Mat descriptors1, descriptors2;//描述符 detector->detectAndCompute( img1, noArray(), keypoints1, descriptors1 );//检测关键点并计算描述符 detector->detectAndCompute( img2, noArray(), keypoints2, descriptors2 ); //-- Step 2: Matching descriptor vectors with a FLANN based matcher // Since SURF is a floating-point descriptor NORM_L2 is used Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::FLANNBASED);//初始化描述符匹配的模型 std::vector< std::vector<DMatch> > knn_matches;//表示进行K近邻匹配,建立存储可能点的向量 matcher->knnMatch( descriptors1, descriptors2, knn_matches, 2 );//进行KNN匹配,找到可能的两个点 //-- Filter matches using the Lowe's ratio test const float ratio_thresh = 0.7f;//阈值比较,当小于这个阈值时,认为最近邻即为所要的点,可根据匹配情况自行调参,调参效果可以参照官方给的图片,个人看图觉得0.4-0.6比较好 std::vector<DMatch> good_matches; for (size_t i = 0; i < knn_matches.size(); i++)//对所有已经初步匹配的各组点进行筛选 { if (knn_matches[i][0].distance < ratio_thresh * knn_matches[i][1].distance)//比较 { good_matches.push_back(knn_matches[i][0]);//得到最后选择出来的点 } } //-- Draw matches Mat img_matches; drawMatches( img1, keypoints1, img2, keypoints2, good_matches, img_matches, Scalar::all(-1), Scalar::all(-1), std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); //-- Show detected matches imshow("Good Matches", img_matches ); waitKey(); return 0; } #else int main() { std::cout << "This tutorial code needs the xfeatures2d contrib module to be run." << std::endl; return 0; } #endif

    运行截图:

    最新回复(0)