2011-09-04 162 views
17

我有一个关于与OpenCV匹配的对象的问题。 我使用opencv 2.3中实现的SURF算法首先检测每个图像的特征,然后提取这些特征的描述符。 在使用Brute Force Matcher进行匹配时出现问题,我不知道如何判断两个图像是否匹配,就像当我使用两个不同的图像时,两个图像中的描述符之间有线条!OpenCV - 使用SURF描述符和BruteForceMatcher对象匹配

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

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

真正匹配:

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; 

回答

17

的问题只用蛮力匹配器,我发现方法在获得一组两个视图之间的良好匹配“的OpenCV 2计算机视觉应用程序编程食谱”

Ch9的:采用随机抽样共识匹配图像

他们使用K-近邻和RANSAC

而且由于

+2

这本书变得非常有用! – 2012-10-02 00:58:29

+1

你应该接受你的答案。 –

8

,为了除去异常RANSAC +单应是一个很好的方法比较两个平面图像时。

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

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

该函数将返回具有用于索引视为离群值1为指数考虑和内围层0的阵列状态,这样就可以通过检查这个状态数组中删除异常值。

+1

使用'LMEDS'(Android上的'Calib3d.LMEDS')给了我更好的结果,我不知道为什么在我的课程项目中,Matlab中的RANSAC给出了非常好的结果。但明确地说,删除大纲是必须的! – Mustafa

3

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

相关问题