Surf特徵點檢測與匹配
阿新 • • 發佈:2019-01-03
#include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\nonfree\features2d.hpp> #include <opencv2\nonfree\nonfree.hpp> #include <opencv2\calib3d\calib3d.hpp> #include <iostream> using namespace std; using namespace cv; vector<DMatch> ransac(vector<KeyPoint> queryKeyPoint,vector<KeyPoint> trainKeyPoint,vector<DMatch> matches); int main(int argc,char* argv[]) { //定義影象 Mat queryImage,trainImage; //讀取影象 queryImage = imread("3.jpg",IMREAD_COLOR); trainImage = imread("4.jpg",IMREAD_COLOR); //判斷是否讀取影象 if(queryImage.empty() || trainImage.empty()) { cerr<<"Failure in loading image"<<endl; return -1; } //定義Surf特徵檢測器 SurfFeatureDetector surfDetector; //定義特徵點 vector<KeyPoint> queryKeyPoint,trainKeyPoint; //檢測surf特徵 surfDetector.detect(queryImage,queryKeyPoint); surfDetector.detect(trainImage,trainKeyPoint); //檢視檢測到的特徵點的數目 cout<<"Number of queryKeyPoint:"<<queryKeyPoint.size()<<endl; cout<<"Number of trainKeyPoint:"<<trainKeyPoint.size()<<endl; //定義繪製surf特徵點的影象 Mat queryImageKeyPoint,trainImageKeyPoint; //繪製surf特徵點 drawKeypoints(queryImage,queryKeyPoint,queryImageKeyPoint,Scalar(0,0,255), /*DrawMatchesFlags::DRAW_RICH_KEYPOINTS*/DrawMatchesFlags::DEFAULT); drawKeypoints(trainImage,trainKeyPoint,trainImageKeyPoint,Scalar(0,0,255), /*DrawMatchesFlags::DRAW_RICH_KEYPOINTS*/DrawMatchesFlags::DEFAULT); //定義顯示視窗,可不要 namedWindow("queryImageKeyPoint",CV_WINDOW_AUTOSIZE); namedWindow("trainImageKeyPoint",CV_WINDOW_AUTOSIZE); //顯示surf特徵點 imshow("queryImageKeyPoint",queryImageKeyPoint); imshow("trainImageKeyPoint",trainImageKeyPoint); //定義surf特徵描述子 Mat queryDescriptor,trainDescriptor; //定義Surf特徵描述子提取器 SurfDescriptorExtractor surfExtractor; //提取特徵描述子 surfExtractor.compute(queryImage,queryKeyPoint,queryDescriptor); surfExtractor.compute(trainImage,trainKeyPoint,trainDescriptor); //定義描述子匹配對 vector<DMatch> bfMatches; vector<DMatch> flannMatches; //Brute Match,窮舉法求最近鄰 BFMatcher bfMatcher; bfMatcher.match(queryDescriptor,trainDescriptor,bfMatches); //FlannBasedMatcher,最近鄰近似匹配 FlannBasedMatcher flannMatcher; flannMatcher.match(queryDescriptor,trainDescriptor,flannMatches); //對匹配點進行RANSAC過濾 vector<DMatch> ransac_BFMatches,ransac_FlannMatches; ransac_BFMatches=ransac(queryKeyPoint,trainKeyPoint,bfMatches); ransac_FlannMatches=ransac(queryKeyPoint,trainKeyPoint,flannMatches); //定義匹配影象 Mat bfMatchImage,flannMatchImage; //繪製匹配影象 //drawMatches(queryImage,queryKeyPoint,trainImage,trainKeyPoint,bfMatches,bfMatchImage); //drawMatches(queryImage,queryKeyPoint,trainImage,trainKeyPoint,flannMatches,flannMatchImage); drawMatches(queryImage,queryKeyPoint,trainImage,trainKeyPoint,ransac_BFMatches,bfMatchImage); drawMatches(queryImage,queryKeyPoint,trainImage,trainKeyPoint,ransac_FlannMatches,flannMatchImage); //顯示匹配結果 imshow("BFMatch",bfMatchImage); imshow("FlannMatch",flannMatchImage); waitKey(0); return 0; } vector<DMatch> ransac(vector<KeyPoint> queryKeyPoint,vector<KeyPoint> trainKeyPoint,vector<DMatch> matches) { cout<<"ransac前:"<<matches.size()<<endl; vector<Point2f> queryPoints(matches.size()),trainPoints(matches.size()); for(int i=0;i<matches.size();i++) { queryPoints[i] = queryKeyPoint[matches[i].queryIdx].pt; trainPoints[i] = trainKeyPoint[matches[i].trainIdx].pt; } Mat H; vector<unsigned char> inlierMask(matches.size()); vector<DMatch> ransac_matches; H = findHomography(queryPoints,trainPoints,CV_RANSAC,3,inlierMask); for(int i=0;i<inlierMask.size();i++) { if(inlierMask[i]) { ransac_matches.push_back(matches[i]); } } cout<<"ransac後:"<<ransac_matches.size()<<endl; return ransac_matches; }
匹配結果: