一、特征匹配簡介
二、暴力匹配
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);