Compare two images the python/linux way Compare two images the python/linux way linux linux

Compare two images the python/linux way


There is a OSS project that uses WebDriver to take screen shots and then compares the images to see if there are any issues (http://code.google.com/p/fighting-layout-bugs/)). It does it by openning the file into a stream and then comparing every bit.

You may be able to do something similar with PIL.

EDIT:

After more research I found

h1 = Image.open("image1").histogram()h2 = Image.open("image2").histogram()rms = math.sqrt(reduce(operator.add,    map(lambda a,b: (a-b)**2, h1, h2))/len(h1))

on http://snipplr.com/view/757/compare-two-pil-images-in-python/ and http://effbot.org/zone/pil-comparing-images.htm


From here

The quickest way to determine if two images have exactly the same contents is to get the difference between the two images, and then calculate the bounding box of the non-zero regions in this image.

If the images are identical, all pixels in the difference image are zero, and the bounding box function returns None.

from PIL import ImageChopsdef equal(im1, im2):    return ImageChops.difference(im1, im2).getbbox() is None


I guess you should decode the images and do a pixel by pixel comparison to see if they're reasonably similar.

With PIL and Numpy you can do it quite easily:

import Imageimport numpyimport sysdef main():    img1 = Image.open(sys.argv[1])    img2 = Image.open(sys.argv[2])    if img1.size != img2.size or img1.getbands() != img2.getbands():        return -1    s = 0    for band_index, band in enumerate(img1.getbands()):        m1 = numpy.array([p[band_index] for p in img1.getdata()]).reshape(*img1.size)        m2 = numpy.array([p[band_index] for p in img2.getdata()]).reshape(*img2.size)        s += numpy.sum(numpy.abs(m1-m2))    print sif __name__ == "__main__":    sys.exit(main())

This will give you a numeric value that should be very close to 0 if the images are quite the same.

Note that images that are shifted/rotated will be reported as very different, as the pixels won't match one by one.