• 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);  //实现描述符之间的匹配

    其余代码相同

  • 相关阅读:
    js 正则表达式之环视结构
    Js 控制随机数概率
    js 随机点名
    事件处理机制
    事件处理程序 (DOM0级)
    事件处理程序(HTML)
    js正则表达式 URL格式匹配详解
    CSS中的圣杯布局与双飞翼布局
    CSS中的vertical-align属性
    CSS中元素的显示模式
  • 原文地址:https://www.cnblogs.com/little-monkey/p/7634573.html
Copyright © 2020-2023  润新知