Python Pillow: how to overlay one binary image on top of another to produce a composite?

Question:

I am doing some image processing, and I need to check if a binary image is identical to another.

Processing speed isn’t an issue, and the simple thing I thought to do was count the white pixels remaining after adding the inverse of image A to image B (these images are very nearly identical, but not quite–some sort of distance metric is the goal).

  • Note: take the logarithm to linearize the distance

However, in order to create the composite image, I need to include a "mask" that is the same size as the two images.

I am having trouble finding an example of creating the mask online and using it for the Image.composite function.

Here is my code:

compA = ImageOps.invert(imgA)
imgAB = Image.composite(compA,imgB,??? mask)

Right now, I have created a mask of all zeros–however, the composite image does not appear correctly (both A and B are exactly the same images; a mask of all zeros–or all ones for that matter–does not work).

mask = Image.fromarray(np.zeros(imgA.size,dtype=int),mode='L')
imgAB = Image.composite(compA,imgB,mask)

How do I just add these two binary images on top of eachother?

Asked By: Chris

||

Answers:

Clearly you’re using numpy, so why not just work with numpy arrays and explicitly do whatever arithmetic you want to do in that domain—such as subtracting one image from the other:

arrayA = numpy.asarray( imgA, dtype=int )
arrayB = numpy.asarray( imgB, dtype=int )

arrayDelta = arrayA - arrayB

print( (arrayDelta !=0 ).sum() )  # print the number of non-identical pixels (why count them by hand?)
# NB: this number may be inflated by a factor of 3 if there are 3 identical channels R, G, B

imgDelta = Image.fromarray((numpy.sign(arrayDelta)*127+127).astype('uint8'))  # display this image if you want to visualize where the differences are

You could do this even more simply, e.g.

print((numpy.asarray(imgA) != numpy.asarray(imgB)).sum())

but I thought casting to a signed integer type first and then subtracting would allow you to visualize more information (A white and B black -> white pixel in delta; A black and B white -> black pixel in delta)

Answered By: jez