先上代码
#include "opencv2/opencv.hpp"
#include <opencv2/nonfree/nonfree.hpp>//SIFT
#include <opencv2/legacy/legacy.hpp>//BFMatch暴力匹配
#include <vector>
#include<iostream>
using namespace std;
using namespace cv;
void main()
{
Mat srcImg1 = imread("D:\\0.jpg");
Mat srcImg2 = imread("D:\\1.jpg");
resize(srcImg1,srcImg1,Size(srcImg1.cols*3,srcImg1.rows*3));
resize(srcImg2,srcImg2,Size(srcImg2.cols/3,srcImg2.rows/3));
//定义SIFT特征检测类对象
SiftFeatureDetector siftDetector(1000);//先给SiftFeatureDetector 定义一个对象,这里与C++构造函数类似。这里1000是一个匹配精度,值越大匹配精度越大
//定义KeyPoint变量,用来存放待会特征点匹配的结果
vector<KeyPoint>keyPoints1;
vector<KeyPoint>keyPoints2;
//特征点检测
siftDetector.detect(srcImg1, keyPoints1);//调用detect属性,这个属性其实是个函数
siftDetector.detect(srcImg2, keyPoints2);//从图片中检查特征点存入keyPoints2中
//绘制特征点(关键点)
Mat feature_pic1, feature_pic2;
drawKeypoints(srcImg1, keyPoints1, feature_pic1, Scalar::all(-1));
drawKeypoints(srcImg2, keyPoints2, feature_pic2, Scalar::all(-1));
//显示原图
imshow("src1", srcImg1);
imshow("src2", srcImg2);
//显示结果
imshow("feature1", feature_pic1);
imshow("feature2", feature_pic2);
//计算特征点描述符 / 特征向量提取
SiftDescriptorExtractor descriptor;//定义一个对象
Mat description1;
descriptor.compute(srcImg1, keyPoints1, description1);//开始调用对象的compute属性计算
Mat description2;
descriptor.compute(srcImg2, keyPoints2, description2);
//进行BFMatch暴力匹配
BruteForceMatcher<L1<float>>matcher; //实例化暴力匹配器
vector<DMatch>matches; //定义匹配结果变量。用来存放匹配到的点
matcher.match(description1, description2, matches); //实现描述符之间的匹配
//匹配结果筛选
nth_element(matches.begin(), matches.begin()+29, matches.end()); //提取出前30个最佳匹配结果
matches.erase(matches.begin()+30, matches.end()); //剔除掉其余的匹配结果
Mat result;
drawMatches(srcImg1, keyPoints1, srcImg2, keyPoints2, matches, result, Scalar(0, 255, 0), Scalar::all(-1));//匹配特征点绿色,单一特征点颜色随机
imshow("Match_Result", result);
waitKey(0);
}