我正在参加一门图像处理课程,对灰度图像进行点操作。像素值是uint8类型的,取值范围为[0,255]。
使用numpy的uint8时,会发生数值溢出。例如,235+30=9。我需要将像素饱和到最大值255或截断到最小值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" )
输入图片:
输出图片:
.png
图像显示出了奇怪的方形伪影,而不是实际的手写数字。问题还在于dtypeint32
。在使用了接受的答案中的numpy.clip
和astype()
转换后,一切都正常了。 - JohnDizzle