2011-12-19 17 views
13

Niedawno dostałem możliwość pracy z Technologiami przetwarzania obrazu w ramach jednego z moich projektów, a moim zadaniem było znalezienie pasujących obrazów ze sklepu z obrazami, gdy podano nowy obraz. Zacząłem swój projekt od wyszukiwarki Google "Jak porównać obrazy za pomocą java" i otrzymałem kilka dobrych artykułów na temat podobieństwa dwóch obrazów. Prawie wszystkie z nich opiera się na czterech podstawowych kroków, są to:Jak porównać obrazy podobieństwa za pomocą java

1.Locating the Region of Interest (Where the Objects appear in the given image), 
2.Re-sizing the ROIs in to a common size, 
3.Substracting ROIs, 
4.Calculating the Black and White Ratio of the resultant image after subtraction. 

Choć brzmi to jak dobry algorytm porównać obrazy, to zajmuje dużo czasu po wprowadzeniu go za pomocą JAI w moim projekcie. Dlatego muszę znaleźć alternatywną metodę robienia tego.

Wszelkie sugestie?

+0

czy pomyślałeś o użyciu OpenCV? http://stackoverflow.com/questions/2037579/java-opencv-bindings –

Odpowiedz

5

W zależności od tego, jak różne są obrazy, można zrobić coś takiego (pseudokod). Jest bardzo prymitywny, ale powinien być dość wydajny. Można go przyspieszyć, biorąc losowe lub wzorzyste piksele zamiast każdego.

for x = 0 to image.size: 
    for y = 0 to image.size: 
     diff += abs(image1.get(x,y).red - image2.get(x,y).red) 
     diff += abs(image1.get(x,y).blue - image2.get(x,y).blue) 
     diff += abs(image1.get(x,y).green - image2.get(x,y).green) 
    end 
end 

return ((float)(diff))/(x * y * 3) 
+0

Czy to naprawdę daje wystarczającą precyzję? – sum2000

+0

Nie sądzę, że to precyzja, której szukasz, ale dokładność. Na przykład, jeśli zrobisz zdjęcie i zrównoważysz je o 3 piksele w dół i w lewo, to pokaże, że obrazy są prawie takie same. Ale musisz zadać sobie pytanie, czyż nie? – corsiKa

+0

czy ta metoda działa na czarno-biały obraz? – manu

10
**// This API will compare two image file // 
// return true if both image files are equal else return false//** 
public static boolean compareImage(File fileA, File fileB) {   
    try { 
     // take buffer data from botm image files // 
     BufferedImage biA = ImageIO.read(fileA); 
     DataBuffer dbA = biA.getData().getDataBuffer(); 
     int sizeA = dbA.getSize();      
     BufferedImage biB = ImageIO.read(fileB); 
     DataBuffer dbB = biB.getData().getDataBuffer(); 
     int sizeB = dbB.getSize(); 
     // compare data-buffer objects // 
     if(sizeA == sizeB) { 
      for(int i=0; i<sizeA; i++) { 
       if(dbA.getElem(i) != dbB.getElem(i)) { 
        return false; 
       } 
      } 
      return true; 
     } 
     else { 
      return false; 
     } 
    } 
    catch (Exception e) { 
     System.out.println("Failed to compare image files ..."); 
     return false; 
    } 
} 
+0

To będzie porównanie, jeśli dwa obrazy są takie same, proszę o znalezienie podobieństwa między dwoma obrazami. – sum2000

+0

Chciałem tylko sprawdzić, czy dwa różne obrazy mają ten sam rozmiar, co zostanie zwrócone? – ChanGan

+0

Cześć Sandip, Jak przekazać dwa obrazy w miejscu dwa pliki A i plik B ... zarówno lokalizacja plików? Czy możesz dać mi trochę krótko? – ChanGan

3

Ten interfejs API będzie porównać dwa pliki obrazów i powrócić procent podobieństwa

public float compareImage(File fileA, File fileB) { 

    float percentage = 0; 
    try { 
     // take buffer data from both image files // 
     BufferedImage biA = ImageIO.read(fileA); 
     DataBuffer dbA = biA.getData().getDataBuffer(); 
     int sizeA = dbA.getSize(); 
     BufferedImage biB = ImageIO.read(fileB); 
     DataBuffer dbB = biB.getData().getDataBuffer(); 
     int sizeB = dbB.getSize(); 
     int count = 0; 
     // compare data-buffer objects // 
     if (sizeA == sizeB) { 

      for (int i = 0; i < sizeA; i++) { 

       if (dbA.getElem(i) == dbB.getElem(i)) { 
        count = count + 1; 
       } 

      } 
      percentage = (count * 100)/sizeA; 
     } else { 
      System.out.println("Both the images are not of same size"); 
     } 

    } catch (Exception e) { 
     System.out.println("Failed to compare image files ..."); 
    } 
    return percentage; 
} 
+0

Proszę znaleźć nazwę metody z parametrami u góry pierwszej linii kodu, tam możemy przekazać dwa obrazy ze ścieżką pliku (np. C: //Documents//image1.jpg) –

+2

Należy wspomnieć, że jest to oparte na kodzie z Sandip Odpowiedź Ganguli. –

Powiązane problemy