我正在使用PIL库进行图像处理,并测试PIL将图像从RGB转换为L(灰度)的方式。
图片是Set5中的butterfly.png
我像这样使用Pillow加载图像:
from PIL import image
im = Image('butterfly.png')
然后将其转换为灰度:
grayscale = im.convert('L')
print(grayscale)
array([[ 32, 45, 68, ..., 63, 60, 60],
[ 27, 32, 40, ..., 60, 61, 60],
[ 65, 35, 28, ..., 62, 63, 58],
...,
[ 46, 49, 53, ..., 112, 114, 111],
[ 46, 49, 66, ..., 115, 113, 114],
[ 49, 53, 65, ..., 115, 113, 113]], dtype=uint8)
要测试PIL使用的公式,请参阅文档:
当将彩色图像转换为灰度(模式“ L”)时,该库使用ITU-R 601-2亮度转换:
L = R * 299/1000 + G * 587/1000 + B * 114/1000
所以我编写了自己的自定义函数:
def pil_rgb_to_gray(im):
R = np.array(im.getchannel('R'))
G = np.array(im.getchannel('G'))
B = np.array(im.getchannel('B'))
L = R * 299/1000 + G * 587/1000 + B * 114/1000
return L
它返回不同的结果:
grayscale2 = pil_rgb_to_gray(im)
print(grayscale2)
array([[ 30.372, 42.731, 64.337, ..., 57.696, 55.208, 55.208],
[ 25.848, 31.278, 38.57 , ..., 55.18 , 56.038, 55.18 ],
[ 60.438, 34.392, 27.321, ..., 56.326, 57.799, 52.724],
...,
[ 44.153, 46.429, 50.457, ..., 104.68 , 105.712, 103.071],
[ 43.463, 46.647, 62.079, ..., 107.327, 104.968, 105.701],
[ 46.397, 50.435, 60.725, ..., 107.327, 104.968, 104.957]])
为什么我得到不同的像素值?
答案 0 :(得分:3)
您正在处理数组中的uint8数字,这意味着它们可能会溢出。这可能导致违反直觉的结果,因为操作顺序很重要,而您可能不会想到。例如,两者之间是有区别的:
>> # multplity (and overflow) then divide
>> np.array([200], dtype=np.uint8) * 587/1000
array([51.864])
和
>> # multiply by small number (and don't overflow)
>> np.array([200], dtype=np.uint8) * (587/1000) # note parenthesis
array([117.4])
如果将分数包裹在()
中,则应获得更好的结果。
L = (R * (299/1000) + G * (587/1000) + B * (114/1000)).astype(np.uint8)
# ...
array([[ 32, 45, 68, ..., 63, 60, 60],
[ 27, 32, 40, ..., 60, 61, 60],
[ 65, 35, 28, ..., 62, 63, 58],