有没有什么办法使用任何常用的Python包将numpy数组保存为16位图像(tif,png)? This是我可以在过去工作的唯一方式,但我需要安装FreeImage软件包,这有点烦人。可以使用“普通”(Enthought)python将numpy数组保存为16位图像吗?
这似乎是一个非常基本的任务,所以我希望它应该被scipy覆盖,但scipy.misc.imsave只能做8位。
任何想法?
有没有什么办法使用任何常用的Python包将numpy数组保存为16位图像(tif,png)? This是我可以在过去工作的唯一方式,但我需要安装FreeImage软件包,这有点烦人。可以使用“普通”(Enthought)python将numpy数组保存为16位图像吗?
这似乎是一个非常基本的任务,所以我希望它应该被scipy覆盖,但scipy.misc.imsave只能做8位。
任何想法?
另一种方法是使用pypng。你仍然需要安装另一个软件包,但它是纯Python,所以应该很简单。 (实际上有一个在pypng源用Cython文件,但它的使用是可选的。)
下面是使用pypng到numpy的阵列写入PNG的示例:
import png
import numpy as np
# The following import is just for creating an interesting array
# of data. It is not necessary for writing a PNG file with PyPNG.
from scipy.ndimage import gaussian_filter
# Make an image in a numpy array for this demonstration.
nrows = 240
ncols = 320
np.random.seed(12345)
x = np.random.randn(nrows, ncols, 3)
# y is our floating point demonstration data.
y = gaussian_filter(x, (16, 16, 0))
# Convert y to 16 bit unsigned integers.
z = (65535*((y - y.min())/y.ptp())).astype(np.uint16)
# Use pypng to write z as a color PNG.
with open('foo_color.png', 'wb') as f:
writer = png.Writer(width=z.shape[1], height=z.shape[0], bitdepth=16)
# Convert z to the Python list of lists expected by
# the png writer.
z2list = z.reshape(-1, z.shape[1]*z.shape[2]).tolist()
writer.write(f, z2list)
# Here's a grayscale example.
zgray = z[:, :, 0]
# Use pypng to write zgray as a grayscale PNG.
with open('foo_gray.png', 'wb') as f:
writer = png.Writer(width=z.shape[1], height=z.shape[0], bitdepth=16, greyscale=True)
zgray2list = zgray.tolist()
writer.write(f, zgray2list)
这里的颜色输出:
和这里的灰度输出:
更新:我最近创建了一个名为numpngw
模块,用于写入numpy的阵列到PNG文件提供一个功能的GitHub的仓库。该存储库有一个setup.py
文件用于将其作为软件包进行安装,但基本代码位于单个文件numpngw.py
中,可以将其复制到任何方便的位置。 numpngw
唯一的依赖是numpy。
下面是生成同样的16位图像那些脚本如上图所示:
import numpy as np
import numpngw
# The following import is just for creating an interesting array
# of data. It is not necessary for writing a PNG file with PyPNG.
from scipy.ndimage import gaussian_filter
# Make an image in a numpy array for this demonstration.
nrows = 240
ncols = 320
np.random.seed(12345)
x = np.random.randn(nrows, ncols, 3)
# y is our floating point demonstration data.
y = gaussian_filter(x, (16, 16, 0))
# Convert y to 16 bit unsigned integers.
z = (65535*((y - y.min())/y.ptp())).astype(np.uint16)
# Use numpngw to write z as a color PNG.
numpngw.write_png('foo_color.png', z)
# Here's a grayscale example.
zgray = z[:, :, 0]
# Use numpngw to write zgray as a grayscale PNG.
numpngw.write_png('foo_gray.png', zgray)
PNG和numpngw的这种解释是非常有帮助!但是,我认为我应该提到一个小小的“错误”。在转换为16位无符号整数时,y.max()应该是y.min()。对于随机颜色的图片,它并不重要,但对于真实的图片,我们需要做的正确。这是更正的代码行...
z = (65535*((y - y.min())/y.ptp())).astype(np.uint16)
我刚注意到这个!当然,你是对的。我已经更新了我的答案(以及示例https://github.com/WarrenWeckesser/numpngw)。 – 2017-06-20 02:29:51
这很好用!作为额外的好处,pyng是“Canopy软件包”之一,虽然默认情况下不安装,但它可以通过Canopy程序轻松安装。 – DanHickstein 2014-09-12 22:37:08