Reputation: 435
I want to get the difference of pixel
values in two images.
out_img = cv2.imread(output_path)
tar_img = cv2.imread(target_path)
difference = out_img - tar_img
But I didn’t get a desirable result, so I checked how subtraction
worked, looking at a specific pixel
.
print out_img[0][0] #shows [254 254 254]
print tar_img[0][0] #shows [255 255 255]
print out_img[0][0] - tar_img[0][0] #this should show [-1 -1 -1], but shows [255 255 255]
What causes this?
Upvotes: 3
Views: 5838
Reputation: 20424
You need to convert the images
that you read in to a data
type
that supports negative numbers, such as unsigned int 8
(np.int8
). This can be done with .astype()
:
out_img = cv2.imread(output_path).astype(np.int8)
tar_img = cv2.imread(target_path).astype(np.int8)
difference = out_img - tar_img
The reason that you were getting the problem before, is that cv2.imread()
returns a numpy
array
with data
type
unsigned int 8
. So when you try and store a value in it a as -1
, this loops around to 255
.
We can demonstrate this with a simpler example:
>>> a
array([1, 2, 3, 4], dtype=uint8)
>>> a[0] = -1
>>> a
array([255, 2, 3, 4], dtype=uint8)
However, if we convert a
to the signed int datatype
(np.int8
), we can do this in the expected way:
>>> a
array([1, 2, 3, 4], dtype=uint8)
>>> a = a.astype(np.int8)
>>> a
array([1, 2, 3, 4], dtype=int8)
>>> a[0] = -1
>>> a
array([-1, 2, 3, 4], dtype=int8)
Hopefully this clears some things up for you!
Upvotes: 2
Reputation: 77857
The result is correct. Pixels are stored as 8-bit unsigned numbers; their range is 0-255. -1
is not a supported value in this type; the arithmetic wraps around to the top of the range again, losing the supposed sign bit to overflow.
You would have a similar effect with addition: 255 + 1 => 0
Upvotes: 0