Python: lire et écrire TIFF 16 bits, trois canaux, images couleur

<!-Est-ce que quelqu'un a une méthode pour importer une image TIFF 16 bits par canal, 3 canaux en Python?

Je n'ai pas encore trouvé de méthode qui préserve la profondeur de 16 bits par canal en traitant avec le format TIFF. J'espère qu'une âme utile trouvera une solution.

<!-Voici une liste de ce que j'ai essayé jusqu'à présent sans succès et les résultats:

import numpy as np
import PIL.Image as Image
import libtiff
import cv2

im = Image.open('a.tif')
# IOError: cannot identify image file

tif = libtiff.TIFF.open('a.tif')
im = tif.read_image()
# im only contains one of the three channels. im.dtype is uint16 as desired.
im = []
for i in tif.iter_images():
    # still only returns one channel

im = np.array(cv2.imread('a.tif'))
# im.dtype is uint8 and not uint16 as desired.
# specifying dtype as uint16 does not correct this
<!-Jusqu'à présent, la seule solution que j'ai trouvée est de convertir L'image en PNG avec ImageMagick. Alors la norme des tourbières matplotlib.pyplot.imread lit le fichier PNG sans aucun problème.

un autre problème que j'ai est d'enregistrer n'importe quels tableaux vides en tant que fichiers PNG 16 bits qui jusqu'à présent n'a pas été simple non plus.

21
demandé sur Lars Chr 2013-08-26 18:41:49

4 réponses

il a des fonctionnalités limitées, surtout quand il s'agit d'écrire à nouveau sur le disque images non RGB, mais Christoph Gohlke tifffile module lit-3 canaux 16 bits Tiff avec pas de problèmes, je l'ai juste testé:

>>> import tifffile as tiff
>>> a = tiff.imread('Untitled-1.tif')
>>> a.shape
(100L, 100L, 3L)
>>> a.dtype
dtype('uint16')

et Photoshop lit sans se plaindre ce que j'obtiens de faire:

>>> tiff.imsave('new.tiff', a)
24
répondu Jaime 2013-08-26 16:51:51

La réponse par @Jaime fonctionne.

en même temps j'ai réussi à résoudre le problème en utilisant cv2.imread in OpenCV.

Par défaut cv2.imread convertira une image 16 bits, trois canaux en a.tif à 8 bits, comme indiqué dans la question.

cv2.imread accepte un drapeau après le nom du fichier ( cv2.imread(filename[, flags]) ) qui spécifie le type de couleur de l'image chargée cf. le documentation:

  1. > 0 renvoie une image couleur à 3 canaux. Il en résulte une conversion en 8 bits comme indiqué ci-dessus.
  2. 0 renvoie une image à l'échelle de gris. Il en résulte également une conversion en 8 bits.
  3. <0 renvoie l'image telle quelle. renvoie une image 16 bits.

ainsi ce qui suit Lira l'image sans conversion:

>>> im = cv2.imread('a.tif', -1)
>>> im.dtype
dtype('uint16')
>>> im.shape
(288, 384, 3)

notez Qu'OpenCV renvoie les canaux R, G et B dans l'ordre inverse donc im[:,:,0] est le canal B, im[:,:,1] le G canal et im[:,:,2] est la chaîne R.

j'ai aussi trouvé que cv2.imwrite peut écrire 16 bits,trois fichiers TIFF.

>>> cv2.imwrite('out.tif', im)

vérification de la profondeur de bits avec ImageMagick:

$ identify -verbose out.tif
  Format: TIFF (Tagged Image File Format)
  Class: DirectClass
  Geometry: 384x288+0+0
  Resolution: 72x72
  Print size: 5.33333x4
  Units: PixelsPerInch
  Type: TrueColor
  Base type: TrueColor
  Endianess: MSB
  Colorspace: sRGB
  Depth: 16-bit
  Channel depth:
    red: 16-bit
    green: 16-bit
    blue: 16-bit
  ....
19
répondu Lars Chr 2017-05-23 11:47:32

j'ai trouvé une alternative supplémentaire aux deux méthodes ci-dessus.

scikit-image paquet peut aussi lire 16 bits, trois fichiers TIFF utilisant les deux tifffile.py et FreeImage et les spécifier comme le plugin à utiliser.

en lisant en utilisant tifffile.py est probablement fait plus simplement de la manière montrée par @Jaime, j'ai pensé que je voudrais montrer comment il est utilisé avec scikit-image au cas où quelqu'un veut le faire dans ce manière.

Pour toute personne utilisant Ubuntu, FreeImage est disponible sous la forme libfreeimage3 en utilisant apt.

Si le tifffile.py l'option plugin est utilisée tifffile.py doit être copié dans le répertoire skimage/io/_plugins (F. ex. sur Ubuntu le chemin complet dans mon cas était /usr/local/lib/python2.7/dist-packages/skimage/io/_plugins/).

>>> import skimage.io
>>> im = skimage.io.imread('a.tif', plugin='tifffile')
>>> im.dtype
dtype('uint16')
>>> im.shape
(288, 384, 3)
>>> im = skimage.io.imread('a.tif', plugin='freeimage')
>>> im.dtype
dtype('uint16')
>>> im.shape
(288, 384, 3)

l'Écriture de fichiers TIFF:

>>> skimage.io.imsave('b.tif', im, plugin='tifffile')
>>> skimage.io.imsave('c.tif', im, plugin='freeimage')

vérification du bitdepth des deux b.tif et c.tif utiliser ImageMagick montre que chaque canal dans les deux images est de 16 bits.

10
répondu Lars Chr 2017-05-23 12:34:54

pour moi les alternatives précédentes n'ont pas fonctionné. J'ai utilisé gdal succès pour la lecture d'images 16bit de 1 Go.

Vous pouvez ouvrir une image avec quelque chose comme ceci:

from osgeo import gdal
import numpy as np
ds = gdal.Open("name.tif")
channel = np.array(ds.GetRasterBand(1).ReadAsArray())

Il y a une liste de prise en charge plongeur que vous pouvez utiliser pour écrire les données.

4
répondu G M 2016-09-23 15:48:43