Python 以png格式保存图像的2个像素通道

Python 以png格式保存图像的2个像素通道,python,scipy,png,Python,Scipy,Png,根据scipy文档,可以像这样保存图像的单个通道 >>> x = np.zeros((255, 255)) >>> x = np.zeros((255, 255), dtype=np.uint8) >>> x[:] = np.arange(255) >>> imsave('/tmp/gradient.png', x) 和这样的图像的3个通道: >>> rgb = np.zeros((255, 255, 3

根据scipy文档,可以像这样保存图像的单个通道

>>> x = np.zeros((255, 255))
>>> x = np.zeros((255, 255), dtype=np.uint8)
>>> x[:] = np.arange(255)
>>> imsave('/tmp/gradient.png', x)
和这样的图像的3个通道:

>>> rgb = np.zeros((255, 255, 3), dtype=np.uint8)
>>> rgb[..., 0] = np.arange(255)
>>> rgb[..., 1] = 55
>>> rgb[..., 2] = 1 - np.arange(255)
>>> imsave('/tmp/rgb_gradient.png', rgb)
但是,是否可以仅将图像的两个通道保存为png?我试图用2个通道模拟上述代码,但遇到以下错误:

ValueError: 'arr' does not have a suitable array shape for any mode.

我并不完全清楚你想要实现什么,或者你想要存储什么样的渠道

根据,只有一个选项:使用灰度+alpha通道。当然,您可以这样存储数据,但是

  • 这意味着位深度为16或32;也许不是你想要的
  • 默认情况下,库会将其解释为灰度+alpha通道
实际上更加灵活,似乎支持任意频道,但据libtiff称,libtiff不支持2频道。(可能是过时的信息;不确定)

所以这可能取决于你真正想做什么。如果您只想存储2个通道(因为您想保存字节,不需要更多通道),而管道中的每一步都可以根据您的喜好进行调整以解释,我建议只存储3个通道,其中一个通道为空(例如,全零)。PNGs过滤器将能够有效地压缩它。当然,在以后阅读/使用这些代码时,您需要修改代码,以便在保存时将其解释为已完成


如果这只是为了某种只涉及python的科学堆栈的任务,那么您可以使用numpy的来存储数组。(备注:将有通用压缩;但没有像
x+1-x
->这样的过滤器使用像素:0、1、2、3难以压缩;但使用增量过滤器:0、1、1、1易于压缩;意思是:与PNG相比,压缩效率取决于您的图像)PNG文件格式支持两个通道的图像,每个通道的位深度为16或32位。PNG将此类文件解释为带有alpha(即透明度)通道的灰度图像。事实上,如果您正在尝试使用alpha通道创建灰度图像,那么这个答案可能会对您有所帮助。如果您试图使用PNG格式来存储数组,那么我建议使用不同的格式。有关建议,请参见@sascha的答案

我编写的()可以用这种格式编写PNG文件。只需传入类型为
np.uint16
或形状为
np.uint32
的数组(m,n,2)

比如说,

import numpy as np
from numpngw import write_png


# Create `img` with a black outer border, a white inner border and
# a transparent square in the middle.
img = np.full((64, 64, 2), fill_value=2**16-1, dtype=np.uint16)
img[16:-16, 16:-16, 1] = 0
img[:8, :, 0] = 0
img[-8:, :, 0] = 0
img[:, :8, 0] = 0
img[:, -8:, 0] = 0

write_png('foo.png', img)

您可能需要进行一些实验,才能将这些数据读回具有相同形状和数据类型的数组中。例如,读取此文件时枕头的默认行为是返回一个具有形状(m,n,4)的8位数组;也就是说,Pillow将数据转换为RGBA格式。

我只想存储红色和绿色通道。我对蓝色频道不感兴趣,因为我没有该频道的信息。