So I want to subtract Image2 from Image1 using Pillow. I first tried to do this by converting them to numpy arrays, subtract those and then converting the arrays back to Images. But this gave me very strange behavior s.t. large parts of the difference picture became white.
I found that i can do the same thing directly using PIL.IamgeChops.subtract which works fine, but I would like to understand why the array way does not work.
Here ist my Code:
import os.path
from PIL import Image, ImageShow, ImageChops
root = os.path.abspath(os.path.curdir)
Image1 = Image.open(
    root + "\\Messwerte\\Messungen_20_11\\AOM_Copy\\1.bmp"
).convert("L")
Image2 = Image.open(
    root + "\\Messwerte\\Messungen_20_11\\B Feld Abh\\hintergrund_B_3.bmp"
).convert("L")
DiffImage = ImageChops.subtract(Image1, Image2)  #this way works perfectly
DiffImage.show()
DiffImageArray = np.array(DiffImage)
arr1 = np.array(Image1)
arr2 = np.array(Image2)
diff = arr1 - arr2   #this doesn't work
Image.fromarray(diff).show()
print(np.max(DiffImageArray)) #this gives me 77
print(np.max(diff))  # and this 255
I also checked that the error does not lie in the converting from array to Image object.
It's because the the type of the image in unit8 and when you do the subtraction, any negative values get circled back up-to 255 because the data-format cannot handle negative integers. That is, 7-8 would be stored as 255 as opposed to -1, 7-9 would be 254 as opposed to -2 and so on. You would need bigger sized data-type and you would also need to take the absolute value of the result of subtraction (or clip negative values to zero depending on use-case) as opposed to just a simple subtraction.
You can solve this by simply doing
arr1 = np.array(Image1).astype(np.int32)
arr2 = np.array(Image2).astype(np.int32)
diff = np.abs(arr1 - arr2)
when you create the arrays.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With