#include
#include
#include
#include "opencv2/xfeatures2d.hpp"
#include "opencv2/xfeatures2d/nonfree.hpp" //SURF
#include "opencv2/xfeatures2d/cuda.hpp"
#include
#include
using namespace cv;
using namespace std;
void getMatchPoint(Mat src1, Mat src2)
{
vector
vector
Ptr
cv::BFMatcher matcher;
Mat descriptorMat1, descriptorMat2;
std::vector
detector->detectAndCompute(src1, Mat(), keys1, descriptorMat1);
detector->detectAndCompute(src2, Mat(), keys2, descriptorMat2);
matcher.match(descriptorMat1, descriptorMat2, mathces);
drawKeypoints(src1, keys1, src1, cv::Scalar::all(255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
drawKeypoints(src2, keys2, src2, cv::Scalar::all(255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
Mat matchMat;
drawMatches(src1, keys1, src2, keys2, mathces, matchMat);
cv::imshow("Mathces", matchMat);
imshow("image1", src1);
imshow("image2", src2);
#if 1
double max_dist = 0; double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for (int i=0; i
double dist = mathces[i].distance;
if (dist < min_dist) min_dist = dist;
if (dist > max_dist) max_dist = dist;
}
cout<<"-- Max dist :"<< max_dist<
//-- Draw only "good" matches (i.e. whose distance is less than 0.6*max_dist )
//-- PS.- radiusMatch can also be used here.
vector< DMatch > good_matches;
for (int i=0; i
if (mathces[i].distance < 0.6*max_dist)
{
good_matches.push_back(mathces[i]);
}
}
Mat img_matches;
drawMatches(src1, keys1, src2, keys2,
good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
vector
imwrite("FASTResult.jpg", img_matches);
imshow("goodMatch", img_matches);
#endif
#if 1
// 分配空间
int ptCount = (int)mathces.size();
Mat p1(ptCount, 2, CV_32F);
Mat p2(ptCount, 2, CV_32F);
// 把Keypoint转换为Mat
Point2f pt;
for (int i=0; i
pt = keys1[mathces[i].queryIdx].pt;
p1.at
p1.at
pt = keys2[mathces[i].trainIdx].pt;
p2.at
p2.at
}
// 用RANSAC方法计算 基本矩阵F
Mat fundamental;
vector
fundamental = findFundamentalMat(p1, p2, RANSACStatus, FM_RANSAC);
// 计算野点个数
int OutlinerCount = 0;
for (int i=0; i
if (RANSACStatus[i] == 0) // 状态为0表示野点
{
OutlinerCount++;
}
}
// 计算内点
vector
vector
vector
// 上面三个变量用于保存内点和匹配关系
int InlinerCount = ptCount - OutlinerCount;
InlierMatches.resize(InlinerCount);
Inlier1.resize(InlinerCount);
Inlier2.resize(InlinerCount);
InlinerCount = 0;
for (int i=0; i
if (RANSACStatus[i] != 0)
{
Inlier1[InlinerCount].x = p1.at
Inlier1[InlinerCount].y = p1.at
Inlier2[InlinerCount].x = p2.at
Inlier2[InlinerCount].y = p2.at
InlierMatches[InlinerCount].queryIdx = InlinerCount;
InlierMatches[InlinerCount].trainIdx = InlinerCount;
cout<<"index = "< imshow("FMatch", OutImage);
#endif
}
结果图:
//good_matches.jpg
// FmatrixResult.jpg
知识点补充:
DMATCH 数据结构:
struct DMatch
{ //三个构造函数
DMatch():
queryIdx(-1),trainIdx(-1),imgIdx(-1),distance(std::numeric_limits::max()) {}
DMatch(int _queryIdx, int _trainIdx, float _distance ) :
queryIdx( _queryIdx),trainIdx( _trainIdx), imgIdx(-1),distance( _distance) {}
DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance ) :
queryIdx(_queryIdx), trainIdx( _trainIdx), imgIdx( _imgIdx),distance( _distance) {}
int queryIdx; //此匹配对应的查询图像的特征描述子索引(输入图1)
int trainIdx; //此匹配对应的训练(模板)图像的特征描述子索引(输入图2)
int imgIdx; //训练图像的索引(若有多个)
float distance; //两个特征向量之间的欧氏距离,越小表明匹配度越高。
booloperator < (const DMatch &m) const;
};
参考文献:
http://blog.csdn.net/ikerpeng/article/details/47972959