98 votes

Travailler avec des fichiers TIFF (importation, exportation) en Python en utilisant numpy

J'ai besoin d'une méthode python pour ouvrir et importer des images TIFF dans des tableaux numpy afin de pouvoir analyser et modifier les données des pixels, puis les sauvegarder à nouveau en tant que TIFF. (Ce sont essentiellement des cartes d'intensité lumineuse en niveaux de gris, représentant les valeurs respectives par pixel)

Je n'ai trouvé aucune documentation sur les méthodes PIL concernant les TIFF. J'ai essayé de comprendre, mais je n'ai obtenu que des erreurs "mauvais mode" ou "type de fichier non pris en charge".

De quoi ai-je besoin d'utiliser ici?

125voto

jterrace Points 21939

Tout d'abord, j'ai téléchargé une image TIFF de test à partir de cette page appelée a_image.tif. Ensuite, je l'ai ouverte avec PIL de cette manière :

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

Cela a affiché l'image en arc-en-ciel. Pour la convertir en un tableau numpy, c'est aussi simple que :

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

Nous pouvons constater que la taille de l'image et la forme du tableau correspondent :

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

Et le tableau contient des valeurs de type uint8 :

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

Une fois que vous avez terminé de modifier le tableau, vous pouvez le convertir de nouveau en une image PIL de cette façon :

>>> Image.fromarray(imarray)

61voto

Michael Brennan Points 1921

J'utilise matplotlib pour lire les fichiers TIFF :

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

et I sera de type ndarray.

Selon la documentation cependant, c'est en fait PIL qui fonctionne en arrière-plan lors du traitement des TIFFs car matplotlib ne lit nativement que les PNG, mais cela a bien fonctionné pour moi.

Il y a aussi une fonction plt.imsave pour enregistrer.

18voto

Jzl5325 Points 1720

Vous pourriez également utiliser GDAL pour cela. Je comprends que c'est une boîte à outils géospatiale, mais rien ne vous oblige à avoir un produit cartographique.

Lien vers les binaires précompilés de GDAL pour Windows (en supposant que vous utilisez Windows) Lien

Pour accéder au tableau :

from osgeo import gdal

dataset = gdal.Open("chemin/vers/jeu de données.tiff", gdal.GA_ReadOnly)
for x in range(1, dataset.RasterCount + 1):
    band = dataset.GetRasterBand(x)
    array = band.ReadAsArray()

14voto

Boris Points 1440

PyLibTiff a mieux fonctionné pour moi que PIL, qui, en avril 2023, ne prend toujours pas en charge les images en couleur avec plus de 8 bits par couleur.

from libtiff import TIFF

tif = TIFF.open('filename.tif') # ouvrir le fichier tiff en mode lecture
# lire une image dans le répertoire TIFF actuel en tant qu'array numpy
image = tif.read_image()

# lire toutes les images dans un fichier TIFF:
for image in tif.iter_images(): 
    pass

tif = TIFF.open('filename.tif', mode='w')
tif.write_image(image)

Vous pouvez installer PyLibTiff avec

pip3 install numpy pylibtiff

Le readme de PyLibTiff mentionne également la bibliothèque tifffile mais je ne l'ai pas essayée.

11voto

Claire Points 143

En cas de piles d'images, je trouve plus facile d'utiliser scikit-image pour lire, et matplotlib pour afficher ou enregistrer. J'ai géré les piles d'images TIFF 16 bits avec le code suivant.

from skimage import io
import matplotlib.pyplot as plt

# lire la pile d'images
img = io.imread('a_image.tif')
# afficher l'image
plt.imshow(img,cmap='gray')
plt.axis('off')
# enregistrer l'image
plt.savefig('output.tif', transparent=True, dpi=300, bbox_inches="tight", pad_inches=0.0)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X