#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
匹配结果: