我对与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;
答案 0 :(得分:19)
问题在于仅使用Brute Force Matcher,我找到了在“OpenCV 2计算机视觉应用程序编程手册”
中获取两个视图之间的一组良好匹配的方法Ch9:使用随机样本共识匹配图像
他们正在使用K-Nearest Neighbor和RANSAC
谢谢
答案 1 :(得分:9)
对于去除异常值 RANSAC +单应性是比较两个平面图像的好方法。
Homography是RANSAC将尝试用来比较两个图像中的点的模型,它将找到更好地适合单应性投影模型(从一个平面到另一个平面的转换)的最佳点集。
cv::findHomography(srcPoints,dstPoints, RANSAC, status);
上面的函数将返回一个数组状态,对于被视为inliers的索引为1,对于被视为异常值的索引为0,因此您可以通过检查此状态数组来删除异常值。
答案 2 :(得分:4)
你需要修改你的Hessian,2500太多了。尝试50.当你使用一个大的Hessian时,结果是很多关键点,导致一些不必要的。关于SURF的另一个信息是你的标记需要更丰富,更详细。