自定义图像XOR计算函数解析及与Pillow内置logical_xor的差异咨询
Hey there! Let's break down this custom "XOR" function step by step, then compare it to Pillow's built-in ImageChops.logical_xor to clear up the differences.
Custom get_xor Function Execution Logic
First, let's look at the code again:
from PIL import Image, ImageChops def get_xor(image_1, image_2): i1 = ImageChops.invert(image_1) i2 = ImageChops.invert(image_2) return ImageChops.invert(ImageChops.add(ImageChops.subtract(i2, i1), ImageChops.subtract(i1, i2)))
Let's unpack each operation (we'll use 8-bit grayscale pixels as an example—RGB channels work the same way per-channel):
- Invert both input images:
ImageChops.invert()takes each pixel valuevand converts it to255 - v. Soi1is the inverse ofimage_1,i2is the inverse ofimage_2.
- Two saturated subtraction operations:
ImageChops.subtract(i2, i1)calculatesi2 - i1, but uses saturated arithmetic: if the result is negative, it clamps to 0. This simplifies tomax(a - b, 0)(whereais a pixel fromimage_1,bfromimage_2).ImageChops.subtract(i1, i2)does the reverse:max(b - a, 0).
- Add the two subtraction results:
- Adding these two values gives us
max(a - b, 0) + max(b - a, 0) = |a - b|(the absolute difference between the original pixel values). This also uses saturated addition (clamps to 255 if the sum exceeds the maximum pixel value).
- Adding these two values gives us
- Invert the final sum:
- The final invert converts
|a - b|to255 - |a - b|.
- The final invert converts
What does this actually compute?
For binary images (pixels are only 0 or 255), this results in the XNOR (not XOR) operation:
- If
aandbare the same (0&0 or 255&255), the result is 255 (bright) - If
aandbare different (0&255), the result is 0 (dark)
For grayscale images, it's a continuous version of this: pixels that are very similar have bright values, while pixels with large differences have dark values. This is not a true bitwise XOR—it's an arithmetic operation focused on pixel value similarity.
Differences from Pillow's ImageChops.logical_xor
The built-in logical_xor is a strict bitwise operation, and it behaves very differently from the custom function:
- Core operation:
logical_xor: Compares each binary bit of the two pixel values. For each bit, if the bits are different, it sets the result bit to 1; if they're the same, it sets it to 0. The final pixel value is the combination of these bits.- Custom
get_xor: Uses arithmetic operations (invert, subtract, add) to compute the inverted absolute difference of pixel values—no bitwise comparison involved.
- Visual effect:
logical_xor: Highlights differences between pixels. The more bits that differ between two pixel values, the brighter the result. For binary images, this gives true XOR (same pixels = dark, different = bright).- Custom
get_xor: Highlights similarities. The closer two pixel values are, the brighter the result; larger differences result in darker pixels.
- Use cases:
logical_xor: Ideal for tasks requiring strict logical bitwise operations, like creating image masks, detecting exact bit-level differences, or working with binary image logic.- Custom
get_xor: Useful for visualizing pixel similarity (e.g., in image matching or alignment tasks where you want to emphasize regions that match).
内容的提问来源于stack exchange,提问作者Amanda

