numpy uint8像素包装解决方案

Dav*_*ole 26 python numpy

对于图像处理类,我在单色图像上进行点操作.像素是uint8 [0,255].

numpy uint8将换行.例如,235 + 30 = 9.我需要像素饱和(max = 255)或截断(min = 0)而不是包裹.

我的解决方案使用int32像素作为点数学,然后转换为uint8以保存图像.

这是最好的方法吗?或者有更快的方法吗?

#!/usr/bin/python

import sys
import numpy as np
import Image

def to_uint8( data ) :
    # maximum pixel
    latch = np.zeros_like( data )
    latch[:] = 255
    # minimum pixel
    zeros = np.zeros_like( data )

    # unrolled to illustrate steps
    d = np.maximum( zeros, data )
    d = np.minimum( latch, d )

    # cast to uint8
    return np.asarray( d, dtype="uint8" )

infilename=sys.argv[1]
img = Image.open(infilename)
data32 = np.asarray( img, dtype="int32")
data32 += 30
data_u8 = to_uint8( data32 )
outimg = Image.fromarray( data_u8, "L" )
outimg.save( "out.png" )
Run Code Online (Sandbox Code Playgroud)

输入图片:
黎曼

输出图像:
产量

unu*_*tbu 34

使用numpy.clip:

import numpy as np
np.clip(data32, 0, 255, out=data32)
data_u8 = data32.astype('uint8')
Run Code Online (Sandbox Code Playgroud)

请注意,您也可以通过这种方式使图像变亮:

import ImageEnhance
enhancer = ImageEnhance.Brightness(img)
outimg = enhancer.enhance(1.2)
outimg.save('out.png')
Run Code Online (Sandbox Code Playgroud)


rad*_*oma 5

您可以使用OpenCV addsubtract函数(此处提供更多说明)。

>>> 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!
Run Code Online (Sandbox Code Playgroud)

不幸的是,不可能对输出数组使用索引,因此每个图像通道的就地计算可能会以这种效率较低的方式执行:

arr[..., channel] = cv2.add(arr[..., channel], 40)
Run Code Online (Sandbox Code Playgroud)