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

19
我有一个与OpenCV匹配对象的问题。 我使用在OpenCV 2.3中实现的SURF算法来首先检测每个图像上的特征,然后提取这些特征的描述符。 在使用Brute Force Matcher进行匹配时的问题是,我不知道如何判断两个图像是否匹配,因为当我使用两个不同的图像时,在两个图像中的描述符之间会出现连接线!
我的代码输出,无论我比较的两个图像是相似还是不同,结果图像都表明这两个图像已匹配。
问题是:我该如何区分这两个图像?
正确匹配: 错误匹配!! : 我的代码:
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;
3个回答

19

问题在于仅使用Brute Force Matcher,我在《OpenCV 2计算机视觉应用程序设计食谱》中找到了一些方法,可以获取两个视图之间一组良好匹配的方法。

第9章:使用随机采样一致性进行图像匹配

他们使用K-Nearest Neighbor和RANSAC算法。

感谢。


2
这本书非常有用! - user349026

9

对于去除离群值,RANSAC + 单应性变换是一种很好的方法,特别是在比较两个平面图像时。

单应性变换是RANSAC将尝试使用的模型,用于比较来自两个图像的点,并找到最佳点集,以更好地适配单应性变换的投影模型(即从一个平面到另一个平面的变换)。

cv::findHomography(srcPoints,dstPoints, RANSAC, status);

上述函数将返回一个数组状态,其中索引为内点的值为1,索引为异常值的值为0,因此您可以通过检查此状态数组来删除异常值。


1
使用 LMEDS(在 Android 上为 Calib3d.LMEDS)对我来说效果更好,我不知道为什么,在我的课程项目中,Matlab 中的 RANSAC 给出了非常好的结果。但是,无论如何,去除异常值是必须的! - Mustafa

4

你需要修改你的海森矩阵,2500太大了。尝试使用50。当你使用较大的海森矩阵时,结果会有很多关键点,导致一些不必要的问题。另外,关于SURF的其他信息是你的标记需要更加丰富,具有更多细节。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接