- #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;
- }
SURF原理:http://blog.csdn.net/quincuntial/article/details/50461274
轉載自:http://blog.csdn.net/quincuntial/article/details/50132089