soshi shimada
soshi shimada

Reputation: 435

Subtraction of two images

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

Answers (2)

Joe Iddon
Joe Iddon

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

Prune
Prune

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

Related Questions