我决定在 PIL 中编写自己的海报化函数,而不是使用提供的函数,以便我可以更好地理解它。
问题
有时,使用我的海报化功能时会出现意外的绿色像素,而使用内置海报化功能时则不会。
示例
第一张图片是我的海报化函数到4个级别的输入和输出。第二个是内置海报化函数的输入和输出。
特写
我的工作原理
我的海报化函数的工作原理是计算出阈值,使用 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
如何采用 lo
和 hi
参数,这些参数设置为 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/