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

一、简介

二、opencv中的SURF算法接口

三、特征点匹配方法

四、代码

1.特征点提取

#include "opencv2/opencv.hpp"
#include <opencv2/nonfree/nonfree.hpp>
#include <vector>
#include<iostream>
using namespace std;
using namespace cv;

void main()
{     
    Mat srcImg1 = imread("E://1.jpg");
    Mat srcImg2 = imread("E://2.jpg");
    //定义SURF特征检测类对象
    SurfFeatureDetector surfDetector(400);//SIFT有默认值,SURF没有默认值,需要赋初值 hessianThreshold
    //定义KeyPoint变量
    vector<KeyPoint>keyPoints1;
    vector<KeyPoint>keyPoints2;
    //特征点检测
    surfDetector.detect(srcImg1, keyPoints1);
    surfDetector.detect(srcImg2, keyPoints2);
    //绘制特征点(关键点)
    Mat feature_pic1, feature_pic2;
    drawKeypoints(srcImg1, keyPoints1, feature_pic1, Scalar(0,255,0));
    //drawKeypoints(srcImg2, keyPoints2, feature_pic2, Scalar::all(-1));
    //drawKeypoints(srcImg1, keyPoints1, feature_pic1, Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    drawKeypoints(srcImg2, keyPoints2, feature_pic2, Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    //显示原图
    imshow("src1", srcImg1);
    imshow("src2", srcImg2);
    //显示结果
    imshow("feature1", feature_pic1);
    imshow("feature2", feature_pic2);

    waitKey(0);
}

 2.暴力匹配(尽量避免使用“nth_element前多少个”筛选)

#include "opencv2/opencv.hpp"
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/legacy/legacy.hpp>
#include <vector>
#include<iostream>
using namespace std;
using namespace cv;

void main()
{     
    Mat srcImg1 = imread("E://11.jpg");
    Mat srcImg2 = imread("E://22.jpg");
    //定义SURF特征检测类对象
    SurfFeatureDetector surfDetector(400);  //HessianThreshold
 
    //定义KeyPoint变量
    vector<KeyPoint>keyPoints1;
    vector<KeyPoint>keyPoints2;
    //特征点检测
    surfDetector.detect(srcImg1, keyPoints1);
    surfDetector.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);

    //计算特征点描述符 / 特征向量提取
    SurfDescriptorExtractor 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);  //实现描述符之间的匹配

     //计算向量距离的最大值与最小值
    double max_dist=0, min_dist=100;
    for(int i=0; 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, matches, result, Scalar::all(-1), Scalar::all(-1));
    drawMatches(srcImg1, keyPoints1, srcImg2, keyPoints2, good_matches, result,  Scalar(0, 255, 0), Scalar::all(-1));
    imshow("Match_Result", result);

    waitKey(0);
}

因为surf检测到的角点比较少,所以不适合做小目标匹配。

同样代码,使用sift作对比

3.FlannBasedMatcher匹配

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

其余代码相同

 

posted @ 2017-10-07 15:14  进击的小猴子  阅读(6595)  评论(0编辑  收藏  举报