python - PIL海报化-修复绿色像素

标签 python python-imaging-library

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

问题

有时,使用我的海报化功能时会出现意外的绿色像素,而使用内置海报化功能时则不会。

示例

mine theirs

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

特写

detail

我的工作原理

我的海报化函数的工作原理是计算出阈值,使用 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

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

最佳答案

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

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

这就是绿色像素的来源。

修复很简单 - 而不是这样做:

bisect_left(thresholds, color)-1

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

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

关于python - PIL海报化-修复绿色像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30690067/

相关文章:

python - 使用OIL自动旋转手机和加速度计拍摄的照片

python - 查找 numpy 数组中值的位置

python - PIL 和 py2exe 的问题

python - 使用 docker 开发时运行预提交 Hook (例如 pylint)

python - 如何重复该过程并将结果存储在新的数据框 pandas 中

python - Image.fromarray 只产生黑色图像

python - 是否可以使用 PIL 减少图像的深度?

python - MySQL 服务器已消失 ConnectionResetError 10054 Flask SqlAlchemy

python - 什么时候在 python 中使用 class 和 dict?

python - 在 Eclipse Pydev 中提交哪些内容到源代码控制