首页 » 技术分享 » Flann特征点匹配简述(Lowe's algorithm)

Flann特征点匹配简述(Lowe's algorithm)

 

/***好记性不如烂笔头,记下来便于以后复习***/       

      特征匹配的结果会得到两个特征集合的对应关系列表。第一组特征集被称为训练集(train),第二组被称为查询集(query)。Flann 在调用匹配函数之前,为了提高匹配速度,训练一个匹配器。训练阶段是为了优化cv::FlannBasedMatcher的性能。train类将会建立特征集的索引树。将 query image 的每一个特征点和 train 匹配器进行匹配,找出最佳匹配;也就是从query image 的特征中逐个去和训练器做匹配,也就是说每一个query image 特征点都会有一个最佳匹配,后期还需要验证这匹配的正确性,可以通过设置截断值来去除误差大的匹配;

     去除了误差大的匹配即可以使用 Lowe's策略进行匹配的再一次筛选;

      knnMatch()找每个query image特征的K近邻匹配,效率不够高,帧率很低。

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

ratio=0. 4:对于准确度要求高的匹配;

ratio=0. 6:对于匹配点数目要求比较多的匹配;

ratio=0. 5:一般情况下。

Lowe's改进:可以反过来使用最近邻比次近邻,在匹配中可以作为置信度来使用,当满足最近邻比次近邻大于某个值的时候,作为某个条件的判别  置信度;比如可以应用在双目视觉立体匹配中的视差选择与优化环节中(论文正在编写中);

#include "highgui/highgui.hpp"    
#include "opencv2/nonfree/nonfree.hpp"    
#include "opencv2/legacy/legacy.hpp"   
#include <iostream>  

using namespace cv;
using namespace std;

int main()
{
    Mat image01 = imread("g2.jpg", 1);    
    Mat image02 = imread("g4.jpg", 1);    
    imshow("p2", image01);
    imshow("p1", image02);

    //灰度图转换  
    Mat image1, image2;
    cvtColor(image01, image1, CV_RGB2GRAY);
    cvtColor(image02, image2, CV_RGB2GRAY);


    //提取特征点    
    SurfFeatureDetector surfDetector(2000); //海塞矩阵阈值,在这里调整精度,值越大点越少,越精准 
    vector<KeyPoint> keyPoint1, keyPoint2;
    surfDetector.detect(image1, keyPoint1);
    surfDetector.detect(image2, keyPoint2);

    //特征点描述,为下边的特征点匹配做准备    
    SurfDescriptorExtractor SurfDescriptor;
    Mat imageDesc1, imageDesc2;
    SurfDescriptor.compute(image1, keyPoint1, imageDesc1);
    SurfDescriptor.compute(image2, keyPoint2, imageDesc2);

    FlannBasedMatcher matcher;
    vector<vector<DMatch> > matchePoints;
    vector<DMatch> GoodMatchePoints;

    vector<Mat> train_desc(1, imageDesc1);
    matcher.add(train_desc);
    matcher.train();

    matcher.knnMatch(imageDesc2, matchePoints, 2);
    cout << "total match points: " << matchePoints.size() << endl;

    // Lowe's algorithm,获取优秀匹配点
    for (int i = 0; i < matchePoints.size(); i++)
    {
        if (matchePoints[i][0].distance < 0.6 * matchePoints[i][1].distance)
        {
            GoodMatchePoints.push_back(matchePoints[i][0]);
        }
    }

    Mat first_match;
    drawMatches(image02, keyPoint2, image01, keyPoint1, GoodMatchePoints, first_match);
    imshow("first_match ", first_match);
    waitKey();
    return 0;
}

参考博客:

https://blog.csdn.net/xxzxxzdlut/article/details/72930209

https://www.cnblogs.com/wyuzl/p/7816011.html

转载自原文链接, 如需删除请联系管理员。

原文链接:Flann特征点匹配简述(Lowe's algorithm),转载请注明来源!

0