views:

35

answers:

2

I need to have a function like the one found here: http://effbot.org/zone/pil-comparing-images.htm that calculates the root mean square difference between two images. The code looks like this:

import ImageChops
import math, operator

def rmsdiff(im1, im2):
    "Calculate the root-mean-square difference between two images"

    h = ImageChops.difference(im1, im2).histogram()

    # calculate rms
    return math.sqrt(reduce(operator.add,
        map(lambda h, i: h*(i**2), h, range(256))
        ) / (float(im1.size[0]) * im1.size[1]))

Trying to run this code leads to the following error: TypeError: unsupported operand type(s) for ** or pow(): 'NoneType' and 'int'. That's the matter with it?

A: 

Wild guess here, but try this in your last line and see if it works:

return math.sqrt(sum(h*(i**2) for i, h in enumerate(h))) / (float(im1.size[0]) * im1.size[1]))

I'm not sure offhand why you'd get the TypeError you're describing, but if you use the above line of code and continue to get it, something seriously weird is going on.

David Zaslavsky
A: 

The problem is that it is creating a histogram that has no values (or really None values) where there is no corresponding pixel value.

i.e. when you are finding the diff of the two images, the resulting image doesn't have any pixels that are, say, 43 units apart, so h[43] = None.

Later, you try to access the number of pixels at each brightness in the range(256), and square it, which is causing it to get confused about what None**2 should be.

Consider changing range(256) to h.keys().

Also, you are using h to mean two different things, consider changing the name of one or, better still, both of them to meaningful names.

Oddthinking