PIL posterize-修复绿色像素

时间:2015-06-07 04:30:10

标签: python python-imaging-library

我决定在PIL中编写自己的posterize函数,而不是使用提供的函数,以便我能够理解它。

问题

有时,使用我的posterize函数时会出现意外的绿色像素,而使用内置的posterize函数则不会。

实施例

mine theirs

第一张图片是我的posterize函数的输入和输出到4级。第二个是内置posterize函数的输入和输出。

特写

detail

我的工作方式

我的posterize函数通过计算阈值来工作,使用bisect_left将RGB元组的每个元素放入一个槽中,并重新分配阈值,就像这样。

def posterize(im, levels):

    #Figure out thresholds for the pixel colors
    increment = 255//levels
    thresholds = range(1, 256, increment)

    im = copy.copy(im)
    img = im.load()
    #Iterate through the image
    for y in range(im.size[1]):
        for x in range(im.size[0]):

            #Get a new RGB tuple based on thresholds
            new = []
            for c in range(3):
                color = img[x, y][c]
                level = bisect_left(thresholds, color)-1
                new.append(thresholds[level])

            #Put the new pixel on the image
            img[x, y] = tuple(new)

    #Return the image
    return im

无论如何,有人可以解释为什么这会返回绿色像素,以及如何解决它?如果可能的话,我希望仍然使用类似于我的方法,如果可能的话。提前谢谢。

1 个答案:

答案 0 :(得分:2)

你几乎正确使用bisect_left ......几乎。

如果您阅读文档,则会注意到bisectlohi个参数的方式,这些参数分别设置为0len(arr)。要解决IndexError,请在结果中添加-1。但是,这会将0的结果映射到len-1,因为Python中的索引arr[-1]与索引arr[len(arr)-1]相同。事实上,如果仔细观察 - 绿色像素应将其绿色通道设置为0,但由于-1环绕,它们会得到255.

这是绿色像素的来源。

修复很简单 - 而不是:

bisect_left(thresholds, color)-1

DO

bisect_left(thresholds, color, lo=0, hi=len(thresholds)-1)

就是这样。同时,你会注意到图片的亮度设置也是正确的,因为-1因为它们应该比它们更暗。

相关问题