OpenCV-使用SURF描述符和BruteForceMatcher进行对象匹配
c++
computer-vision
object-detection
opencv
9
0

我对与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;
参考资料:
Stack Overflow
收藏
评论
共 3 个回答
高赞 时间 活跃

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

第9章:使用随机样本共识来匹配图像

他们正在使用K最近邻居和RANSAC

谢谢你

收藏
评论

为了消除离群值,比较两个平面图像时, RANSAC +单应性是一种很好的方法。

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

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

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

收藏
评论

您需要修改您的Hessian,2500太多了。尝试50。当您使用大的Hessian时,结果是很多关键点,从而导致不必要的事情。有关SURF的另一个信息是您的标记需要更丰富,更详细。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题