使用Python读取16位PNG图像文件

Now*_*uri 7 python png python-imaging-library

我正在尝试读取以16位数据类型编写的PNG图像文件.数据应转换为NumPy数组.但我不知道如何在'16位'中读取文件.我尝试使用PIL和SciPy,但是当它们加载时它们将16位数据转换为8位数据.谁能告诉我如何从16位PNG文件中提取数据并将其转换为NumPy数组而不更改数据类型?

以下是我使用的脚本.

from scipy import misc
import numpy as np
from PIL import Image
#make a png file    
a = np.zeros((1304,960), dtype=np.uint16)
a[:] = np.arange(960)
misc.imsave('16bit.png',a)

#read the png file using scipy
b = misc.imread('16bit.png')
print "scipy:" ,b.dtype

#read the png file using PIL
c = Image.open('16bit.png')   
d = np.array(c)
print "PIL:", d.dtype
Run Code Online (Sandbox Code Playgroud)

Igo*_*gor 17

我建议使用 opencv:

pip install opencv-python
Run Code Online (Sandbox Code Playgroud)

import cv2
image = cv2.imread('16bit.png', cv2.IMREAD_UNCHANGED)

Run Code Online (Sandbox Code Playgroud)
  • 与OpenImageIO相比,opencv 可以通过 pip 安装
  • 读取单个 4000x4000 png 所需的时间与 PIL 大致相同,但 PIL 使用更多的 CPU 并且需要额外的时间将数据转换回uint16.


Rut*_*rus 6

我建立的最简单的解决方案:

当我打开 16 位单色 PNG Pillow 时,它无法正确打开I;16模式。 Image.mode打开为I(32 位)

因此,转换为 numpy 数组的最佳方法。它是 dtype="int32",因此我们将其转换为 dtype="uint16"。

import numpy as np
from PIL import Image

im = Image.fromarray(np.array(Image.open(name)).astype("uint16"))
print("Image mode: ",im.mode))
Run Code Online (Sandbox Code Playgroud)

在 Python 3.6.8 和 Pillow 6.1.0 中测试


小智 5

我在这里遇到同样的问题.我用我自己创建的16位图像测试了它.当我用png包加载它们时,所有这些都被正确打开了.'file'的输出看起来还不错.

用PIL打开它们总是导致8位numpy-arrays.

在Linux btw上使用Python 2.7.6.

像这样对我有用:

import png
import numpy as np

reader = png.Reader( path-to-16bit-png )
pngdata = reader.read()
px_array = np.array( map( np.uint16, pngdata[2] ) 
print( px_array.dtype )
Run Code Online (Sandbox Code Playgroud)

也许有人可以提供更多信息,在哪种情况下前一种方法有效?(因为这个很慢)

提前致谢.