0

I'm trying to add a scalar value at certain indices in a numpy array, which is of type numpy.uint8. Is there a way for me to make sure the addition clips at a certain maximum, so that the sum doesn't overflow? Here's how achieve it with a for loop, but it is slow and inefficient. Is there a way to use np.add.at or another function to do this faster?

change_by = 80
indices = [(0,0), (100, 100), (23, 45)]

for idx in indices:
    output_image[idx[0], idx[1]] = min(255, image[idx[0], idx[1]] + change_by)

This limits the max value for each element to be 255. Is there a more efficient way to achieve this? Thanks!

  • This works - https://stackoverflow.com/questions/37822375/python-opencv-increasing-image-brightness-without-overflowing-uint8-array? – Divakar Nov 11 '20 at 18:34

1 Answers1

1

Try np.clip() Something like

import numpy as np
array = np.array([-10,0,1,2,100,200,300])
min = 0
max = 255
np.clip(array, min, max)

https://numpy.org/doc/stable/reference/generated/numpy.clip.html

If you need to work with uint8 and add before clip:

>>> import numpy as np
>>> a = np.array(range(10),dtype=np.uint8)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=uint8)
>>> np.array(a+250,dtype=np.uint8)
array([250, 251, 252, 253, 254, 255,   0,   1,   2,   3], dtype=uint8)

Is this the type of problem you're seeing? Try this maybe:

>>> np.array(np.clip(a.astype(np.int)+250,0,255),dtype=np.uint8)
array([250, 251, 252, 253, 254, 255, 255, 255, 255, 255], dtype=uint8)
poleguy
  • 523
  • 7
  • 11
  • Thanks, but the issue is that my datatype is `uint8` and after using `np.add.at`, the sum has already overflowed past 255. So I cannot clip after the fact. Can I do the clipping in the addition itself, like I do it in the loop? I updated the question with this detail – deepaktalwardt Nov 11 '20 at 18:18
  • @deepaktalwardt does my updated example solve the problem? If so I'd appreciate marking it accepted as I'm trying to build my reputation. – poleguy Nov 16 '20 at 17:42