C++ OpenCV - 使用 SURF 描述符和 BruteForceMatcher 的对象匹配
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7296915/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
OpenCV - Object matching using SURF descriptors and BruteForceMatcher
提问by khateeb
I have a question about objects matching with OpenCV. I'm useing SURF algorithm implemented in opencv 2.3 to first detect features on each image, and then extracting the descriptors of these features. The problem in matching using Brute Force Matcher, I don't know how I judge that the two images are matched or not that's as when I'm using two different images there are lines between descriptors in the two images!
我有一个关于与 OpenCV 匹配的对象的问题。我使用在 opencv 2.3 中实现的 SURF 算法首先检测每个图像上的特征,然后提取这些特征的描述符。使用Brute Force Matcher进行匹配的问题,我不知道我如何判断两个图像是否匹配,因为当我使用两个不同的图像时,两个图像中的描述符之间存在线条!
These outputs of my code, either the two images -I compare with them - are similar or different, the result image indicate that the two images are matched.
我的代码的这些输出,无论是两个图像 - 我与它们进行比较 - 是相似的还是不同的,结果图像表明这两个图像是匹配的。
The question is: How can I distinguish between the two images?
问题是:如何区分这两个图像?
True matching:
真匹配:
False matching!! :
错误匹配!!:
My code:
我的代码:
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;
采纳答案by khateeb
The problem was in using Brute Force Matcher only, I found methods to obtain a set of good matches between two views at "OpenCV 2 Computer Vision Application Programming Cookbook"
问题仅在于使用 Brute Force Matcher,我在“OpenCV 2 Computer Vision Application Programming Cookbook”中找到了在两个视图之间获得一组良好匹配的方法
Ch9: Matching images using random sample consensus
Ch9:使用随机样本一致性匹配图像
They are using K-Nearest Neighbor and RANSAC
他们使用 K-Nearest Neighbor 和 RANSAC
And thanks
谢谢
回答by Jav_Rock
For removing outliers RANSAC + homographyis a good method when comparing two planar images.
为了去除异常值,RANSAC + 单应性是比较两个平面图像的好方法。
Homography is the model that RANSAC will try to use to compare points from both images and it will find the best set of points that better fit the projection model of the homography (the transformation from one plane to another).
单应性是 RANSAC 将尝试用来比较来自两个图像的点的模型,它将找到更适合单应性投影模型(从一个平面到另一个平面的变换)的最佳点集。
cv::findHomography(srcPoints,dstPoints, RANSAC, status);
The function above will return an array status that has a 1 for indices considered inliers and 0 for indices considered outliers, so you can remove outliers by checking this status array.
上面的函数将返回一个数组状态,对于被认为是内部值的索引,它的值为 1,对于被认为是异常值的索引,它的值为 0,因此您可以通过检查此状态数组来删除异常值。
回答by Ricardo Ribani
You need to modify your Hessian, 2500 is too much. Try 50. When you use a big Hessian, the result is a lot of keypoints, resulting some unnecessary. Another information about SURF is that your marker need to be more rich, with more details.
你需要修改你的Hessian,2500太多了。试试50。当你使用大Hessian时,结果是很多关键点,导致一些不必要的。关于 SURF 的另一个信息是您的标记需要更丰富,具有更多细节。