OpenCV2.4.4中调用SIFT特征检测器进行图像匹配
来源:互联网 发布:c语言文件打开方式 编辑:程序博客网 时间:2024/06/04 20:07
OpenCV中一些相关结构说明:
特征点类:
- class KeyPoint
- {
- Point2f pt;
- float size;
- float angle;
- float response;
- int octave;
- int class_id;
- }
存放匹配结果的结构:
- 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)中的一个特征描述子(特征向量)。
- #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;
- }
结果:
效果图: