One bug to look out for performing both methods on the same data
object. However, I've tried your methods on my own images, and the results were incorrect.
You can fix the behavior in method two by rephrasing the calculation to 255 - data[:,:,:3]
. This solution assumes that your images have a max values of (255, 255, 255) for (R,G,B).
# old method
data[:,:,:3] = np.abs(data[:,:,:3] - 255)
# new method
data[:,:,:3] = 255 - data[:,:,:3]
You can verify this method by running the code
img = Image.open(path)
data = np.asarray(img, dtype='uint8' )
experiment_1 = np.copy(data)
experiment_2 = np.copy(data)
# Perform method 1 on experiment_1
# ...
# Perform method 2 on experiment_2
# ...
print(np.all(experiment_1 == experiment_2))
If you want to understand why the code is behaving this way, it's because your code data_origin
array is datatype np.uint8
. uint8
is an unsigned integer with 8 bits meaning it can only be values from [0,255]. Subtracting a uint8 by 255 doesn't result in a negative number, but an overflow of x - 255.
For example,
a = np.array([10, 100, 125, 250], dtype='uint8')
print(a - 255) # incorrect
>> array([ 11, 101, 126, 251], dtype=uint8)
print(255 - a) # correct
>> array([245, 155, 130, 5], dtype=uint8)
Even though np.abs(data[:,:,:3] - 255)
should behave like 255 - data[:,:,:3]
(because f(x) = abs(x-255)
equals f(x) = 255 -x
for domain in range [0, 255]), the datatype makes this conversion incorrect.
Another fix to this code would be to replace dtype='uint8'
to dtype='int32'
(because int32 allows for negative values). However, I don't recommend this solution because int32 is much larger than uint8.