I need a python method to open and import TIFF images into numpy arrays so I can analyze and modify the pixel data and then save them as TIFFs again. (They are basically light intensity maps in greyscale, representing the respective values per pixel)
I couldn't find any documentation on PIL methods concerning TIFF. I tried to figure it out, but only got "bad mode" or "file type not supported" errors.
What do I need to use here?
This question is related to
python
numpy
python-imaging-library
tiff
PyLibTiff worked better for me than PIL, which as of December 2020 still doesn't support color images with more than 8 bits per color.
from libtiff import TIFF
tif = TIFF.open('filename.tif') # open tiff file in read mode
# read an image in the currect TIFF directory as a numpy array
image = tif.read_image()
# read all images in a TIFF file:
for image in tif.iter_images():
pass
tif = TIFF.open('filename.tif', mode='w')
tif.write_image(image)
You can install PyLibTiff with
pip3 install numpy libtiff
The readme of PyLibTiff also mentions the tifffile
library but I haven't tried it.
In case of image stacks, I find it easier to use scikit-image
to read, and matplotlib
to show or save. I have handled 16-bit TIFF image stacks with the following code.
from skimage import io
import matplotlib.pyplot as plt
# read the image stack
img = io.imread('a_image.tif')
# show the image
plt.imshow(mol,cmap='gray')
plt.axis('off')
# save the image
plt.savefig('output.tif', transparent=True, dpi=300, bbox_inches="tight", pad_inches=0.0)
I use matplotlib for reading TIFF files:
import matplotlib.pyplot as plt
I = plt.imread(tiff_file)
and I
will be of type ndarray
.
According to the documentation though it is actually PIL that works behind the scenes when handling TIFFs as matplotlib only reads PNGs natively, but this has been working fine for me.
There's also a plt.imsave
function for saving.
I recommend using the python bindings to OpenImageIO, it's the standard for dealing with various image formats in the vfx world. I've ovten found it more reliable in reading various compression types compared to PIL.
import OpenImageIO as oiio
input = oiio.ImageInput.open ("/path/to/image.tif")
You could also use GDAL to do this. I realize that it is a geospatial toolkit, but nothing requires you to have a cartographic product.
Link to precompiled GDAL binaries for windows (assuming windows here) http://www.gisinternals.com/sdk/
To access the array:
from osgeo import gdal
dataset = gdal.Open("path/to/dataset.tiff", gdal.GA_ReadOnly)
for x in range(1, dataset.RasterCount + 1):
band = dataset.GetRasterBand(x)
array = band.ReadAsArray()
You can also use pytiff of which I'm the author.
import pytiff
with pytiff.Tiff("filename.tif") as handle:
part = handle[100:200, 200:400]
# multipage tif
with pytiff.Tiff("multipage.tif") as handle:
for page in handle:
part = page[100:200, 200:400]
It's a fairly small module and may not have as many features as other modules, but it supports tiled tiffs and bigtiff, so you can read parts of large images.
import cv2
image = cv2.imread(tiff_file.tif)
cv2.imshow('tif image',image)
Source: Stackoverflow.com