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

Posted

技术标签:

【中文标题】OpenCV - 使用 SURF 描述符和 BruteForceMatcher 进行对象匹配【英文标题】:OpenCV - Object matching using SURF descriptors and BruteForceMatcher 【发布时间】:2011-11-09 22:44:34 【问题描述】:

我有一个关于与 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;

【问题讨论】:

【参考方案1】:

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

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

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

谢谢

【讨论】:

这本书非常有用!【参考方案2】:

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

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

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

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

【讨论】:

使用LMEDSandroid 上的Calib3d.LMEDS)给我带来了更好的结果,我不知道为什么,在我的课程项目中,Matlab 中的 RANSAC 给出了非常好的结果。但毫无疑问,删除大纲是必须的!【参考方案3】:

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

【讨论】:

以上是关于OpenCV - 使用 SURF 描述符和 BruteForceMatcher 进行对象匹配的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV:从用户定义的关键点中提取 SURF 特征

opencv中SURF特征提取的最佳hessian阈值+最小描述符匹配

PyCharm:为 SIFT、SURF 等操作安装非免费 OpenCV 模块

OpenCV for Android - 使用 SURF 描述符训练 SVM

尝试从 OpenCV 使用 SURF 时出现 java.lang.UnsatisfiedLinkError

OpenCV 结合 SURF 和神经网络