it-swarm.com.de

Arbeiten mit TIFFs (Import, Export) in Python mit Numpy

Ich brauche eine Python-Routine, die TIFF-Bilder öffnen und in numpy-Arrays importieren kann, sodass ich die enthaltenen Daten analysieren und modifizieren und sie anschließend wieder als TIFF-Dateien speichern kann. (Sie sind im Wesentlichen Lichtintensitätskarten in Graustufen, die die jeweiligen Werte pro Pixel darstellen.)

Ich habe versucht, etwas zu finden, aber es gibt keine Dokumentation zu PIL-Methoden bezüglich TIFF. Ich versuchte es herauszufinden, bekam aber nur fehlerhaften Modus/Dateityp nicht unterstützte Fehler.

Was muss ich hier verwenden?

53
Jakob

Zuerst habe ich ein Test-TIFF-Bild von dieser Seite mit dem Namen a_image.tif heruntergeladen. Dann habe ich mit PIL so geöffnet:

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

Dies zeigte das Regenbogenbild. Um in ein numpy Array zu konvertieren, ist es so einfach wie folgt:

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

Wir können sehen, dass die Größe des Bildes und die Form des Arrays übereinstimmen:

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

Und das Array enthält uint8-Werte:

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

Wenn Sie mit dem Ändern des Arrays fertig sind, können Sie es wie folgt in ein PIL-Bild umwandeln:

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

Ich verwende matplotlib zum Lesen von TIFF-Dateien:

import matplotlib.pyplot as plt
I = plt.imread(tiff_file)

und I wird vom Typ ndarray sein.

Laut der Dokumentation ist es eigentlich PIL, das hinter den Kulissen arbeitet, wenn mit TIFFs gearbeitet wird, da matplotlib nur PNGs nativ liest, aber das hat für mich gut funktioniert.

Es gibt auch eine plt.imsave-Funktion zum Speichern.

40
Michael Brennan

Sie können dazu auch GDAL verwenden. Mir ist klar, dass es sich um ein Geodaten-Toolkit handelt, aber Sie brauchen kein kartografisches Produkt.

Link zu vorkompilierten GDAL-Binärdateien für Windows (Fenster hier vorausgesetzt) ​​ http://www.gisinternals.com/sdk/

So greifen Sie auf das Array zu:

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

pylibtiff hat für mich besser funktioniert als PIL, das keine Farbbilder mit mehr als 8 Bit pro Farbe unterstützt .

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)

Sie können pylibtiff mit installieren 

pip3 install numpy libtiff

Die Readme von pylibtiff erwähnt auch tifffile.py , aber ich habe es nicht probiert.

4
Boris

Sie können auch pytiff verwenden, von dem ich der Autor bin. 

    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]

Es ist ein relativ kleines Modul und hat möglicherweise nicht so viele Funktionen wie andere Module, aber es unterstützt gekachelte Tiffs und Bigtiff, sodass Sie Teile großer Bilder lesen können. 

2
hnfl

Bei Bildstapeln finde ich es einfacher, scikit-image zu lesen und matplotlib anzuzeigen oder zu speichern. Ich habe 16-Bit-TIFF-Bildstapel mit dem folgenden Code verarbeitet.

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)
2
Claire

Ich empfehle die Verwendung der Python-Bindungen für OpenImageIO, dies ist der Standard für den Umgang mit verschiedenen Bildformaten in der vfx-Welt. Ich habe festgestellt, dass es beim Lesen verschiedener Kompressionstypen im Vergleich zu PIL zuverlässiger war.

import OpenImageIO as oiio
input = oiio.ImageInput.open ("/path/to/image.tif")
0
zeno