版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/legacy/legacy.hpp"
#include "iostream"
#include "time.h"
using namespace cv;
int main( )
{
long time = clock();
Mat image1 = imread("F://army//person.jpg");
Mat image2 = imread("F://army//person4.jpg");
// 检测surf特征点
vector<KeyPoint> keypoints1, keypoints2;
SurfFeatureDetector detector(700);
detector.detect(image1, keypoints1);
detector.detect(image2, keypoints2);
// 计算特征描述点
SurfDescriptorExtractor surfDesc;
Mat descriptros1, descriptros2;
surfDesc.compute(image1, keypoints1, descriptros1);
surfDesc.compute(image2, keypoints2, descriptros2);
// 计算匹配点数
BruteForceMatcher<L2<float>>matcher;
vector<DMatch> matches;
matcher.match(descriptros1, descriptros2, matches);//匹配特征向量
// 对找到的匹配特征向量进行二分排序,将匹配度强的n个向量放到前面
std::nth_element(matches.begin(), matches.begin() + 4, matches.end());
matches.erase(matches.begin() + 5, matches.end());//擦除排序在阈值后面的所有匹配点
// 画出匹配图
Mat imageMatches;
drawMatches(image1, keypoints1, image2, keypoints2, matches,imageMatches, Scalar(255, 0, 0));//进行绘制
//获得并打印两张图匹配点的坐标
vector<DMatch> ::iterator itor;//容器迭代器
printf("左边图像\n");
itor = matches.begin();
while (itor != matches.end())
{
printf("x:%.2f,y:%.2f\n", keypoints1[itor->queryIdx].pt.x, keypoints1[itor->queryIdx].pt.y);
itor++;
}
printf("右边图像\n");
itor = matches.begin();
while (itor != matches.end())
{
printf("x:%.2f,y:%.2f\n", keypoints2[itor->trainIdx].pt.x, keypoints2[itor->trainIdx].pt.y);//注意这里用的是trainIdx,其保存着右边图像匹配点的序号,而上边的queryIdx保存着左边图像匹配点的序号
itor++;
}
printf("匹配花费时间%dms", clock() - time);
imshow("image2", imageMatches);
//printf("\n%d",matches.end()-matches.begin());
waitKey();
return 0;
}
总结:可以自定义输出匹配坐标个数,可以用来直观的显示两张图片的相似之处,但输出比较单一,无法输出具体数值判断相似程度,适用于数量较少图片判断。