opencv学习之路(34)SIFT特征匹配

Posted 进击的小猴子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencv学习之路(34)SIFT特征匹配相关的知识,希望对你有一定的参考价值。

一、特征匹配简介

二、暴力匹配

1.nth_element筛选

#include "opencv2/opencv.hpp"
#include <opencv2/nonfree/nonfree.hpp>//SIFT
#include <opencv2/legacy/legacy.hpp>//BFMatch暴力匹配
#include <vector>
#include<iostream>
using namespace std;
using namespace cv;

void main()
{     
    Mat srcImg1 = imread("E://11.jpg");
    Mat srcImg2 = imread("E://22.jpg");
    //定义SIFT特征检测类对象
    SiftFeatureDetector siftDetector;
    //定义KeyPoint变量
    vector<KeyPoint>keyPoints1;
    vector<KeyPoint>keyPoints2;
    //特征点检测
    siftDetector.detect(srcImg1, keyPoints1);
    siftDetector.detect(srcImg2, keyPoints2);
    //绘制特征点(关键点)
    Mat feature_pic1, feature_pic2;
    drawKeypoints(srcImg1, keyPoints1, feature_pic1, Scalar::all(-1));
    drawKeypoints(srcImg2, keyPoints2, feature_pic2, Scalar::all(-1));
    //显示原图
    //imshow("src1", srcImg1);
    //imshow("src2", srcImg2);
    //显示结果
    imshow("feature1", feature_pic1);
    imshow("feature2", feature_pic2);

    //计算特征点描述符 / 特征向量提取
    SiftDescriptorExtractor descriptor;
    Mat description1;
    descriptor.compute(srcImg1, keyPoints1, description1);
    Mat description2;
    descriptor.compute(srcImg2, keyPoints2, description2);
    cout<<description1.cols<<endl;
    cout<<description1.rows<<endl;

    //进行BFMatch暴力匹配
    BruteForceMatcher<L2<float>>matcher;    //实例化暴力匹配器
    vector<DMatch>matches;   //定义匹配结果变量
    matcher.match(description1, description2, matches);  //实现描述符之间的匹配

    //匹配结果筛选
    nth_element(matches.begin(), matches.begin()+29, matches.end());   //提取出前30个最佳匹配结果     
    matches.erase(matches.begin()+30, matches.end());    //剔除掉其余的匹配结果

    Mat result;
    drawMatches(srcImg1, keyPoints1, srcImg2, keyPoints2, matches, result,  Scalar(0, 255, 0), Scalar::all(-1));//匹配特征点绿色,单一特征点颜色随机
    imshow("Match_Result", result);
    
    waitKey(0);
}

没有进行筛选时

进行筛选后

2.计算向量距离进行筛选(比第一种筛选方式好)

前面代码相同
    //进行BFMatch暴力匹配
    BruteForceMatcher<L2<float>>matcher;    //实例化暴力匹配器
    vector<DMatch>matches;   //定义匹配结果变量
    matcher.match(description1, description2, matches);  //实现描述符之间的匹配

    //计算向量距离的最大值与最小值:距离越小越匹配
    double max_dist=matches[0].distance,min_dist=matches[0].distance;
    for(int i=1; i<description1.rows; i++)
    {
        if(matches.at(i).distance > max_dist)
            max_dist = matches[i].distance;
        if(matches.at(i).distance < min_dist)
            min_dist = matches[i].distance;
    }
    cout<<"min_distance="<<min_dist<<endl;
    cout<<"max_distance="<<max_dist<<endl;
    //匹配结果删选    
    vector<DMatch>good_matches;
    for(int i=0; i<matches.size(); i++)
    {
        if(matches[i].distance < 2*min_dist)
            good_matches.push_back(matches[i]);
    }

    Mat result;
    drawMatches(srcImg1, keyPoints1, srcImg2, keyPoints2, good_matches, result,  Scalar(0, 255, 0), Scalar::all(-1));//匹配特征点绿色,单一特征点颜色随机
    imshow("Match_Result", result);

 

以上是关于opencv学习之路(34)SIFT特征匹配的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV竟然可以这样学!成神之路终将不远(三十五)

OpenCV SIFT特征算法详解与使用

opencv学习之路(35)SURF特征点提取与匹配

如何使用opencv实现图像匹配

OpenCV中的特征匹配(Feature Matching)

6-sift特征匹配