Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between PIL.ImageChops.subtract and first converting to numpy arrays and then subtract those?

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.

like image 265
Leonhard Richter Avatar asked Oct 31 '25 22:10

Leonhard Richter


1 Answers

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.

like image 53
Ananda Avatar answered Nov 03 '25 13:11

Ananda