我正在使用Python Imaging Library通过定义颜色关系的查找表为黑白图像着色。查找表只是RGB元组的256个元素的列表:

>>> len(colors)
256
>>> colors[0]
(255, 237, 237)
>>> colors[127]
(50, 196, 33)
>>>
我的第一个版本使用了getpixel()putpixel()方法:
    for x in range(w):
        for y in range(h):
            pix = img.getpixel((x,y))
            img.putpixel((x,y), colors[pix[0]])
这太慢了。 profile报告指出putpixelgetpixel方法是罪魁祸首。稍作调查(即阅读文档),我发现“请注意,此方法相对较慢。”回复:putpixel。 (实际运行时:对于1024x1024图像,putpixel中为53s,getpixel中为50s)
根据文档中的建议,我改用im.load()和直接像素访问:
    pixels = img.load()
    for x in range(w):
        for y in range(h):
            pix = pixels[x, y]
            pixels[x, y] = colors[pix[0]]
处理速度加快了一个数量级,但是仍然很慢:处理1024x1024图像大约需要3.5秒。
对PIL文档的更深入研究似乎表明Image.point()正是用于此目的的:

我花了一些时间在界面上乱搞,但似乎不太正确。原谅我的无知,但是PIL的文档简直就是草率,我没有太多图像处理经验。我在谷歌上搜索了一些示例,但是没有什么让我感到“点击”。因此,最后,我的问题是:
  • Image.point()是此工作的正确工具吗?
  • Image.point()期望表格采用什么格式/结构?
  • 有人可以粗略示例实现吗?到目前为止,我尝试过的每个迭代都以纯黑色图像结束。
  • 最佳答案



    是的,的确,Image.point()非常适合此工作



    您应该使列表变平,所以不要使用[(12, 140, 10), (10, 100, 200), ...]:

    [12, 140, 10, 10, 100, 200, ...]
    

    这是我刚刚尝试的一个简单示例:
    im = im.point(range(256, 0, -1) * 3)
    


    顺便说一句,如果您需要更好地控制颜色,并且觉得Image.point不适合您,则还可以使用Image.getdataImage.putdata来比loadputpixel更快地更改颜色。它比Image.point慢。
    Image.getdata提供所有像素的列表,对其进行修改并使用Image.putdata写回。就这么简单。但是,请先尝试使用Image.point进行操作。

    编辑

    我在第一个解释中弄错了,现在我将正确地解释:

    颜色表实际上是这样的
    [0, 1, 2, 3, 4, 5, ...255, 0, 1, 2, 3, ....255, 0, 1, 2, 3, ...255]
    

    每个频段范围彼此相邻。
    要将颜色(0,0,0)更改为(10,100,10),它需要变成这样:
    [10, 1, 2, 3, 4, 5, ...255, 100, 1, 2, 3, ....255, 10, 1, 2, 3, ...255]
    

    要将颜色列表转换为正确的格式,请尝试以下操作:
    table = sum(zip(*colors), ())
    

    我认为我的第一个例子应该为您展示好运。

    09-10 08:49
    查看更多