comparing 2 images

Skip Montanaro skip at pobox.com
Thu May 15 10:09:06 EDT 2003


    Joe> I would like to take 2 images (scanned) and compare them to see if
    Joe> they are similar. An example (but not limited to), would be 2
    Joe> signatures.

You mean, like this?  (Yes, this uses PIL.)

    import Image, ImageChops

    def rmsdiff(im1, im2):
        "Calculate the rms difference between two images"

        h = ImageChops.difference(im1, im2).histogram()
        return wfop.rmsdiff_helper(h, im1.size[0], im1.size[1])

    def geterror(im1, im2):
        """Calculate an error term for a color image - average of
        rms diff of the red, green and blue channels
        """

        if im1.mode != "RGB": im1 = im1.convert("RGB")
        if im2.mode != "RGB": im2 = im2.convert("RGB")
        ssplit = im1.split()
        osplit = im2.split()

        errvec = map(rmsdiff, ssplit, osplit)
        return (errvec[0]+errvec[1]+errvec[2])/3

where wfop.rmsdiff_helper is written in C and looks like

    static PyObject *
    wfop_rmsdiff_helper(self, args)
            PyObject *self; /* Not used */
            PyObject *args;
    {

        PyListObject *hist;
        long w, h;
        float sum, rslt;
        int i, j, nchannels;

        if (!PyArg_ParseTuple(args, "Oll", (PyObject **)&hist, &w, &h) ||
            !PyList_Check(hist))
            return NULL;

        nchannels = PyObject_Length((PyObject *)hist)/256;
        rslt = 0.0;
        for (j = 0; j < nchannels; j++) {
            sum = 0.0;
            for (i = 0; i < 256; i++) {
                sum += i*i*
                    PyInt_AS_LONG((PyIntObject*)PyList_GET_ITEM(hist, i+j*256));
            }
            rslt += sqrt(sum/(w*h));
        }
        return PyFloat_FromDouble(rslt/nchannels);

    }

I think you could easily rewrite it using Numeric in fewer lines and get the
same speed out of it. 

Note: This is very old code which I no longer use.  PIL's API may have
changed a bit since then and there are probably easier ways to do this now,
but this at least suggests the solution is possible with PIL.

Skip





More information about the Python-list mailing list