2011-09-04 164 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的另一個信息是,您的標記需要更豐富,並有更多細節。

相關問題