I try to overlay two images but the result is not what I want. imag1 is a dermocopy image occluded with hair. image a hair-free image. I substract them to get the hair. When i try to reverse the operation by summimg imag1 and image 2, the result is different. the hair looks white while it is black.
from PIL import Image, ImageChops
# Load the images
image1 = Image.open('C:/Users/asus/Desktop/Testing/hairoccluded/ISIC_0024327.jpg')
image2 = Image.open('C:/Users/asus/Desktop/Testing/hairfree/ISIC_0024327.jpg')
# Subtract image2 from image1
subtracted_image = ImageChops.subtract(image2, image1)
# Reverse the subtraction using ImageChops.add
reversed_image = ImageChops.add(image2, subtracted_image)
# Display the reversed image
reversed_image.show()
[[[enter image description here](https://ienter image description herestack.imgur.com/bzo4m.jpg)](https://i.sstatic.net/n0XAO.jpg)](https://i.sstatic.net/akeor.jpg)
THe opeation image.add should be reversed correctly
There are two issues:
subtracted_image = ImageChops.subtract(image2, image1)
==> subtracted_image = image2 - image1
reversed_image = ImageChops.add(image2, subtracted_image)
==> reversed_image = image2 + subtracted_image
==> reversed_image = image2 + (image2 - image1)
==> reversed_image = image2*2 - image1
As you can see the math is wrong.
The correct statement is:
reversed_image = ImageChops.add(image1, subtracted_image)
==> reversed_image = image1 + (image2 - image1)
==> reversed_image = image2
ImageChops.subtract
and ImageChops.add
are not reversible operations.uint8
, and can't have negative values (and can't have values above 255).ImageChops.subtract
, all negative values are clipped to zero.ImageChops.add
, all values above 255 are clipped to 255.There is a nice explanation in the following post.
We may use ImageChops.subtract_modulo and ImageChops.add_modulo, which are reversible.
The math is not intuitive, but it's working:
from PIL import Image, ImageChops
# Load the images
image1 = Image.open('image1.jpg')
image2 = Image.open('image2.jpg')
# Subtract image2 from image1
subtracted_image = ImageChops.subtract_modulo(image1, image2) # image1 - image2
reversed_image = ImageChops.add_modulo(image2, subtracted_image) # image2 + (image1 - image2)
# Display the reversed image
reversed_image.show()
More intuitive solution is converting the images to NumPy arrays with type dtype np.int32
or np.int16
.
Then subtract and add the NumPy arrays.
The advantage is that np.int32
or np.int16
types may hold positive and negative values, and have a larger range that avoids arithmetic overflow.