使用PIL中的Image.point()方法来处理像素数据 [英] Using the Image.point() method in PIL to manipulate pixel data

查看:4733
本文介绍了使用PIL中的Image.point()方法来处理像素数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using the Python Imaging Library to colorize a black and white image with a lookup table that defines the color relationships. The lookup table is simply a 256-element list of RGB tuples:

>>> len(colors)
256
>>> colors[0]
(255, 237, 237)
>>> colors[127]
(50, 196, 33)
>>> 

我的第一个版本使用 getpixel() putpixel()方法:

My first version used the getpixel() and putpixel() methods:

    for x in range(w):
        for y in range(h):
            pix = img.getpixel((x,y))
            img.putpixel((x,y), colors[pix[0]])

这非常慢。 个人资料报告指向 putpixel getpixel 方法罪魁祸首。稍微调查(即阅读文档),我发现请注意,此方法相对较慢。re: putpixel 。 (实际运行时:53美元 putpixel 和50s getpixel 获取1024x1024图像)

This was horribly slow. A profile report pointed to the putpixel and getpixel methods as the culprits. A little investigation (i.e, read the docs) and I find "Note that this method is relatively slow." re: putpixel. (actual runtime: 53s in putpixel and 50s getpixel for a 1024x1024 image)

根据文档中的建议,我使用 im.load()并改为直接像素访问:

Based on the suggestion in the docs, I used im.load() and direct pixel access instead:

    pixels = img.load()
    for x in range(w):
        for y in range(h):
            pix = pixels[x, y]
            pixels[x, y] = colors[pix[0]]                

处理加速了一个数量级,但仍然慢:约3.5秒来处理1024x1024图像。

Processing sped up by an order of magnitude, but is still slow: about 3.5s to process a 1024x1024 image.

对PIL文档进行更全面的研究似乎表明 Image.point() 正好用于此目的:

A more thorough study of the PIL docs seems to indicate Image.point() is exactly intended for this purpose:


im.point(table) = > image

im.point(table) => image

im.point(function) => image

im.point(function) => image

返回图像的副本,其中每个像素已通过给定的表进行映射。该表应包含图像中每个波段256个值。如果使用函数,则应该使用单个参数。对每个可能的像素值调用该函数一次,结果表应用于图像的所有波段。

Returns a copy of the image where each pixel has been mapped through the given table. The table should contains 256 values per band in the image. If a function is used instead, it should take a single argument. The function is called once for each possible pixel value, and the resulting table is applied to all bands of the image.

我是花了一些时间来破解界面,但似乎不能正确。原谅我的无知,但PIL的文档很简单,我没有太多的图像处理经验。我已经google了一下,并举了几个例子,但没有任何让我使用点击的东西。最后,我的问题是:

I've spent some time hacking around with the interface, but can't quite seem to get it right. Forgive my ignorance, but PIL's docs are curt and I don't have much image processing experience. I've googled around a bit and turned up a few examples, but nothing that made the usage "click" for me. Thus, finally, my questions:


  • Image.point()右边这个工作的工具?

  • 什么格式/结构 Image.point()期望表?

  • 有人可以粗略地执行示例吗?到目前为止,我尝试过的每次迭代最终都会产生一个直的黑色图像。

  • Is Image.point() the right tool for this job?
  • What format/structure does Image.point() expect the table?
  • Can someone rough out an example implementation? Every iteration I've tried so far has ended up with a straight black image.

推荐答案


Image.point()是否适用于
这个职位?

Is Image.point() the right tool for this job?

是的, Image.point()非常适合这份工作

Yes indeed, Image.point() is perfect for this job



Image.point()期望表的格式/结构是什么?

What format/structure does Image.point() expect the table?

你应该扁平化列表而不是 [(12,140,​​10),(10,100,200), ...] 使用:

You should flatten the list so instead of [(12, 140, 10), (10, 100, 200), ...] use:

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

这是我刚试过的一个简单示例:

Here is a quick example I just tried:

im = im.point(range(256, 0, -1) * 3)


顺便说一下,如果你需要更多的颜色控制,你觉得Image.point不是对于你,你也可以使用 Image.getdata Image.putdata 加载 putpixel 更快地更改颜色。它比 Image.point 慢。

And by the way, if you need more control over colors and you feel Image.point is not for you you can also use Image.getdata and Image.putdata to change colors more quickly than both load and putpixel. It is slower than Image.point though.

Image.getdata 为您提供所有像素的列表,修改它们并使用 Image.putdata 将它们写回。就这么简单。但是首先尝试使用 Image.point

Image.getdata gives you the list of all pixels, modify them and write them back using Image.putdata. It is that simple. But try to do it using Image.point first.

编辑

我在第一个解释中犯了一个错误,我现在会正确解释:

I made a mistake in the first explanation, I'll explain correctly now:

颜色表实际上是这样的

[0, 1, 2, 3, 4, 5, ...255, 0, 1, 2, 3, ....255, 0, 1, 2, 3, ...255]

每个波段范围紧挨着另一波段。
要将颜色(0,0,0)更改为(10,100,10),需要将其更改为:

Each band range next to the other. To change the color (0, 0, 0) to (10, 100, 10) it need to become like this:

[10, 1, 2, 3, 4, 5, ...255, 100, 1, 2, 3, ....255, 10, 1, 2, 3, ...255]

要将颜色列表转换为正确的格式,请尝试以下方法:

To transform your color list into the right format try this:

table = sum(zip(*colors), ())

我想我的第一个例子应该为你演示合成。

I think my first example should demonstrate the formate for you.

这篇关于使用PIL中的Image.point()方法来处理像素数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆