19

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

我的代码的这些输出,无论是两个图像 - 我与它们进行比较 - 是相似的还是不同的,结果图像表明这两个图像是匹配的。

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

真实匹配:

http://store1.up-00.com/Jun11/hxM00286.jpg

错误匹配!!:

http://store1.up-00.com/Jun11/D5H00286.jpg

我的代码:

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;
4

3 回答 3

19

问题在于仅使用蛮力匹配器,我在“OpenCV 2 Computer Vision Application Programming Cookbook”中找到了在两个视图之间获得一组良好匹配的方法

Ch9:使用随机样本共识匹配图像

他们正在使用 K-Nearest Neighbor 和 RANSAC

谢谢

于 2011-09-05T13:08:04.757 回答
9

对于去除异常值, RANSAC + 单应性是比较两个平面图像时的好方法。

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

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

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

于 2012-12-19T16:23:02.910 回答
4

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

于 2013-03-01T00:58:49.253 回答