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);  //實現描述符之間的匹配

其余代碼相同

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM