Working with TIFFs (import, export) in Python using numpy

眉间皱痕 提交于 2019-12-27 11:54:41

问题


I need a python routine that can open and import TIFF images into numpy arrays, so I can analyze and modify the contained data and afterwards save them as TIFFs again. (They are basically light intensity maps in greyscale, representing the respective values per pixel)

I tried to find something, but there is no documentation on PIL methods concerning TIFF. I tried to figure it out, but only got bad mode/ file type not supported errors.

What do I need to use here?


回答1:


First, I downloaded a test TIFF image from this page called a_image.tif. Then I opened with PIL like this:

>>> from PIL import Image
>>> im = Image.open('a_image.tif')
>>> im.show()

This showed the rainbow image. To convert to a numpy array, it's as simple as:

>>> import numpy
>>> imarray = numpy.array(im)

We can see that the size of the image and the shape of the array match up:

>>> imarray.shape
(44, 330)
>>> im.size
(330, 44)

And the array contains uint8 values:

>>> imarray
array([[  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246],
       ..., 
       [  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246]], dtype=uint8)

Once you're done modifying the array, you can turn it back into a PIL image like this:

>>> Image.fromarray(imarray)
<Image.Image image mode=L size=330x44 at 0x2786518>



回答2:


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.




回答3:


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()



回答4:


pylibtiff worked better for me than PIL, which 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 tifffile.py, but I haven't tried it.




回答5:


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.




回答6:


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)



回答7:


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")


来源:https://stackoverflow.com/questions/7569553/working-with-tiffs-import-export-in-python-using-numpy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!