18

Recently I got an opportunity to work with Image Processing Technologies as a part of one of my projects and my task was to find matching images from an image store when a new image is given. I started my project with googling "How to compare images using java" and I got some good articles on finding the similarity of two images. Almost all of them were based on four basic steps, they are:

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.

Though this sounds as a good algorithm to compare images, it takes a considerable amount of time after implementing it using JAI in my project. Therefore I have to find an alternate method of doing it.

Any suggestions?

sum2000
  • 1,363
  • 5
  • 21
  • 36

4 Answers4

12
    **// 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;
    }
}
Sandip Ganguli
  • 137
  • 1
  • 2
  • 3
    This will compare if the two images are same, i am asking to find the similarity between two images. – sum2000 Jun 22 '12 at 07:24
  • Just wanted to check, if two different images meets same size, what will be returned? – ChanGan Jan 18 '13 at 11:31
  • Hi Sandip, How to pass two pass two images in place fileA and fileB... both are the location of files? Can you please give me bit brief. – ChanGan Jan 18 '13 at 12:10
8

Depending on how different the images are, you could do something like this (pseudocode). It's very primitive, but should be pretty efficient. You could speed it up by taking random or patterned pixels instead of every one.

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)
corsiKa
  • 81,495
  • 25
  • 153
  • 204
  • does this really give enough precision?? – sum2000 Dec 19 '11 at 21:45
  • 3
    Well I don't think it's precision you're looking for, but accuracy. For example, if you take an image and offset it by 3 pixels down and left, this will show that the images are almost nothing alike. But then you have to ask yourself, should it? – corsiKa Dec 19 '11 at 21:50
  • However well it works (which may or may not be good at all depending on if you do every pixel or groups of pixels or whatever) it will work just as well for black and white images. – corsiKa May 08 '14 at 13:19
6

This API will compare two image file and return the percentage of similarity

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;
}
Dev
  • 2,326
  • 24
  • 45
Sireesha K
  • 95
  • 1
  • 4
-1
    BufferedImage img1 = ImageIO.read(file);
    BufferedImage img2 = ImageIO.read(file2);

    // Comprueba si cada pixel es igual
    for (int x = 0; x < img1.getWidth(); x++) {
        for (int y = 0; y < img1.getHeight(); y++) {
            Assert.assertEquals(img1.getRGB(x, y), img2.getRGB(x, y));
        }
    }
Carlos Noé
  • 103
  • 3
  • 11
  • that is even worse than the previous two answers that calculate per-pixel equality or difference because you just threw an `assertEquals` in there. there is no reason for this answer to exist. – Christoph Rackwitz Aug 04 '23 at 09:53