opencv2.4 sift算法的使用
来源:互联网 发布:常用国家域名 编辑:程序博客网 时间:2024/06/05 15:09
与opencv2.3.1版本的sift算法的编程方法有所不同,貌似opencv2.4版本之后将sift、surf算法移到了nonfree区。
所以,需要包换的头文件:
#include <nonfree/features2d.hpp>#include <nonfree/nonfree.hpp>
增加静态链接库:
opencv_nonfree249d.lib和opencv_features2d249d.lib
注:在使用 initModule_nonfree()函数时,需要用到 opencv_nonfree249d.lib 这个链接库,才能不出现“无法解析的外部符号”。
具体SIFT算法的运算过程是这样的:
1、用FeatureDetector创建相应的特征检测器,并调用FeatureDetector::detect()函数,来求取特征点,并保存在KeyPoint的vector容器中。
特征检测器如下:
Ptr<FeatureDetector> 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<DescriptorExtractor> 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<DescriptorMatcher> 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<float>::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 <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <features2d/features2d.hpp>#include <nonfree/features2d.hpp>#include <nonfree/nonfree.hpp>#include <iostream>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<FeatureDetector> detector = FeatureDetector::create( "SIFT" );//创建SIFT特征检测器 Ptr<DescriptorExtractor> descriptor_extractor = DescriptorExtractor::create( "SIFT" );//创建特征向量生成器 Ptr<DescriptorMatcher> descriptor_matcher = DescriptorMatcher::create( "BruteForce" );//创建特征匹配器 if( detector.empty() || descriptor_extractor.empty() ) cout<<"fail to create detector!"; //检测特征点vector<KeyPoint> vkKeypoints1,vkKeypoints2;detector->detect(image1,vkKeypoints1);detector->detect(image2,vkKeypoints2);cout<<"图像1特征点个数:"<<vkKeypoints1.size()<<endl;cout<<"图像2特征点个数:"<<vkKeypoints2.size()<<endl;//根据特征点计算特征描述子矩阵,即特征向量矩阵 Mat mDescriptors1,mDescriptors2;descriptor_extractor->compute( image1, vkKeypoints1, mDescriptors1);descriptor_extractor->compute(image2, vkKeypoints2, mDescriptors2);cout<<"图像1特征描述矩阵大小:"<<mDescriptors1.size() <<",特征向量个数:"<<mDescriptors1.rows<<",维数:"<<mDescriptors1.cols<<endl;cout<<"图像2特征描述矩阵大小:"<<mDescriptors2.size() <<",特征向量个数:"<<mDescriptors2.rows<<",维数:"<<mDescriptors2.cols<<endl;//特征匹配vector<DMatch> vdMatches;descriptor_matcher->match(mDescriptors1,mDescriptors2,vdMatches);//筛选匹配结果//距离是指两个特征向量间的欧式距离,表明两个特征的差异,值越小表明两个特征点越接近int nMinDis=100,nMaxDis=0;for (int i=0;i<vdMatches.size();i++){if (nMinDis>vdMatches[i].distance)nMinDis=vdMatches[i].distance;if (nMaxDis<vdMatches[i].distance)nMaxDis=vdMatches[i].distance;}cout<<"最大距离:"<<nMaxDis<<endl; cout<<"最小距离:"<<nMinDis<<endl; vector<DMatch> vdGoodMatches;for (int i=0;i<vdMatches.size();i++){if (vdMatches[i].distance < nMaxDis * 0.3)//0.3为参考值,距离是指两个特征向量间的欧式距离,表明两个特征的差异,//值越小表明两个特征点越接近 。越小结果越精,但剩下的点少;越大结果//越粗,剩下的点多vdGoodMatches.push_back(vdMatches[i]);}//画出匹配结果Mat mMatchResult;drawMatches(image1,vkKeypoints1,image2,vkKeypoints2,vdGoodMatches,mMatchResult,Scalar::all(-1),//Scalar::all(-1)表示将各匹配点颜色随机生成CV_RGB(0,255,0),//未匹配点的颜色Mat(),DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);//NOT_DRAW_SINGLE_POINTS 不画出未匹配点namedWindow("Match");imshow("Match",mMatchResult);waitKey();return 0;}
运行结果:
参考:http://blog.csdn.net/masibuaa/article/details/8998601
- opencv2.4 sift算法的使用
- OpenCV2.4.13 SIFT算法
- 基于vs2008的OpenCV2.3.1配置及SIFT算法实现
- SIFT算法的c++实现(VS2010+OpenCV2.3.1)
- SIFT算法的c++实现(VS2010+OpenCV2.3.1)
- SIFT算法的c++实现(VS2010+OpenCV2.3.1)
- SIFT算法的c++实现(VS2010+OpenCV2.3.1)
- 基于vs2008的OpenCV2.3.1配置及SIFT算法实现
- 【OpenCV】 基于 ransac 算法的 sift 特征匹配程序(开发环境为OpenCV2.3.1+VS2010)
- 【OpenCV】 基于 ransac 算法的 sift 特征匹配程序(开发环境为OpenCV2.3.1+VS2010)
- 利用opencv2.4.10+VS2012和RobHess的sift特征算法实现全景图像拼接
- OpenCV】 基于 ransac 算法的 sift 特征匹配程序(开发环境为OpenCV2.3.1+VS2010)
- Linux系统下OpenCV2.x的安装与SIFT算法测试
- SIFT算法的几个问题
- sift算法不要用opencv2.4.3来写,因为sift的有关东西都移到nonfree模块了。用2.3.1版本的吧,少年。。
- OpenCV2.4.9新版本使用问题---sift,surf无法使用
- OpenCV2.4.9新版本使用问题---sift,surf无法使用
- 9.4 【OpenCV】 基于 ransac 算法的 sift 特征匹配程序(开发环境为OpenCV2.3.1+VS2010)
- 第一章----绪论(笔记)
- 【视频】javascript16-17 列表收起弹出和使用DOM创建表格
- 笔试准备之——C经典算法18例之二
- 输入一个链表,从尾到头打印链表每个节点的值。
- C语言位运算详解
- opencv2.4 sift算法的使用
- Fragment用法以及接口的复习
- Linux R 安装
- libcurl使用多线程下载大文件源码示例!
- 解析oracle的rownum
- ejb_se/servlet/jsp
- 博弈问题及SG函数
- Android sharedUserId研究记录
- 请输入一个年份,判断是否是闰年?