【问题标题】:Different pixel values converting RGB to Greyscale using PIL使用 PIL 将 RGB 转换为灰度的不同像素值
【发布时间】:2020-09-02 00:12:43
【问题描述】:

我正在使用 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]])

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

【问题讨论】:

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


    【解决方案1】:

    您正在处理数组中的 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],
    

    【讨论】:

    • 谢谢。我没有意识到添加括号会有很大的不同。现在,如果我的数组一开始是 float64,它会减轻乘法的溢出问题吗?
    • 我认为这对图像数据没有帮助@StevenChen,因为您的值仍然分布在整个范围内,当您乘以一个很大的数字时,它仍然会溢出。也许如果您从 8 位数字开始并将它们放入 64 位数组中,但这对我来说似乎很难。
    猜你喜欢
    • 2018-08-15
    • 2015-07-11
    • 1970-01-01
    • 2014-02-26
    • 2014-12-22
    • 2017-06-17
    • 2013-10-25
    • 1970-01-01
    相关资源
    最近更新 更多