opencv2.4 sift算法的使用

与opencv2.3.1版本的sift算法的编程方法有所不同,貌似opencv2.4版本之后将sift、surf算法移到了nonfree区。

所以,需要包换的头文件:

#include

#include

增加静态链接库:

opencv_nonfree249d.lib和opencv_features2d249d.lib

注:在使用 initModule_nonfree()函数时,需要用到 opencv_nonfree249d.lib 这个链接库,才能不出现“无法解析的外部符号”。


具体SIFT算法的运算过程是这样的:

1、用FeatureDetector创建相应的特征检测器,并调用FeatureDetector::detect()函数,来求取特征点,并保存在KeyPoint的vector容器中。

特征检测器如下:

Ptr detector = FeatureDetector::create( "SIFT" );//创建SIFT特征检测器 

其中FeatureDetector::create()函数的参数可选:

• "FAST" – FastFeatureDetector

• "STAR" – StarFeatureDetector
• "SIFT" – SIFT (nonfree module)
• "SURF" – SURF (nonfree module)
• "ORB" – ORB
• "BRISK" – BRISK
• "MSER" – MSER
• "GFTT" – GoodFeaturesToTrackDetector
• "HARRIS" – GoodFeaturesToTrackDetector with Harris detector enabled
• "Dense" – DenseFeatureDetector
• "SimpleBlob" – SimpleBlobDetector


Keypoints特征点类定义如下:

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


2、用DescriptorExtractor创建相应的特征向量生成器,并调用DescriptorExtractor::compute()函数,来求取特征矩阵,保存在Mat型变量中。

特征向量生成器定义如下:

Ptr descriptor_extractor = DescriptorExtractor::create( "SIFT" );//创建特征向量生成器  

其中DescriptorExtractor::create()函数的参数如下:

• "SIFT" – SIFT
• "SURF" – SURF
• "BRIEF" – BriefDescriptorExtractor
• "BRISK" – BRISK
• "ORB" – ORB
• "FREAK" – FREAK


3、用DescriptorMatcher创建特征匹配器,并调用DescriptorMatcher::match()函数,求取两幅图像之间的匹配点,并保存在DMatch的vector容器中。

特征匹配器定义如下:

Ptr descriptor_matcher = DescriptorMatcher::create( "BruteForce" );//创建特征匹配器
其中DescriptorMatcher::create()函数的参数如下,对应不同的匹配算法:

– BruteForce (it uses L2 ) 
– BruteForce-L1
– BruteForce-Hamming
– BruteForce-Hamming(2)
– FlannBased


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


4、调用drawMatches()函数绘制匹配结果。


例程如下:

#include 
#include 
#include 
#include 
#include 
#include 


using namespace cv;
using namespace std;



int main()
{
	/*SIFT算法*/
	Mat image1=imread("E:\\test\\lena.bmp",0);
	Mat image2=imread("E:\\test\\lena_Match.bmp",0);
	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!"; 


	//检测特征点
	vector vkKeypoints1,vkKeypoints2;
	detector->detect(image1,vkKeypoints1);
	detector->detect(image2,vkKeypoints2);
	cout<<"图像1特征点个数:"<compute( image1, vkKeypoints1, mDescriptors1);
	descriptor_extractor->compute(image2, vkKeypoints2, mDescriptors2);
	cout<<"图像1特征描述矩阵大小:"< vdMatches;
	descriptor_matcher->match(mDescriptors1,mDescriptors2,vdMatches);


	//筛选匹配结果
	//距离是指两个特征向量间的欧式距离,表明两个特征的差异,值越小表明两个特征点越接近
	int nMinDis=100,nMaxDis=0;
	for (int i=0;ivdMatches[i].distance)
			nMinDis=vdMatches[i].distance;
		if (nMaxDis vdGoodMatches;
	for (int i=0;i



注:如果仅仅想画出特征点,可调用 drawKeypoints()函数实现,如:drawKeypoints(img1,keypoints1,img_keypoints1,Scalar::all(-1),0); 

运行结果:

opencv2.4 sift算法的使用_第1张图片

opencv2.4 sift算法的使用_第2张图片


参考:http://blog.csdn.net/masibuaa/article/details/8998601


你可能感兴趣的:(OpenCV)