从PIL图像获取32位RGBA numpy数组
假设我加载了一张图片,代码是:
> image = Image.open('temp.png')
<PngImagePlugin.PngImageFile image mode=RGBA size=1200x600 at 0x112F0C488>
注意,这张图片的尺寸是 1200x600
。
我想把这张图片转成一个二维的 numpy 数组,每个元素存放一个32位的整数。
如果我这样做:
np.array(image).shape
我得到的是:
(600,1200, 4)
我该如何把它转换成一个 32 位的 RGBA 二维 numpy 数组呢?
1 个回答
5
1. 索引
你可能对NumPy处理图像的索引方式有些误解。NumPy更喜欢使用一种叫做行优先索引的方式来处理图像,这种方式的顺序是(y, x, c),具体原因可以参考这里的说明:
使用[列优先索引]的缺点是可能会影响性能。通常在处理数组时,数据是按顺序访问的,这可以是隐式的(在数组操作中)或者显式的(通过循环访问图像的行)。如果这样做,数据的访问顺序就会变得不理想。随着第一个索引的增加,实际上是访问了内存中相隔很远的元素,这样的内存访问速度通常很慢。
如果你更喜欢使用列优先索引(x, y, c),并且不介意可能的性能损失,那么可以使用numpy.transpose
来调整索引的顺序:
np.array(image).transpose((1, 0, 2))
不过,NumPy的文档建议你还是习惯这种方式:
我们建议你学习在访问数组元素时反转索引的常规顺序。虽然这可能有点不习惯,但这更符合Python的语义和数据的自然顺序。
2. 颜色通道
数组的第三个轴表示每个像素的4个颜色通道,分别是(红色, 绿色, 蓝色, 透明度)。对于大多数应用来说,这比单个32位数字更有用。例如,你可以通过写image[...,3]
来提取透明度通道。
如果你真的想要32位的颜色值,可以使用ndarray.view
方法来查看相同的图像数据,但使用不同的dtype
,然后使用numpy.reshape
来去掉最后一个轴(因为它现在是多余的):
a = np.array(image)
a.view(dtype=np.uint32).reshape(a.shape[:-1])