Search code examples
pythonpngpython-imaging-library

Read 16-bit PNG image file using Python


I'm trying to read a PNG image file written in 16-bit data type. The data should be converted to a NumPy array. But I have no idea how to read the file in '16-bit'. I tried with PIL and SciPy, but they converted the 16-bit data to 8-bit when they load it. Could anyone please let me know how to read data from a 16-bit PNG file and convert it to NumPy array without changing the datatype?

The following is the script that I used.

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
               

Solution

  • I'd recommend using opencv:

    pip install opencv-python
    

    and

    import cv2
    image = cv2.imread('16bit.png', cv2.IMREAD_UNCHANGED)
    
    
    • in contrast to OpenImageIO, opencv could be installed from pip
    • The time, required to read a single 4000x4000 png is about the same as PIL, but PIL uses more CPU and requires additional time to convert data back to uint16.