Tjelvar Olsson     About     Posts     Feed     Newsletter


I'm currently working on a computing book aimed at biologists. Check out the Biologist's Guide to Computing!

Saving 16-bit tiff files using Python

When dealing with microscopy data it is not uncommon to be dealing with image files that have 16-bit channels. This presents a difficulty when working with Python as many imaging libraries struggle to save numpy.uint16 arrays.

To illustrate the problem let us create a white 50x50 pixel 16-bit image using numpy.

>>> import numpy as np
>>> ar = np.ones((50,50), dtype=np.uint16)
>>> ar = ar * np.iinfo(np.uint16).max

PIL/Pillow simply, and helpfully, raises a TypeError.

>>> from PIL import Image
>>> img = Image.fromarray(ar)
Traceback (most recent call last):
...
TypeError: Cannot handle this data type

SciPy does save the file, but it converts it to 8-bit. Personally I do not like this behaviour as it has caused me confusion on several occasions as subsequent steps of the analysis has read the file and tried to extract meaningful information from it.

>>> import scipy.misc
>>> scipy.misc.imsave('scipy.tiff', ar)
>>> ar2 = scipy.misc.imread('scipy.tiff')
>>> ar2.dtype
dtype('uint8')
>>> np.max(ar2)
0

PyLibTiff to the rescue

PyLibTiff is a package that provides a wrapper to the libtiff library. To use it simply make sure that you have the libtiff library installed on your system and then you can use pip to install PyLibTiff. On a Debian based system.

sudo apt-get install libtiff-dev
sudo pip install libtiff

Now let us look at how to save a file using PyLibTiff.

>>> from libtiff import TIFF
>>> tiff = TIFF.open('libtiff.tiff', mode='w')
>>> tiff.write_image(ar)
>>> tiff.close()

To show that everything is working as expected let us open the tiff file and read in the image from it.

>>> tiff = TIFF.open('libtiff.tiff', mode='r')
>>> ar = tiff.read_image()
>>> tiff.close()
>>> ar.dtype
dtype('uint16')
>>> np.max(ar)
65535

Other options

Another option for working with 16-bit tiff files is OpenCV-Python. I also believe that tiffile.py can handle them, although I have not tested this myself. The reason I prefer PyLibTiff over these is that it can be installed into a virtual environment using pip.