OpenCV2.4.4中调用SIFT特征检测器进行图像匹配

OpenCV中一些相关结构说明:

特征点类:

       class KeyPoint
       {
              Point2f  pt;  //坐标
              float  size; //特征点邻域直径
              float  angle; //特征点的方向,值为[0,360),负值表示不使用
              float  response; //
              int  octave; //特征点所在的图像金字塔的组
              int  class_id; //用于聚类的id
       }

存放匹配结果的结构:

       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) {}
 
           intqueryIdx;  //此匹配对应的查询图像的特征描述子索引
           inttrainIdx;   //此匹配对应的训练(模板)图像的特征描述子索引
           intimgIdx;    //训练图像的索引(若有多个)
           float distance;  //两个特征向量之间的欧氏距离,越小表明匹配度越高。
           booloperator < (const DMatch &m) const;
       };

       说明:以两个特征点描述子(特征向量)之间的欧氏距离作为特征点匹配的相似度准则,假设特征点对p和q的

               特征描述子分别为Desp和Desq,则其欧氏距离定义为:


                所以每个匹配分别对应训练图像(train)和查询图像(query)中的一个特征描述子(特征向量)。



#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/nonfree/features2d.hpp"
#include 
#include 
#include 

using namespace cv;
using namespace std;

int main()
{
    initModule_nonfree();//初始化模块,使用SIFT或SURF时用到
    Ptr detector = FeatureDetector::create( "SIFT" );//创建SIFT特征检测器
    Ptr descriptor_extractor = DescriptorExtractor::create( "SIFT" );//创建特征向量生成器
    Ptr descriptor_matcher = DescriptorMatcher::create( "BruteForce" );//创建特征匹配器
    if( detector.empty() || descriptor_extractor.empty() )
        cout<<"fail to create detector!";

    //读入图像
    Mat img1 = imread("desk.jpg");
    Mat img2 = imread("desk_glue.jpg");

    //特征点检测
    double t = getTickCount();//当前滴答数
    vector keypoints1,keypoints2;
    detector->detect( img1, keypoints1 );//检测img1中的SIFT特征点,存储到keypoints1中
    detector->detect( img2, keypoints2 );
    cout<<"图像1特征点个数:"<compute( img1, keypoints1, descriptors1 );
    descriptor_extractor->compute( img2, keypoints2, descriptors2 );
    t = ((double)getTickCount() - t)/getTickFrequency();
    cout<<"SIFT算法用时:"< matches;//匹配结果
    descriptor_matcher->match( descriptors1, descriptors2, matches );//匹配两个图像的特征矩阵
    cout<<"Match个数:"< max_dist) max_dist = dist;
    }
    cout<<"最大距离:"< goodMatches;
    for(int i=0; i

结果:

OpenCV2.4.4中调用SIFT特征检测器进行图像匹配_第1张图片


效果图:

OpenCV2.4.4中调用SIFT特征检测器进行图像匹配_第2张图片

OpenCV2.4.4中调用SIFT特征检测器进行图像匹配_第3张图片

OpenCV2.4.4中调用SIFT特征检测器进行图像匹配_第4张图片


源码下载:

http://download.csdn.net/detail/masikkk/5511831


当然,这些匹配还没有经过系统的筛选,还存在大量的错配,关于匹配的筛选参见这篇文章:

 利用RANSAC算法筛选SIFT特征匹配

以及RobHess的SIFT源码分析系列文章:http://blog.csdn.net/masibuaa/article/details/9191309

OpenCV2.4.4中调用SIFT特征检测器进行图像匹配

你可能感兴趣的:(计算机视觉,OpenCV)