简体   繁体   English

将 16 位 numpy 数组保存为 16 位 PNG 图像

[英]Save 16-bit numpy arrays as 16-bit PNG image

I'm trying to save a 16-bit numpy array as a 16-bit PNG but what I obtain is only a black picture.我正在尝试将 16 位 numpy 数组保存为 16 位 PNG,但我获得的只是一张黑色图片。 I put here a minimum example of what I'm talking aboout.我在这里放了一个我正在谈论的最低限度的例子。

im = np.random.randint(low=1, high=6536, size=65536).reshape(256,256) #sample numpy array to save as image
plt.imshow(im, cmap=plt.cm.gray)

在此处输入图片说明

Given the above numpy array this is the image I see with matplotlib, but when then I save the image as 16-bit png I obtain the picture below:鉴于上面的 numpy 数组,这是我用 matplotlib 看到的图像,但是当我将图像保存为 16 位 png 时,我获得了下面的图片:

import imageio

imageio.imwrite('result.png', im)

Image saved:图像保存:

在此处输入图片说明

where some light grey spots are visible but the image is substantially black.其中一些浅灰色斑点是可见的,但图像基本上是黑色的。 Anyway when I read back the image and visualize it again with matplotlib I see the same starting image.无论如何,当我读回图像并使用 matplotlib 再次对其进行可视化时,我看到了相同的起始图像。 I also tried other libraries instead of imageio (like PIL or PyPNG ) but with the same result.我还尝试了其他库而不是imageio (如PILPyPNG ),但结果相同。

I know that 16-bit image values range from 0 to 65535 and in the array numpy array here there only values from 1 to 6536, but I need to save numpy arrays images similar to this, ie where the maximum value represented in the image isn't the maximum representable value.我知道 16 位图像值的范围从 0 到 65535,在数组 numpy 数组中,这里只有 1 到 6536 的值,但我需要保存与此类似的 numpy 数组图像,即图像中表示的最大值是'不是最大的可表示值。 I think that some sort of nornalization is involved in the saving process.我认为保存过程中涉及某种规范化。 I need to save the array exactly as I see them in matplotlib at their maximum resolution and without compression or shrinkage in their values (so division by 255 or conversion to 8-bit array are not suitable).我需要完全按照我在 matplotlib 中看到的最大分辨率保存数组,并且不压缩或缩小它们的值(因此除以 255 或转换为 8 位数组是不合适的)。

It looks like imageio.imwrite will do the right thing if you convert the data type of the array to numpy.uint16 before writing the PNG file:它看起来像imageio.imwrite会做正确的事情,如果你转换数组的数据类型numpy.uint16写PNG文件之前:

imageio.imwrite('result.png', im.astype(np.uint16))

When I do that, result.png is a 16 bit gray-scale PNG file.当我这样做时, result.png是一个 16 位灰度 PNG 文件。

If you want the image to have the full grayscale range from black to white, you'll have to scale the values to the range [0, 65535].如果您希望图像具有从黑色到白色的完整灰度范围,则必须将值缩放到范围 [0, 65535]。 Eg something like:例如:

im2 = (65535*(im - im.min())/im.ptp()).astype(np.uint16)

Then you can save that array with然后你可以用

imageio.imwrite('result2.png', im2)

For writing a NumPy array to a PNG file, an alternative is numpngw (a package that I created).要将 NumPy 数组写入 PNG 文件,另一种方法是numpngw (我创建的包)。 For example,例如,

from numpngw import write_png

im2 = (65535*(im - im.min())/im.ptp()).astype(np.uint16)
write_png('result2.png', im2)

If you are already using imageio , there is probably no signficant advantage to using numpngw .如果您已经使用imageio ,有可能是无显着优势,使用numpngw It is, however, a much lighter dependency than imageio --it depends only on NumPy (no dependence on PIL/Pillow and no dependence on libpng ).然而,它比imageio依赖要轻得多—— imageio依赖于 NumPy(不依赖于 PIL/Pillow 也不依赖于libpng )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM