C++ OpenCV-使用SURF描述符和BruteForceMatcher进行对象匹配

C++ OpenCV-使用SURF描述符和BruteForceMatcher进行对象匹配,c++,opencv,computer-vision,surf,object-detection,C++,Opencv,Computer Vision,Surf,Object Detection,我有一个关于与OpenCV匹配的对象的问题。 我使用opencv 2.3中实现的SURF算法首先检测每个图像上的特征,然后提取这些特征的描述符。 使用蛮力匹配器进行匹配的问题在于,我不知道如何判断两个图像是否匹配,这就好比我使用两个不同的图像时,两个图像中的描述符之间有一条线 我的代码的这些输出,或者两个图像(我与它们比较)相似或者不同,结果图像表明两个图像是匹配的 问题是:如何区分这两幅图像? 真实匹配: 错误匹配!!: 我的代码: Mat image1, outImg1, image2,

我有一个关于与OpenCV匹配的对象的问题。 我使用opencv 2.3中实现的SURF算法首先检测每个图像上的特征,然后提取这些特征的描述符。 使用蛮力匹配器进行匹配的问题在于,我不知道如何判断两个图像是否匹配,这就好比我使用两个不同的图像时,两个图像中的描述符之间有一条线

我的代码的这些输出,或者两个图像(我与它们比较)相似或者不同,结果图像表明两个图像是匹配的

问题是:如何区分这两幅图像?

真实匹配:

错误匹配!!:

我的代码:

Mat image1, outImg1, image2, outImg2;

// vector of keypoints
vector<KeyPoint> keypoints1, keypoints2;

// Read input images
image1 = imread("C://Google-Logo.jpg",0);
image2 = imread("C://Alex_Eng.jpg",0);

SurfFeatureDetector surf(2500);
surf.detect(image1, keypoints1);
surf.detect(image2, keypoints2);
drawKeypoints(image1, keypoints1, outImg1, Scalar(255,255,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
drawKeypoints(image2, keypoints2, outImg2, Scalar(255,255,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

namedWindow("SURF detector img1");
imshow("SURF detector img1", outImg1);

namedWindow("SURF detector img2");
imshow("SURF detector img2", outImg2);

SurfDescriptorExtractor surfDesc;
Mat descriptors1, descriptors2;
surfDesc.compute(image1, keypoints1, descriptors1);
surfDesc.compute(image2, keypoints2, descriptors2);

BruteForceMatcher<L2<float>> matcher;
vector<DMatch> matches;
matcher.match(descriptors1,descriptors2, matches);

nth_element(matches.begin(), matches.begin()+24, matches.end());
matches.erase(matches.begin()+25, matches.end());

Mat imageMatches;
drawMatches(image1, keypoints1, image2, keypoints2, matches, imageMatches, Scalar(255,255,255));

namedWindow("Matched");
imshow("Matched", imageMatches);

cv::waitKey();
return 0;
Mat image1,outImg1,image2,outImg2;
//关键点向量
向量关键点1,关键点2;
//读取输入图像
image1=imread(“C://googlelogo.jpg”,0);
image2=imread(“C://Alex_Eng.jpg”,0);
表面特征探测器表面粗糙度(2500);
冲浪检测(图像1,关键点1);
冲浪检测(图像2,关键点2);
drawKeypoints(图像1、keypoints1、outImg1、标量(255255)、DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
drawKeypoints(图像2、keypoints2、outImg2、标量(255255255)、DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
namedWindow(“海浪探测器img1”);
imshow(“海浪探测器img1”,outImg1);
namedWindow(“冲浪探测器img2”);
imshow(“海浪探测器img2”,outImg2);
SURFdescriptor surfDesc;
Mat描述符1,描述符2;
surfDesc.compute(图像1,关键点1,描述符1);
surfDesc.compute(图像2,关键点2,描述符2);
蛮力匹配器;
向量匹配;
匹配(描述符1,描述符2,匹配);
第n个元素(matches.begin(),matches.begin()+24,matches.end());
matches.erase(matches.begin()+25,matches.end());
Mat图像匹配;
drawMatches(图像1,关键点1,图像2,关键点2,匹配,图像匹配,标量(255255));
姓名(以下简称“匹配”);
imshow(“匹配”,imageMatches);
cv::waitKey();
返回0;

问题在于仅使用蛮力匹配器,我在“OpenCV 2计算机视觉应用程序编程手册”中找到了在两个视图之间获得一组良好匹配的方法

Ch9:使用随机样本一致性匹配图像

他们使用K-最近邻和RANSAC


感谢

去除异常值RANSAC+单应性是比较两幅平面图像时的一种好方法

单应性是RANSAC尝试使用的模型,用于比较两幅图像中的点,它将找到更适合单应性投影模型(从一个平面到另一个平面的变换)的最佳点集


上面的函数将返回一个数组状态,对于被认为是内联的索引为1,对于被认为是离群的索引为0,因此您可以通过检查此状态数组来删除离群值。

您需要修改Hessian,2500太多了。试试50英镑。当你使用一个大黑森,结果是很多关键点,导致一些不必要的。关于SURF的另一个信息是,你的标记需要更加丰富,有更多的细节。

这本书非常有用!在Android上使用
LMEDS
Calib3d.LMEDS
)会给我带来更好的结果,我不知道为什么在我的课程项目中,Matlab中的RANSAC会给出非常好的结果。但确实,删除大纲视图是必须的!
cv::findHomography(srcPoints,dstPoints, RANSAC, status);