2016-01-13 109 views
15

我試圖使用OpenCV庫比較兩個圖像(確定它們是否相似)。我配置了java包裝器,並找到了一些我正在嘗試重寫入Java的教程(主要是C/C++)。我正在使用特徵檢測方法。在Java中使用OpenCV比較兩個圖像

的問題是,我現在有不產生任何合理的結果的算法(它聲稱,兩個類似的圖像沒有任何共同之處,並且是完全不同的另外兩個圖像之間找到匹配)。有人可能會建議我應該如何使用openCV匹配器來產生一些合理的結果?

這是我的形象比較

private static void compareImages(String path1, String path2) { 
    System.out.println(path1 + "-" + path2); 

    FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB); 
    DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB); 

    DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING); 

    // first image 
    Mat img1 = Imgcodecs.imread(path1, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE); 
    Mat descriptors1 = new Mat(); 
    MatOfKeyPoint keypoints1 = new MatOfKeyPoint(); 

    detector.detect(img1, keypoints1); 
    descriptor.compute(img1, keypoints1, descriptors1); 

    // second image 
    Mat img2 = Imgcodecs.imread(path2, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE); 
    Mat descriptors2 = new Mat(); 
    MatOfKeyPoint keypoints2 = new MatOfKeyPoint(); 

    detector.detect(img2, keypoints2); 
    descriptor.compute(img2, keypoints2, descriptors2); 

    // match these two keypoints sets 
    MatOfDMatch matches = new MatOfDMatch(); 
    matcher.match(descriptors1, descriptors2, matches); 

    for (DMatch m : matches.toArray()) { 
     // how to use these values to detect the similarity? They seem to be way off 
     // all of these values are in range 50-80 which seems wrong to me 
     System.out.println(m.distance); 
    } 
    } 

不幸的是,像SURF和SIFT算法不具備的Java包裝,所以我使用ORB代碼。我對計算機視覺幾乎沒有任何經驗,我只是試圖讓這個簡單的比較算法的工作產生一些合理的結果。我會很高興的任何幫助!

編輯:我的用例是針對從不同角度拍攝的圖像運行此算法。我更新了我的代碼以更好地格式化。

樣本圖像進行比較:

enter image description here enter image description here

+0

[可能是有用的(http://stackoverflow.com/questions/15544158/error-matching-with-orb-in- android) – GPPK

+0

鏈接中的算法似乎與我在這裏完全一樣...仍然產生非常差的結果。我只想加載兩個圖像併產生一些值,表明它們的相似性 – Smajl

+0

只是一個註釋:我試圖用'cv :: Stitcher'類內部使用'xfeatures2d :: SURF'來縫合兩個圖像,並且失敗。我認爲這意味着很難確定SURF的圖像的相似性 – sturkmen

回答

5

只是我的兩分錢:

  1. 有接觸到衝浪過篩在Java:openCV DescriptorExtractor Reference。我在三年前嘗試了FREAK實現,發現當openCV將它們傳遞給Java時,二進制描述符發生了一些變化。這可能是ORB受到同樣的問題。您是否將c或C++中描述符的數據與java端的描述符進行了比較?

  2. 蠻力匹配器從查詢圖像中的每個要素的列車圖像中找到最佳匹配特徵。即使它看起來完全不同。你必須篩選比賽並放棄壞的。有幾種策略,一個簡單的方法就是取最好的20%的比賽(但這不會降低所有比賽)。 Progressive Sample Consensus在我的設置中表現非常好。

  3. 使用功能來比較圖像相似性有缺陷。功能數量和質量因圖片大小和內容而異,這使得難以在全球範圍內比較圖像(如果您想知道兩幅圖像中的哪一幅與另一幅相比更接近參考)。您可以使用Calib3d.findHomography(obj, scene, CV_RANSAC);來估計從一幅圖像到另一幅圖像的變換,並使用重疊區域的歸一化像素差異。
+0

謝謝你的回答。至於SURF和SIFT - 它們列在可用算法的枚舉中,但如果嘗試使用它們,則會得到「不支持」的異常。我將不得不使用一些舊版本的OpenCV來訪問它們。如果您能夠提供一些比我的效果更好的示例Java代碼,我將非常高興,因爲評估我嘗試的圖像相似性的每種策略都會產生非常差的結果。在這一點上,我真的卡住了:/ – Smajl

0

正如this SO Question所述,最容易和最直接的方法是比較直方圖。如果您的算法只需要爲特定數據集工作,請嘗試使用不同的顏色通道來查看您的集合中的圖像共享最相似的位置。

直方圖方法可能看起來不切實際,但考慮到圖像的顏色相似性,我相信這可能有一定用處。

在Photoshop中你比較兩個圖像直方圖後:

histogram comparison