2013-03-04 65 views
6

我想創建一個C++程序,其中有一個列表中的圖像與一個輸入圖像相比有很多圖像。我得到了整個事情的工作,該計劃正在創建DMatch比賽。OpenCV:使用ORB比較多個圖像

現在我正在嘗試確定與源圖像比較的圖像列表中的哪一個是最匹配的。我首先試圖通過比較圖像之間的哪些匹配來做到這一點,但問題是當生成的圖像有很多關鍵點時;他們也往往有很多比賽,至少在我的計劃中。

那麼如何確定哪個圖像陣列與源圖像最匹配呢?我使用這個循環,以確定比賽,但它並沒有真正的工作:

vector< vector<DMatch> > filteredMatches; 
vector<int> goodIds; 
Ptr<DescriptorMatcher> matcher(new BFMatcher(NORM_HAMMING, false)); 

printf("bad matches: "); 

for(size_t i = 0; i < images.size();i++){ 
    vector<DMatch> matches, good_matches; 

    matcher->clear(); 
    matcher->match(images[i], tex_des, matches); 
    if(matches.size() < 8){ 
     printf("F%d,", (int)i + 1); 
     continue; 
    } 

    double min_dist = 100; 

    for(size_t j = 0; j < matches.size(); j++){ 
     double dist = matches[j].distance; 
     if(dist < min_dist) 
      min_dist = dist; 
    } 

    if(min_dist > 50.0){ 
     printf("D%d,", (int)i + 1); 
     continue; 
    } 

    double good_dist = min_dist * 3; 
    for(size_t j = 0; j < matches.size(); j++){ 
     if(matches[j].distance < good_dist) 
      good_matches.push_back(matches[j]); 
    } 

    size_t size = good_matches.size(); 
    if(size < 8){ 
     printf("M%d,", (int)i + 1); 
     continue; 
    } 

    vector<Point2f> srcPoints(size); 
    vector<Point2f> dstPoints(size); 

    for(size_t j = 0; j < size; j++){ 
     srcPoints[j] = destination[good_matches[j].trainIdx].pt;  
     dstPoints[j] = keyPoints[i][good_matches[j].queryIdx].pt; 
    } 

    vector<unsigned char> inliersMask(srcPoints.size()); 
    Mat H = findHomography(srcPoints, dstPoints, CV_FM_RANSAC, 3.0, inliersMask); 

    vector<DMatch> inliers; 
    for(size_t j = 0; j < inliersMask.size(); j++){ 
     if(inliersMask[j]){ 
      inliers.push_back(good_matches[j]); 
     } 
    } 
    if(inliers.size() < 4){ 
     printf("S%d,", (int)i + 1); 
     continue; 
    } 

    filteredMatches.push_back(inliers); 
    goodIds.push_back((int)i); 

    H.release(); 
} 

printf(" good matches: "); 

int best = -1; 
int amount = 0; 
for(size_t i = 0; i < filteredMatches.size(); i++){ 
    int size = (int)filteredMatches.at(i).size(); 
    if(size < 8) continue; 

    printf("%d,", goodIds[i] + 1); 

    if(amount < size){ 
     amount = size; 
     best = i; 
    } 
} 

if(best >= 0) printf(" best match on image: %d, keypoints: %d, ", goodIds[best] + 1, amount); 

如果有人能指點功能或邏輯我必須用我將不勝感激!

+0

說「與最內層的匹配是我最好的搭配」有什麼問題? – 2013-03-08 14:38:24

+0

這也是我想到的第一件事,但是當我嘗試它時,我沒有得到任何準確的結果。 – tversteeg 2013-03-08 14:40:17

+0

好的,所以圖片(甚至是假的)與我猜的很相似。如果您取所有比賽或所有比賽的平均距離,準確度如何?你可以發佈圖片失敗的例子嗎? – 2013-03-08 15:03:16

回答

0

您的問題很短的搜索提供我按照OpenCV的答案部分條目:

/CV Answer forum

這似乎答案提供給您的問題似乎是有。要按照答案中的建議篩選結果,我會看看RANSAC算法,以便在匹配選擇中找到最佳結果。

RANSAC desctiption Wikipedia

至少這應該指向你在正確的方向。

+0

如果你看看我的代碼,你可以看到我已經在使用RANSAC。 – tversteeg 2013-03-12 08:05:14

0

這取決於列表中的圖像是什麼。對於世界上的每一個視力問題,你都不能有一個解決方案。例如,我工作的項目需要識別牆上照片中的材料。你不能用不同的材料將它與不同的牆面圖片進行比較,並希望得到一個匹配。

在我的情況下,我需要創建描述符。 Descriptors是可以與其他圖片的其他值進行比較的輸出值的算法。 OpenCV中已經有很多描述符可用,如LBP,SURF等。簡而言之,您不再比較圖像,將圖像1的描述符的輸出值與所有圖像的描述符值進行比較圖像在列表中。

您需要拿起您的眼睛/大腦用於在現實生活中找到匹配的描述符。例如,如果匹配是基於顏色的,則可以使用CLD或DCD。如果匹配基於紋理,則使用LBP。您也可以像我在我的項目中那樣做,並使用大量描述符,並使用機器學習與訓練有素的數據算法來找到最佳匹配。

因此,總而言之,沒有銀彈可以解決所有視力問題。您需要根據問題調整解決方案。

希望它能幫助!

1

沒有任何直接的答案。爲了獲得更好的結果,你必須實現某種變換,並對變換後的地圖進行聚類,而不是僅僅總結距離。這很難,甚至publishable

否則,你將不得不使用更實用的技術,如尺寸和直方圖過濾。你可以看看OpenCV的stitcher,隔離你感興趣的模塊,並根據你的需要定製源代碼。