【问题标题】:Convert an images pixel value from rgb to grayscale manually python PIL?手动将图像像素值从 rgb 转换为灰度 python PIL?
【发布时间】:2015-07-11 09:53:50
【问题描述】:

我正在尝试使用 specific gamma corrected grayscale implementation - Gleam 将图像像素转换为灰度。如何使用 PIL python 手动执行此操作?

def tau_gamma_correct(pixel_channel):
    pixel_channel = pixel_channel**(1/2.2)
    return pixel_channel

#@param: rgb
#@result: returns grayscale value
def gleam(rgb):
    #convert rgb tuple to list
    rgblist = list(rgb)
    #gamma correct each rgb channel
    rgblist[0] = tau_gamma_correct(rgblist[0])
    rgblist[1] = tau_gamma_correct(rgblist[1])
    rgblist[2] = tau_gamma_correct(rgblist[2])
    grayscale = 1/3*(rgblist[0] + rgblist[1] + rgblist[2])
    return grayscale

# get a glob list of jpg filenames
files = glob.glob('*.jpg')
for file in files:
    file = open(file)
    filename = file.name
    image = Image.open(file)
    pix = image.load()
    width, height = image.size
    #print(width,height)
    for x in range(0, width):
        for y in range(0, height):
            rgb = pix[x,y]
            #print(rgb)
            # calc new pixel value and set to pixel
            image.mode = 'L'
            pix[x,y] = gleam(rgb)

            image.save(filename + 'gray.gleam'+'.jpg')
   file.close()

SystemError: new style getargs format but argument is not a tuple
它仍然期待我认为的 rgb 元组。

【问题讨论】:

  • 尝试将file.close() 2 缩进块向后移动,看​​看它解决了问题吗?我的意思是将file.close() 命令移动到与open() 方法相同的缩进级别。
  • 没有帮助,问题是我不确定如何将 rgb 元组更改为单个灰度值。我试图改变模式,但它似乎不起作用,或者它可能无法改变。我会检查 PIL 文档。
  • gleam 函数不是返回 0 到 255 之间的整数灰度值吗?你想要一个由函数返回的元组而不是整数吗?
  • 是的,这就是我的目标..
  • 我想将像素值设置为灰度值而不是 rgb 元组

标签: python python-imaging-library grayscale


【解决方案1】:

看到SystemError: new style getargs format but argument is not a tuple 错误似乎需要返回一个元组,表示为:

sample_tuple = (1, 2, 3, 4)

所以我们将gleam()函数编辑为:

def gleam(rgb):
    #convert rgb tuple to list
    rgblist = list(rgb)
    #gamma correct each rgb channel
    rgblist[0] = tau_gamma_correct(rgblist[0])
    rgblist[1] = tau_gamma_correct(rgblist[1])
    rgblist[2] = tau_gamma_correct(rgblist[2])
    grayscale = 1/3*(rgblist[0] + rgblist[1] + rgblist[2])
    return (grayscale, )

请记住,在返回单个元素元组时,您需要表示为:

sample_tuple = (1, )

这是因为(4) == 4(4, ) != 4

【讨论】:

    【解决方案2】:

    我发现我可以构建另一个图像:

    import sys
    import os
    import glob
    import numpy
    from PIL import Image
    
    def tau_gamma_correct(pixel_channel):
        pixel_channel = pixel_channel**(1/2.2)
        return pixel_channel
    
    #@param: rgb
    #@result: returns grayscale value
    def gleam(rgb):
        #convert rgb tuple to list
        rgblist = list(rgb)
        #gamma correct each rgb channel
        rgblist[0] = tau_gamma_correct(rgblist[0])
        print('gleamed red ' + str(rgblist[0]))
        rgblist[1] = tau_gamma_correct(rgblist[1])
        print('gleamed green ' + str(rgblist[1]))
        rgblist[2] = tau_gamma_correct(rgblist[2])
        print('gleamed blue ' + str(rgblist[0]))
        grayscale = (rgblist[0] + rgblist[1] + rgblist[2])/3
        print('grayscale '+ str(grayscale))
        return grayscale
    
    # get a glob list of jpg filenames
    files = glob.glob('*.jpg')
    for file in files:
        file = open(file)
        filename = file.name
        image = Image.open(file)
        pix = image.load()
        width, height = image.size
        new_image = Image.new('L', image.size)
        #pixelmatrix = [width][height]
        pixelmatrix = numpy.zeros((width, height))
        #print(width,height)
        for x in range(0, width):
            for y in range(0, height):
                rgb = pix[x,y]
                print('current pixel value: '+str(rgb))
                # calc new pixel value and set to pixel
                #print(gleam(rgb))
                gray = gleam(rgb)
                print('changing to pixel value: '+str(gray))
                pixelmatrix[x,y] = gray
                new_image.save(filename + 'gray.gleam'+'.jpg')
        new_image.putdata(pixelmatrix)
        file.close()
    

    【讨论】:

      【解决方案3】:

      问题是image.mode = 'L' 实际上并没有改变图像的类型,它只是改变了属性,所以它不再准确。要更改图像的模式,您需要使用image.convert('L') 制作新副本。

      一旦你有了灰度模式的图像,它就不再需要一个元组来表示像素值了。

      【讨论】:

      • 谢谢。 tho 似乎我需要处理每个像素,它 [对我来说足够好] 从头开始​​构建灰度。 IE。我不需要转换原件,我只需要灰度。将 numpy 数组/矩阵数据放入图像时遇到问题。
      • @jsky 你有两个对象,new_imagenew_img,你可能只是把它们弄糊涂了。
      猜你喜欢
      • 2018-08-15
      • 2011-12-03
      • 2020-09-02
      • 1970-01-01
      • 2014-02-26
      • 2014-12-22
      • 2021-04-02
      • 1970-01-01
      相关资源
      最近更新 更多