James Gregson's Website

Sep 02, 2018

16 bit Image IO with Python

Reading and writing 16 bit images is very important for a wide variety of topics but is surprisingly overlooked by many imaging libraries in Python.

There are a number of different Python extensions that support 16 bit images but have surprising restrictions or complications:

  • scikit-image+FreeImage plugin: apparently reads/writes 16 bit formats but I could not find any explanation of how to actually install it.
  • Pillow: extension of the PIL library but seems to only support monochrome 16 bit formats.
  • PyPNG: reads/writes 16 bit images but is terribly slow due to pure-Python implementation
  • easy_image_io: My own foray into this, reads/writes 16 bit pngs & tiffs but requires compilation

However, I recently discovered that OpenCV will happily read/write at least 16 bit png files. Installation is very easy:

pip install opencv-python

Reading and writing is then easily done:

import cv2
I = np.ones( (10,20,3) )*65535
cv2.imwrite( 'output16.png', I.astype(np.uint16) )
I2 = cv2.imread( 'output16.png', cv2.IMREAD_UNCHANGED )
I2.shape
# prints (10, 20, 3)
I2[1,1,1]
# prints 65535

This is by far the easiest way I've seen to get 16 bit image IO running under python, provided you're willing to introduce the relatively large dependency of OpenCV.