使用PIL将RGB转换为灰度的不同像素值

时间:2020-05-16 03:42:37

标签: python image-processing computer-vision python-imaging-library

我正在使用PIL库进行图像处理,并测试PIL将图像从RGB转换为L(灰度)的方式。

图片是Set5中的butterfly.png

enter image description here

我像这样使用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]])

为什么我得到不同的像素值?

1 个答案:

答案 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],