有没有办法使用任何常用的python包将numpy数组保存为16位图像(tif,png)?这是我过去可以开始工作的唯一方法,但我需要安装FreeImage包,这有点烦人.
这似乎是一个非常基本的任务,所以我希望它应该被scipy覆盖,但是scipy.misc.imsave只能做8位.
有任何想法吗?
War*_*ser 10
一种选择是使用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)
Run Code Online (Sandbox Code Playgroud)
这是颜色输出:

这是灰度输出:

更新:我最近为一个模块创建了一个github存储库,numpngw它提供了一个将numpy数组写入PNG文件的函数.存储库有一个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)
Run Code Online (Sandbox Code Playgroud)
小智 6
png 和 numpngw 的这个解释非常有帮助!但是,我认为我应该提到一个小“错误”。在转换为 16 位无符号整数时,y.max() 应该是 y.min()。对于随机颜色的图片来说,这并不重要,但对于真实的图片,我们需要做对。这是更正后的代码行...
z = (65535*((y - y.min())/y.ptp())).astype(np.uint16)
Run Code Online (Sandbox Code Playgroud)