PIL posterize- 修复绿色像素

PIL posterize- fix green pixels

我决定在 PIL 中编写自己的 posterize 函数,而不是使用提供的函数,这样我可以更好地理解它。

问题

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

例子

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

特写

我的工作原理

我的 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

无论如何,有人可以解释为什么这个 returns 绿色像素,以及如何修复它吗?如果可能的话,我想仍然使用类似于我的方法,如果可能的话。提前致谢。

您几乎正确地使用了bisect_left……几乎。

如果您阅读文档,您会注意到 bisect 如何采用 lohi 参数,这些参数设置为 0len(arr)分别。要解决 IndexError,您将 -1 添加到结果中。但这会将应为 0 的结果映射到 len-1,因为在 Python 中索引 arr[-1] 与索引 arr[len(arr)-1] 相同。事实上,如果你仔细观察 - 绿色像素应该将它们的绿色通道设置为 0,但由于 -1 环绕,它们会变成 255。

那是你绿色像素的来源。

修复很简单 - 而不是做:

bisect_left(thresholds, color)-1

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

仅此而已。同时,您会注意到图片的亮度设置也很正确,因为 -1 因为 -1 比应有的暗。