3
import cv2
image1 = cv2.imread('one.jpg', 0)
image2 = cv2.imread('two.jpg', 0)
diff   = image1 - image2

For the above code, for some values, overflow due to subtraction is taking place. For eg:

238 - 254 = 240

What can I do to prevent this overflow and instead get -16 as the answer?

8
  • signed int iso unsigned byte as type? Commented Sep 8, 2015 at 5:37
  • right now unsigned int8. shall I make it signed? Commented Sep 8, 2015 at 5:39
  • yep, that is an unsigned byte. Commented Sep 8, 2015 at 5:39
  • How can I do that?some numpy function? Commented Sep 8, 2015 at 5:42
  • 4
    As long as the values are Python integers, there won't be any issue. If you are dealing with ctypes such as c_short or c_ushort, you will have issues. Python will also even automatically convert the integer to a long, or automatically use a long if the value exceeds the limit. docs.python.org/2.4/lib/typesnumeric.html In short, I doubt you are doing this in "pure Python". Maybe some code would help? Commented Sep 8, 2015 at 6:09

2 Answers 2

2

So here's the optimized answer after you have provided the cv2 module.

Your answer showed the issue:

>>> import cv2
>>> img = cv2.imread('myimage.jpg', 0)
>>> img.dtype
dtype('uint8')

This means, as you correctly stated, that it is an unsigned 8-bit integer, which can only take values from 0-255.

You can, however, automatically convert the array to a better dtype which is much more memory efficient than doing int(value). For example...

>>> img[0][0] 
0
>>> img[0][0] -= 1
>>> img[0][0]
255 # since it's uint8
>>> img[0][0] += 1
>>> img2 = img.astype('uint16')
>>> img2[0][0] -= 1
>>> img2[0][0]
65535 # since it's uint16

You an also convert to other types other than uint8, 16, 32, and 64. For example...

>>> img3 = img2.astype('int64') # signed int64
>>> img3[0][0] -= 7000000
>>> img3[0][0]
-6934465

In short, rather than using Python's built-in type conversion, you can manually specify the dtypes from uint8-64 and int8-64 (and maybe more) using NumPy's dtypes, by specifying the newarray = array.astype('type'), creating a compact and efficient array using the new dtype. You can also specificy other types, such as 'int', 'bool', 'object', etc., showing the versatility and utility of NumPy arrays.

To read more about the dtypes and how to use them, the link to the SciPy documentation is here.

Sign up to request clarification or add additional context in comments.

Comments

1

The datatype of the above numbers was unsigned int8, that can take values from 0 to 255.

238 - 254 = -16, and since uint8 doesn't have representation for negative numbers, it was giving 240 as the answer.

Instead, convert the numbers to int8 (-128 to 127) or int16 (-32768 to 32767).

5 Comments

Nancy please share the actual code you used to set this up including the libraries you are using. As @alexanderhuszag mentioned, it seems certain that you have abstracted your problem away from code. Future users of your library might miss the solution without the name and it probably wont work for users of other libraries. Also, if you are using numpy, converting your numbers to python ints is probably not an optimal solution.
@kobejohn I was using cv2 library. The cv2.imread() function takes values as uint8
Thanks for updating the question! It's much clearer now.
Converting to int8 still could result in over- or underflows as the maximum distance between two unsigned 8 bit values can be 255 (or -255).
@BlackJack Yes of course. In my problem,int8 served the purpose.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.