#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/nonfree/features2d.hpp>
#include<opencv2/legacy/legacy.hpp>
using namespace cv;
using namespace std;
void readme();
/** @function main */
int main(int argc, char** argv)
{
Mat img_1 = imread("color52.bmp", CV_LOAD_IMAGE_GRAYSCALE);
Mat img_2 = imread("color51.bmp", CV_LOAD_IMAGE_GRAYSCALE);
if (!img_1.data || !img_2.data)
{
return -1;
}
//-- Step 1: Detect the keypoints using SURF Detector
int minHessian = 400;
SurfFeatureDetector detector(minHessian);//定义最大特征数400
std::vector<KeyPoint> keypoints_1, keypoints_2;//OpenCV里为角点检测提供了统一的接口,通过类下面的detect方法来检测对应的角点,而输出格式都是vector<KeyPoint>
detector.detect(img_1, keypoints_1);//特征检测
detector.detect(img_2, keypoints_2);
//-- Step 2: Calculate descriptors (feature vectors)
SurfDescriptorExtractor extractor;
Mat descriptors_1, descriptors_2;
extractor.compute(img_1, keypoints_1, descriptors_1);//提取SURF特征点以及其描述
extractor.compute(img_2, keypoints_2, descriptors_2);
//-- Step 3: Matching descriptor vectors with a brute force matcher计算匹配点数
BruteForceMatcher< L2<float> > matcher;
std::vector< DMatch > matches;
matcher.match(descriptors_1, descriptors_2, matches);
/*void match(const Mat& queryDescriptors, const Mat& trainDescriptors,
CV_OUT vector<DMatch>& matches, const Mat& mask = Mat()) const;
*/
//匹配点向量和画图
int w = img_1.cols;
int h = img_1.rows;
Mat showImg(h, 2*w, CV_8UC1, Scalar(0, 0, 0));
img_1.copyTo(showImg(Rect(0, 0, w,h)));
img_2.copyTo(showImg(Rect(w, 0, w,h)));
vector<Point2f> feture_matche[2];
for (int i = 0; i < matches.size(); ++i)
{
Point2f p1 = keypoints_1[matches[i].queryIdx].pt; //matches[i].queryIdx第i个匹配的特征点的索引,通过索引获得这个特征点在图一特征向量中的坐标
Point2f p2 = keypoints_2[matches[i].trainIdx].pt;
p2.x += w;
CvScalar color = CV_RGB(rand() % 255, rand() % 255, rand() % 255);
line(showImg, p1, p2, color);
//int g = matches[i].distance;
//将匹配点保存在feture_mache2维向量中
feture_matche[0].push_back(p1);//未分配内存所以不能使用feture_matche[0][i]=p1
feture_matche[1].push_back(p2);
}
for (int i = 0; i < feture_matche[0].size(); i++)
cout << "图1已经匹配的特征点坐标p1" << i << "=" << feture_matche[0][i] << " " << "图2已经匹配的特征点坐标p2" << i << "=" << feture_matche[1][i] << endl;
cout << matches.size() << " " << feture_matche[0].size() << " " << feture_matche[1].size() << endl;//这三个数是相等的
imshow("match", showImg);
//只提取25个匹配点并画出
std::nth_element(matches.begin(), matches.begin() + 24, matches.end());
matches.erase(matches.begin() + 25, matches.end());
//-- Draw matches
Mat img_matches;
drawMatches(img_1, keypoints_1, img_2, keypoints_2, matches, img_matches,Scalar(255, 0, 0));//未定义颜色则将画出不同颜色匹配线条
// -- Show detected matches
imshow("Matches", img_matches);
waitKey(0);
return 0;
}
/** @function readme */