numpy uint8 pixel wrapping solution

后端 未结 3 1381
离开以前
离开以前 2020-12-23 20:45

For an image processing class, I am doing point operations on monochrome images. Pixels are uint8 [0,255].

numpy uint8 will wrap. For example, 235+30 = 9. I need th

相关标签:
3条回答
  • 2020-12-23 21:09

    Use numpy.clip:

    import numpy as np
    np.clip(data32, 0, 255, out=data32)
    data_u8 = data32.astype('uint8')
    

    Note that you can also brighten images without numpy this way:

    import ImageEnhance
    enhancer = ImageEnhance.Brightness(img)
    outimg = enhancer.enhance(1.2)
    outimg.save('out.png')
    
    0 讨论(0)
  • 2020-12-23 21:18

    Basically, it comes down to checking before you add. For instance, you could define a function like this:

    def clip_add(arr, amt):
        if amt > 0:
            cutoff = 255 - amt
            arr[arr > cutoff] = 255
            arr[arr <= cutoff] += amt
        else:
            cutoff = -amt
            arr[arr < cutoff] = 0
            arr[arr >= cutoff] += amt
    
    0 讨论(0)
  • 2020-12-23 21:26

    You can use OpenCV add or subtract functions (additional explanation here).

    >>> import numpy as np
    >>> import cv2
    >>> arr = np.array([100, 250, 255], dtype=np.uint8)
    >>> arr
    Out[1]: array([100, 250, 255], dtype=uint8)
    >>> cv2.add(arr, 10, arr)  # Inplace
    Out[2]: array([110, 255, 255], dtype=uint8)  # Saturated!
    >>> cv2.subtract(arr, 150, arr)
    Out[3]: array([  0, 105, 105], dtype=uint8)  # Truncated!
    

    Unfortunately it's impossible to use indexes for output array, so inplace calculations for each image channel may be performed in this, less efficient, way:

    arr[..., channel] = cv2.add(arr[..., channel], 40)
    
    0 讨论(0)
提交回复
热议问题