生活随笔
收集整理的这篇文章主要介绍了
OpenCV2.4.4中调用SIFT特征检测器进行图像匹配
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
OpenCV中一些相关结构说明:
特征点类:
[cpp] view plain
copy class KeyPoint { Point2f pt; float size; float angle; float response; int octave; int class_id; }
存放匹配结果的结构:
[cpp] view plain
copy 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; };
说明:以两个特征点描述子(特征向量)之间的欧氏距离作为特征点匹配的相似度准则,假设特征点对p和q的
特征描述子分别为Desp和Desq,则其欧氏距离定义为:
所以每个匹配分别对应训练图像(train)和查询图像(query)中的一个特征描述子(特征向量)。
[cpp] view plain
copy #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/nonfree/nonfree.hpp" #include "opencv2/nonfree/features2d.hpp" #include <iostream> #include <stdio.h> #include <stdlib.h> using namespace cv; using namespace std; int main() { initModule_nonfree(); Ptr<FeatureDetector> detector = FeatureDetector::create( "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!"; Mat img1 = imread("desk.jpg"); Mat img2 = imread("desk_glue.jpg"); double t = getTickCount(); vector<KeyPoint> keypoints1,keypoints2; detector->detect( img1, keypoints1 ); detector->detect( img2, keypoints2 ); cout<<"图像1特征点个数:"<<keypoints1.size()<<endl; cout<<"图像2特征点个数:"<<keypoints2.size()<<endl; Mat descriptors1,descriptors2; descriptor_extractor->compute( img1, keypoints1, descriptors1 ); descriptor_extractor->compute( img2, keypoints2, descriptors2 ); t = ((double)getTickCount() - t)/getTickFrequency(); cout<<"SIFT算法用时:"<<t<<"秒"<<endl; cout<<"图像1特征描述矩阵大小:"<<descriptors1.size() <<",特征向量个数:"<<descriptors1.rows<<",维数:"<<descriptors1.cols<<endl; cout<<"图像2特征描述矩阵大小:"<<descriptors2.size() <<",特征向量个数:"<<descriptors2.rows<<",维数:"<<descriptors2.cols<<endl; Mat img_keypoints1,img_keypoints2; drawKeypoints(img1,keypoints1,img_keypoints1,Scalar::all(-1),0); drawKeypoints(img2,keypoints2,img_keypoints2,Scalar::all(-1),0); vector<DMatch> matches; descriptor_matcher->match( descriptors1, descriptors2, matches ); cout<<"Match个数:"<<matches.size()<<endl; double max_dist = 0; double min_dist = 100; for(int i=0; i<matches.size(); i++) { double dist = matches[i].distance; if(dist < min_dist) min_dist = dist; if(dist > max_dist) max_dist = dist; } cout<<"最大距离:"<<max_dist<<endl; cout<<"最小距离:"<<min_dist<<endl; vector<DMatch> goodMatches; for(int i=0; i<matches.size(); i++) { if(matches[i].distance < 0.31 * max_dist) { goodMatches.push_back(matches[i]); } } cout<<"goodMatch个数:"<<goodMatches.size()<<endl; Mat img_matches; drawMatches(img1,keypoints1,img2,keypoints2,goodMatches,img_matches, Scalar::all(-1),CV_RGB(0,255,0),Mat(),2); imshow("MatchSIFT",img_matches); waitKey(0); return 0; }
结果:
效果图:
源码下载:
http://download.csdn.net/detail/masikkk/5511831
当然,这些匹配还没有经过系统的筛选,还存在大量的错配,关于匹配的筛选参见这篇文章:
利用RANSAC算法筛选SIFT特征匹配
以及RobHess的SIFT源码分析系列文章:http://blog.csdn.net/masibuaa/article/details/9191309
from: http://blog.csdn.net/masibuaa/article/details/8998601
总结
以上是生活随笔为你收集整理的OpenCV2.4.4中调用SIFT特征检测器进行图像匹配的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。