opencv3.1 surf特征匹配


 #include  
#include
#include      
#include "opencv2/xfeatures2d.hpp"   
#include "opencv2/xfeatures2d/nonfree.hpp"  //SURF
#include "opencv2/xfeatures2d/cuda.hpp"  
#include     
#include

using namespace cv;
using namespace std;

void getMatchPoint(Mat src1, Mat src2)

{

    vector keys1;  
   vector keys2;

   Ptr detector = xfeatures2d::SURF::create(800);
   cv::BFMatcher matcher;
   Mat descriptorMat1, descriptorMat2;
   std::vector mathces;
 
   detector->detectAndCompute(src1, Mat(), keys1, descriptorMat1);
   detector->detectAndCompute(src2, Mat(), keys2, descriptorMat2);
   matcher.match(descriptorMat1, descriptorMat2, mathces);

   drawKeypoints(src1, keys1, src1, cv::Scalar::all(255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
   drawKeypoints(src2, keys2, src2, cv::Scalar::all(255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
  

   Mat matchMat;
   drawMatches(src1, keys1, src2, keys2, mathces, matchMat);
   cv::imshow("Mathces", matchMat);

   imshow("image1", src1);      
   imshow("image2", src2); 


  #if 1 
    double max_dist = 0; double min_dist = 100;
    //-- Quick calculation of max and min distances between keypoints  
    for (int i=0; i     {
        double dist = mathces[i].distance;
        if (dist < min_dist) min_dist = dist;
        if (dist > max_dist) max_dist = dist;
    }
    cout<<"-- Max dist :"<< max_dist<     cout<<"-- Min dist :"<< min_dist<
     //-- Draw only "good" matches (i.e. whose distance is less than 0.6*max_dist )  
    //-- PS.- radiusMatch can also be used here.  
    vector< DMatch > good_matches;
    for (int i=0; i     {
        if (mathces[i].distance < 0.6*max_dist)
        {
            good_matches.push_back(mathces[i]);
        }
    }

    Mat img_matches;
    drawMatches(src1, keys1, src2, keys2,
    good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
    vector(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

    imwrite("FASTResult.jpg", img_matches);
    imshow("goodMatch", img_matches);  
#endif

#if 1
    // 分配空间
    int ptCount = (int)mathces.size();
    Mat p1(ptCount, 2, CV_32F);
    Mat p2(ptCount, 2, CV_32F);

    // 把Keypoint转换为Mat
    Point2f pt;
    for (int i=0; i     {
        pt = keys1[mathces[i].queryIdx].pt;
        p1.at(i, 0) = pt.x;
        p1.at(i, 1) = pt.y;

        pt = keys2[mathces[i].trainIdx].pt;
        p2.at(i, 0) = pt.x;
        p2.at(i, 1) = pt.y;
    }


    // 用RANSAC方法计算 基本矩阵F
    Mat fundamental;
    vector RANSACStatus;

    fundamental = findFundamentalMat(p1, p2, RANSACStatus, FM_RANSAC);
    // 计算野点个数
    int OutlinerCount = 0;
    for (int i=0; i     {
        if (RANSACStatus[i] == 0) // 状态为0表示野点
        {
            OutlinerCount++;
        }
    }
   
      // 计算内点
    vector Inlier1;
    vector Inlier2;
    vector InlierMatches;
    // 上面三个变量用于保存内点和匹配关系
    int InlinerCount = ptCount - OutlinerCount;
    InlierMatches.resize(InlinerCount);
    Inlier1.resize(InlinerCount);
    Inlier2.resize(InlinerCount);
    InlinerCount = 0;
    for (int i=0; i     {
        if (RANSACStatus[i] != 0)
        {
            Inlier1[InlinerCount].x = p1.at(i, 0);
            Inlier1[InlinerCount].y = p1.at(i, 1);
            Inlier2[InlinerCount].x = p2.at(i, 0);
            Inlier2[InlinerCount].y = p2.at(i, 1);
            InlierMatches[InlinerCount].queryIdx = InlinerCount;
            InlierMatches[InlinerCount].trainIdx = InlinerCount;
            cout<<"index = "<     imshow("FMatch", OutImage);
#endif

 

}

结果图:

opencv3.1 surf特征匹配_第1张图片

//good_matches.jpg

opencv3.1 surf特征匹配_第2张图片

// FmatrixResult.jpg

opencv3.1 surf特征匹配_第3张图片



 知识点补充:

DMATCH 数据结构:

struct DMatch
{ //三个构造函数
DMatch():
queryIdx(-1),trainIdx(-1),imgIdx(-1),distance(std::numeric_limits::max()) {}

DMatch(int _queryIdx, int _trainIdx, float _distance ) :
queryIdx( _queryIdx),trainIdx( _trainIdx), imgIdx(-1),distance( _distance) {}

DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance ) :
queryIdx(_queryIdx), trainIdx( _trainIdx), imgIdx( _imgIdx),distance( _distance) {}
int queryIdx; //此匹配对应的查询图像的特征描述子索引(输入图1)
int trainIdx; //此匹配对应的训练(模板)图像的特征描述子索引(输入图2)
int imgIdx; //训练图像的索引(若有多个)
float distance; //两个特征向量之间的欧氏距离,越小表明匹配度越高。
booloperator < (const DMatch &m) const;
};


参考文献:

http://blog.csdn.net/ikerpeng/article/details/47972959



你可能感兴趣的:(图像特征)