码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2014-11-14 10:39:01      阅读:286      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   io   color   ar   os   使用   

 

OpenCV中一些相关结构说明:

特征点类:

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

存放匹配结果的结构:

 1 struct DMatch
 2 {
 3     //三个构造函数
 4     DMatch(): queryIdx(-1), trainIdx(-1),imgIdx(-1),
 5         distance(std::numeric_limits<float>::max()) {}
 6     DMatch(int  _queryIdx, int  _trainIdx, float  _distance ) :
 7         queryIdx( _queryIdx),trainIdx( _trainIdx), imgIdx(-1),distance( _distance) {}
 8     DMatch(int  _queryIdx, int  _trainIdx, int  _imgIdx, float  _distance ) :
 9         queryIdx(_queryIdx), trainIdx( _trainIdx), imgIdx( _imgIdx),distance( _distance) {}
10 
11     int queryIdx;  //此匹配对应的查询图像的特征描述子索引
12     int trainIdx;   //此匹配对应的训练(模板)图像的特征描述子索引
13     int imgIdx;    //训练图像的索引(若有多个)
14     float distance;  //两个特征向量之间的欧氏距离,越小表明匹配度越高。
15     bool operator < (const DMatch &m) const;
16 };

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

bubuko.com,布布扣

 

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

 1 #include "opencv2/highgui/highgui.hpp"
 2 #include "opencv2/imgproc/imgproc.hpp"
 3 #include "opencv2/nonfree/nonfree.hpp"
 4 #include "opencv2/nonfree/features2d.hpp"
 5 #include <iostream>
 6 #include <stdio.h>
 7 #include <stdlib.h>
 8 
 9 using namespace cv;
10 using namespace std;
11 
12 int main()
13 {
14     initModule_nonfree();//初始化模块,使用SIFT或SURF时用到
15     Ptr<FeatureDetector> detector = FeatureDetector::create( "SIFT" );//创建SIFT特征检测器
16     Ptr<DescriptorExtractor> descriptor_extractor = DescriptorExtractor::create( "SIFT" );//创建特征向量生成器
17     Ptr<DescriptorMatcher> descriptor_matcher = DescriptorMatcher::create( "BruteForce" );//创建特征匹配器
18     if( detector.empty() || descriptor_extractor.empty() )
19         cout<<"fail to create detector!";
20 
21     //读入图像
22     Mat img1 = imread("desk.jpg");
23     Mat img2 = imread("desk_glue.jpg");
24 
25     //特征点检测
26     double t = getTickCount();//当前滴答数
27     vector<KeyPoint> keypoints1,keypoints2;
28     detector->detect( img1, keypoints1 );//检测img1中的SIFT特征点,存储到keypoints1中
29     detector->detect( img2, keypoints2 );
30     cout<<"图像1特征点个数:"<<keypoints1.size()<<endl;
31     cout<<"图像2特征点个数:"<<keypoints2.size()<<endl;
32 
33     //根据特征点计算特征描述子矩阵,即特征向量矩阵
34     Mat descriptors1,descriptors2;
35     descriptor_extractor->compute( img1, keypoints1, descriptors1 );
36     descriptor_extractor->compute( img2, keypoints2, descriptors2 );
37     t = ((double)getTickCount() - t)/getTickFrequency();
38     cout<<"SIFT算法用时:"<<t<<""<<endl;
39 
40 
41     cout<<"图像1特征描述矩阵大小:"<<descriptors1.size()
42         <<",特征向量个数:"<<descriptors1.rows<<",维数:"<<descriptors1.cols<<endl;
43     cout<<"图像2特征描述矩阵大小:"<<descriptors2.size()
44         <<",特征向量个数:"<<descriptors2.rows<<",维数:"<<descriptors2.cols<<endl;
45 
46     //画出特征点
47     Mat img_keypoints1,img_keypoints2;
48     drawKeypoints(img1,keypoints1,img_keypoints1,Scalar::all(-1),0);
49     drawKeypoints(img2,keypoints2,img_keypoints2,Scalar::all(-1),0);
50     //imshow("Src1",img_keypoints1);
51     //imshow("Src2",img_keypoints2);
52 
53     //特征匹配
54     vector<DMatch> matches;//匹配结果
55     descriptor_matcher->match( descriptors1, descriptors2, matches );//匹配两个图像的特征矩阵
56     cout<<"Match个数:"<<matches.size()<<endl;
57 
58     //计算匹配结果中距离的最大和最小值
59     //距离是指两个特征向量间的欧式距离,表明两个特征的差异,值越小表明两个特征点越接近
60     double max_dist = 0;
61     double min_dist = 100;
62     for(int i=0; i<matches.size(); i++)
63     {
64         double dist = matches[i].distance;
65         if(dist < min_dist) min_dist = dist;
66         if(dist > max_dist) max_dist = dist;
67     }
68     cout<<"最大距离:"<<max_dist<<endl;
69     cout<<"最小距离:"<<min_dist<<endl;
70 
71     //筛选出较好的匹配点
72     vector<DMatch> goodMatches;
73     for(int i=0; i<matches.size(); i++)
74     {
75         if(matches[i].distance < 0.31 * max_dist)
76         {
77             goodMatches.push_back(matches[i]);
78         }
79     }
80     cout<<"goodMatch个数:"<<goodMatches.size()<<endl;
81 
82     //画出匹配结果
83     Mat img_matches;
84     //红色连接的是匹配的特征点对,绿色是未匹配的特征点
85     drawMatches(img1,keypoints1,img2,keypoints2,goodMatches,img_matches,
86                 Scalar::all(-1)/*CV_RGB(255,0,0)*/,CV_RGB(0,255,0),Mat(),2);
87 
88     imshow("MatchSIFT",img_matches);
89     waitKey(0);
90     return 0;
91 }


结果:

bubuko.com,布布扣

 

效果图:

bubuko.com,布布扣

bubuko.com,布布扣

bubuko.com,布布扣

 

源码下载:

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

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

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

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

 

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

标签:des   style   blog   http   io   color   ar   os   使用   

原文地址:http://www.cnblogs.com/shiddong/p/4096431.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!