#if !defined MATCHER
#define MATCHER
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/calib3d/calib3d.hpp>
using namespace cv;
using namespace std;
class HarrisMatcher {
private:
Ptr<GoodFeaturesToTrackDetector> detcetor;
int maxnum;
float ratio; // 第一个以及第二个最邻近之间的最大比率
bool refineF; // 是否改善F矩阵
double distance; // 到极线的最小距离
double confidence; // 置信等级(概率)
public:
HarrisMatcher() : ratio(0.75f), refineF(true), confidence(0.89), distance(10.0),maxnum(500)
{
detcetor= new GoodFeaturesToTrackDetector();
}
// Set the feature detector
void setFeatureDetector(Ptr<GoodFeaturesToTrackDetector>& detect)
{
detcetor= detect;
}
// Set the minimum distance to epipolar in RANSAC
void setMinDistanceToEpipolar(double d)
{
distance= d;
}
// Set confidence level in RANSAC
void setConfidenceLevel(double c)
{
confidence= c;
}
// Set the NN ratio
void setRatio(float r)
{
ratio= r;
}
// if you want the F matrix to be recalculated
void refineFundamental(bool flag)
{
refineF= flag;
}
// Clear matches for which NN ratio is > than threshold
// return the number of removed points
// (corresponding entries being cleared, i.e. size will be 0)
int ratioTest(vector<vector<DMatch>>& matches)
{
int removed=0;
// for all matches
for (vector<vector<DMatch>>::iterator matchIterator= matches.begin();
matchIterator!= matches.end(); ++matchIterator)
{
// if 2 NN has been identified
if (matchIterator->size() > 1)
{
// check distance ratio
if ((*matchIterator)[0].distance/(*matchIterator)[1].distance > ratio)
{
matchIterator->clear(); // remove match
removed++;
}
}
else
{ // does not have 2 neighbours
matchIterator->clear(); // remove match
removed++;
}
}
return removed;
}
// Insert symmetrical matches in symMatches vector
void symmetryTest(const vector<vector<DMatch>>& matches1,
const vector<vector<DMatch>>& matches2,
vector<DMatch>& symMatches)
{
// for all matches image 1 -> image 2
for (vector<vector<DMatch>>::const_iterator matchIterator1= matches1.begin();
matchIterator1!= matches1.end(); ++matchIterator1)
{
if (matchIterator1->size() < 2) // ignore deleted matches
continue;
// for all matches image 2 -> image 1
for (vector<vector<DMatch>>::const_iterator matchIterator2= matches2.begin();
matchIterator2!= matches2.end(); ++matchIterator2)
{
if (matchIterator2->size() < 2) // ignore deleted matches
continue;
// Match symmetry test
if ((*matchIterator1)[0].queryIdx == (*matchIterator2)[0].trainIdx &&
(*matchIterator2)[0].queryIdx == (*matchIterator1)[0].trainIdx)
{
// add symmetrical match
symMatches.push_back(DMatch((*matchIterator1)[0].queryIdx,
(*matchIterator1)[0].trainIdx,
(*matchIterator1)[0].distance));
break; // next match in image 1 -> image 2
}
}
}
}
void xgxsmatch()
{
}
double xgxs(int matchwin, int rL, int cL, int rR, int cR)
{
//采用相关系数算法
int m,n;
double r,Sg,Sf,Sgf,Sgg,Sff,mn;
mn=matchwin*matchwin;
Sg=Sgg=0;
for(m=(-1)*matchwin/2;m<matchwin/2;m++)
for(n=(-1)*matchwin/2;n<matchwin/2;n++)
{
Sg+=OrgPh[0].Newph[ceng][rL+m][cL+n];
Sgg+=(OrgPh[0].Newph[ceng][rL+m][cL+n])*(OrgPh[0].Newph[ceng][rL+m][cL+n]);
}
Sf=Sgf=Sff=r=0;
for(m=(-1)*matchwin/2;m<matchwin/2;m++)
for(n=(-1)*matchwin/2;n<matchwin/2;n++)
{
Sf+=OrgPh[1].Newph[ceng][rR+m][cR+n];
Sgf+=OrgPh[0].Newph[ceng][rL+m][cL+n]*OrgPh[1].Newph[ceng][rR+m][cR+n];
Sff+=(OrgPh[1].Newph[ceng][rR+m][cR+n])*(OrgPh[1].Newph[ceng][rR+m][cR+n]);
}
r=(Sgf-Sg*Sf/mn)/sqrt((Sgg-Sg*Sg/mn)*(Sff-Sf*Sf/mn));
return r;
}
// 基于RANSAC的识别优质矩阵
// 返回基础矩阵
Mat ransacTest(const vector<DMatch>& matches,
const vector<KeyPoint>& keypoints1,
const vector<KeyPoint>& keypoints2,
vector<DMatch>& outMatches)
{
// 将keypoints类型到Point2f
vector<Point2f> points1, points2;
for (vector<DMatch>::const_iterator it= matches.begin();
it!= matches.end(); ++it)
{
// 得到左边特征点的坐标
float x= keypoints1[it->queryIdx].pt.x;
float y= keypoints1[it->queryIdx].pt.y;
points1.push_back(Point2f(x,y));
// 得到右边特征点的坐标
x= keypoints2[it->trainIdx].pt.x;
y= keypoints2[it->trainIdx].pt.y;
points2.push_back(Point2f(x,y));
}
// 用RANSAC计算F矩阵
vector<uchar> inliers(points1.size(),0);
Mat fundemental= findFundamentalMat(
Mat(points1),Mat(points2), // 匹配点
inliers, // 匹配状态(inlier ou outlier)
CV_FM_LMEDS, // RANSAC method
distance, // 到极线的距离
confidence); // 置信概率
// 提取通过的匹配
vector<uchar>::const_iterator itIn= inliers.begin();
vector<DMatch>::const_iterator itM= matches.begin();
// 遍历所有匹配
for ( ;itIn!= inliers.end(); ++itIn, ++itM)
{
if (*itIn)
{ // 为有效匹配
outMatches.push_back(*itM);
}
}
cout << "Number of matched points (after cleaning): " << outMatches.size() << endl;
if (refineF)
{
// F矩阵将使用所有的接受的匹配重新计算
// 转换keypoints到Point2f准备计算最终的F矩阵
points1.clear();
points2.clear();
for (vector<DMatch>::const_iterator it= outMatches.begin();
it!= outMatches.end(); ++it)
{
// 得到左边特征点的坐标
float x= keypoints1[it->queryIdx].pt.x;
float y= keypoints1[it->queryIdx].pt.y;
points1.push_back(Point2f(x,y));
// 得到右边特征点的坐标
x= keypoints2[it->trainIdx].pt.x;
y= keypoints2[it->trainIdx].pt.y;
points2.push_back(Point2f(x,y));
}
// 从所有接受的匹配中计算8点F
fundemental= findFundamentalMat(
Mat(points1),Mat(points2), // 匹配
CV_FM_8POINT); // 8点法
}
return fundemental;
}
// Match feature points using symmetry test and RANSAC
// returns fundemental matrix
Mat match(Mat& image1, Mat& image2, // input images
vector<DMatch>& matches, // output matches and keypoints
vector<KeyPoint>& keypoints1, vector<KeyPoint>& keypoints2)
{
double t=cvGetTickCount();
detcetor->detect(image1,keypoints1);
detcetor->detect(image2,keypoints2);
printf("Feature Detection Time is %lf s.\n",((cvGetTickCount()-t)/(cvGetTickFrequency()*1000000)));
cout << "Number of Harris points (1): " << keypoints1.size() << endl;
cout << "Number of Harris points (2): " << keypoints2.size() << endl;
// 创建匹配器
BFMatcher matcher;
BFMatcher matcher2;
// from image 1 to image 2
// based on k nearest neighbours (with k=2)
vector<vector<DMatch>> matches1;
matcher.(descriptors1,descriptors2,
matches1, // vector of matches (up to 2 per entry)
2); // return 2 nearest neighbours
// from image 2 to image 1
// based on k nearest neighbours (with k=2)
vector<vector<DMatch>> matches2;
matcher.knnMatch(descriptors2,descriptors1,
matches2, // vector of matches (up to 2 per entry)
2); // return 2 nearest neighbours
cout << "Number of matched points 1->2: " << matches1.size() << endl;
cout << "Number of matched points 2->1: " << matches2.size() << endl;
// 3. Remove matches for which NN ratio is > than threshold
// clean image 1 -> image 2 matches
int removed= ratioTest(matches1);
cout << "Number of matched points 1->2