一、特征匹配简介
二、暴力匹配
1.nth_element筛选
#include "opencv2/opencv.hpp" #include <opencv2/nonfree/nonfree.hpp>//SIFT #include <opencv2/legacy/legacy.hpp>//BFMatch暴力匹配 #include <vector> #include<iostream> using namespace std; using namespace cv; void main() { Mat srcImg1 = imread("E://11.jpg"); Mat srcImg2 = imread("E://22.jpg"); //定义SIFT特征检测类对象 SiftFeatureDetector siftDetector; //定义KeyPoint变量 vector<KeyPoint>keyPoints1; vector<KeyPoint>keyPoints2; //特征点检测 siftDetector.detect(srcImg1, keyPoints1); siftDetector.detect(srcImg2, keyPoints2); //绘制特征点(关键点) Mat feature_pic1, feature_pic2; drawKeypoints(srcImg1, keyPoints1, feature_pic1, Scalar::all(-1)); drawKeypoints(srcImg2, keyPoints2, feature_pic2, Scalar::all(-1)); //显示原图 //imshow("src1", srcImg1); //imshow("src2", srcImg2); //显示结果 imshow("feature1", feature_pic1); imshow("feature2", feature_pic2); //计算特征点描述符 / 特征向量提取 SiftDescriptorExtractor descriptor; Mat description1; descriptor.compute(srcImg1, keyPoints1, description1); Mat description2; descriptor.compute(srcImg2, keyPoints2, description2); cout<<description1.cols<<endl; cout<<description1.rows<<endl; //进行BFMatch暴力匹配 BruteForceMatcher<L2<float>>matcher; //实例化暴力匹配器 vector<DMatch>matches; //定义匹配结果变量 matcher.match(description1, description2, matches); //实现描述符之间的匹配 //匹配结果筛选 nth_element(matches.begin(), matches.begin()+29, matches.end()); //提取出前30个最佳匹配结果 matches.erase(matches.begin()+30, matches.end()); //剔除掉其余的匹配结果 Mat result; drawMatches(srcImg1, keyPoints1, srcImg2, keyPoints2, matches, result, Scalar(0, 255, 0), Scalar::all(-1));//匹配特征点绿色,单一特征点颜色随机 imshow("Match_Result", result); waitKey(0); }
没有进行筛选时
进行筛选后
2.计算向量距离进行筛选(比第一种筛选方式好)
前面代码相同 //进行BFMatch暴力匹配 BruteForceMatcher<L2<float>>matcher; //实例化暴力匹配器 vector<DMatch>matches; //定义匹配结果变量 matcher.match(description1, description2, matches); //实现描述符之间的匹配 //计算向量距离的最大值与最小值:距离越小越匹配 double max_dist=matches[0].distance,min_dist=matches[0].distance; for(int i=1; i<description1.rows; i++) { if(matches.at(i).distance > max_dist) max_dist = matches[i].distance; if(matches.at(i).distance < min_dist) min_dist = matches[i].distance; } cout<<"min_distance="<<min_dist<<endl; cout<<"max_distance="<<max_dist<<endl; //匹配结果删选 vector<DMatch>good_matches; for(int i=0; i<matches.size(); i++) { if(matches[i].distance < 2*min_dist) good_matches.push_back(matches[i]); } Mat result; drawMatches(srcImg1, keyPoints1, srcImg2, keyPoints2, good_matches, result, Scalar(0, 255, 0), Scalar::all(-1));//匹配特征点绿色,单一特征点颜色随机 imshow("Match_Result", result);