首先安装opencv以及opencv的features模块
// 来自高翔SLAM十四讲
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/features2d/features2d.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int main(){
Mat img_1 = imread("test.jpg",CV_LOAD_IMAGE_COLOR);
Mat img_2 = imread("test.jpg",CV_LOAD_IMAGE_COLOR);
// 初始化
std::vector<KeyPoint> keypoints_1, keypoints_2;
Mat descriptors_1, descriptors_2;
Ptr<ORB> orb = ORB::create(500, 1.2f, 8, 31, 0, 2, ORB::HARRIS_SCORE, 31, 20); // 汉明距离
// 第一步:检测FAST角点位置
orb->detect(img_1,keypoints_1);
orb->detect(img_2, keypoints_2);
// 第二步:根据角点位置计算BRIEF描述子
orb->compute(img_1, keypoints_1, descriptors_1);
orb->compute(img_2, keypoints_2, descriptors_2);
// 显示检测出来的特征点
Mat outimg1;
drawKeypoints(img_1, keypoints_1, outimg1, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
imshow("ORB特征点检测", outimg1);
// 第三步:对两幅图像中的BRIEF描述子进行匹配,使用汉明距离
vector<DMatch> matches;
BFMatcher matcher(NORM_HAMMING); // 汉明距离的暴力匹配
matcher.match(descriptors_1, descriptors_2, matches);
// 第四步:对匹配点进行筛选
double min_dist = 10000, max_dist = 0;
// 找出所有匹配之间的最小距离和最大距离,即最相似和最不相似的两组点之间的距离
for(int i=0; i<descriptors_1.rows; i++){
double dist = matches[i].distance;
min_dist = min_dist < dist ? min_dist : dist;
max_dist = max_dist > dist ? max_dist : dist;
}
std::cout<<"-- Max dist : "<<max_dist<<std::endl;
std::cout<<"-- Min dist : "<<min_dist<<std::endl;
// 当描述子之间的距离大于两倍的最小距离时,认为匹配有误。
// 有时候最小距离很小,所以还是要设置一个经验值作为下限
std::vector<DMatch> good_matches;
for(int i=0; i<descriptors_1.rows; i++){
if(matches[i].distance <= max(2*min_dist, 30.0)){
good_matches.push_back(matches[i]);
}
}
// 第5步:绘制匹配结果
Mat img_match;
Mat img_goodmatch;
drawMatches(img_1, keypoints_1, img_2, keypoints_2, matches, img_match);
drawMatches(img_1, keypoints_1, img_2, keypoints_2, good_matches, img_goodmatch);
imshow("所有匹配点",img_match);
imshow("优化后的匹配点",img_goodmatch);
waitKey(0);
return 0;
}