Tifffile es una biblioteca de Python para
Las imágenes y los metadatos se pueden leer desde TIFF, BigTIFF, OME-TIFF, GeoTIFF, Adobe DNG, ZIF (formato de archivo de imagen con zoom), MetaMorph STK, Zeiss LSM, ImageJ hyperstack, Micro-Manager MMStack y NDTiff, SGI, NIHImage, Olympus FluoView. y SIS, ScanImage, Molecular Dynamics GEL, Aperio SVS, Leica SCN, Roche BIF, Archivos formateados PerkinElmer QPTIFF (QPI, PKI), Hamamatsu NDPI, Argos AVS y Philips DP.
Los datos de imagen se pueden leer como matrices NumPy o matrices/grupos Zarr de tiras, mosaicos, páginas (IFD), SubIFD, series de orden superior y niveles piramidales.
Los datos de imagen se pueden escribir en archivos compatibles con hiperstack TIFF, BigTIFF, OME-TIFF e ImageJ en formato de varias páginas, volumétrico, piramidal, asignable en memoria, en mosaico, predicho o comprimido.
Muchos esquemas de compresión y predicción son compatibles a través de la biblioteca imagecodecs, incluidos LZW, PackBits, Deflate, PIXTIFF, LZMA, LERC, Zstd, JPEG (8 y 12 bits, sin pérdidas), JPEG 2000, JPEG XR, JPEG XL, WebP, PNG. , EER, Jetraw, punto flotante de 24 bits y diferenciación horizontal.
Tifffile también se puede utilizar para inspeccionar estructuras TIFF, leer datos de imágenes de secuencias de archivos multidimensionales, escribir fsspec ReferenceFileSystem para archivos TIFF y secuencias de archivos de imágenes, parchear valores de etiquetas TIFF y analizar muchos formatos de metadatos propietarios.
Autor: | Christoph Göhlke |
---|---|
Licencia: | Cláusula 3 de BSD |
Versión: | 2024.9.20 |
DOI: | 10.5281/zenodo.6795860 |
Instale el paquete tifffile y todas las dependencias del índice de paquetes de Python:
python -m pip instalar -U tifffile[todos]
Tifffile también está disponible en otros repositorios de paquetes como Anaconda, Debian y MSYS2.
La biblioteca tifffile tiene anotaciones de tipo y está documentada mediante cadenas de documentos:
python -c "importar archivo tiff; ayuda (archivo tiff)"
Tifffile se puede utilizar como script de consola para inspeccionar y obtener una vista previa de archivos TIFF:
python -m archivo tiff --ayuda
Consulte Ejemplos de uso de la interfaz de programación.
El código fuente y el soporte están disponibles en GitHub.
También se proporciona soporte en el foro image.sc.
Esta revisión se probó con los siguientes requisitos y dependencias (es posible que funcionen otras versiones):
2024.9.20
2024.8.30
2024.8.28
2024.8.24
2024.8.10
2024.7.24
2024.7.21
2024.7.2
2024.6.18
2024.5.22
2024.5.10
2024.5.3
2024.4.24
2024.4.18
2024.2.12
2024.1.30
2023.12.9
2023.9.26
2023.9.18
2023.8.30
2023.8.25
2023.8.12
2023.7.18
Consulte el archivo CAMBIOS para revisiones anteriores.
TIFF, el formato de archivo de imagen etiquetado, fue creado por Aldus Corporation y Adobe Systems Incorporated.
Tifffile admite un subconjunto de la especificación TIFF6, principalmente imágenes enteras de 8, 16, 32 y 64 bits, flotantes de 16, 32 y 64 bits, en escala de grises y de muestras múltiples. Específicamente, no se implementan la compresión CCITT y OJPEG, el submuestreo de croma sin compresión JPEG, las transformaciones del espacio de color, las muestras con diferentes tipos ni los metadatos IPTC, ICC y XMP.
Además del TIFF clásico, tifffile admite varios formatos similares a TIFF que no se ajustan estrictamente a la especificación TIFF6. Algunos formatos permiten que los tamaños de archivos y datos excedan el límite de 4 GB del TIFF clásico:
Otras bibliotecas para leer, escribir, inspeccionar o manipular archivos TIFF científicos desde Python son aicsimageio, apeer-ometiff-library, bigtiff, fabio.TiffIO, GDAL, imread, large_image, openslide-python, opentile, pylibtiff, pylsm, pymimage, python. -bioformatos, pytiff, scanimagetiffreader-python, SimpleITK, slideio, tiffslide, tifftools, tyf, xtiff y ndtiff.
Escriba una matriz NumPy en un archivo TIFF RGB de una sola página:
>> > data = numpy . random . randint ( 0 , 255 , ( 256 , 256 , 3 ), 'uint8' )
>> > imwrite ( 'temp.tif' , data , photometric = 'rgb' )
Lea la imagen del archivo TIFF como matriz NumPy:
>> > image = imread ( 'temp.tif' )
>> > image . shape
( 256 , 256 , 3 )
Utilice los argumentos fotométricos y planarconfig para escribir una matriz NumPy de 3x3x3 en un RGB intercalado, un RGB plano o un TIFF en escala de grises de 3 páginas:
>> > data = numpy . random . randint ( 0 , 255 , ( 3 , 3 , 3 ), 'uint8' )
>> > imwrite ( 'temp.tif' , data , photometric = 'rgb' )
>> > imwrite ( 'temp.tif' , data , photometric = 'rgb' , planarconfig = 'separate' )
>> > imwrite ( 'temp.tif' , data , photometric = 'minisblack' )
Utilice el argumento extrasamples para especificar cómo se interpretan los componentes adicionales, por ejemplo, para una imagen RGBA con un canal alfa no asociado:
>> > data = numpy . random . randint ( 0 , 255 , ( 256 , 256 , 4 ), 'uint8' )
>> > imwrite ( 'temp.tif' , data , photometric = 'rgb' , extrasamples = [ 'unassalpha' ])
Escriba una matriz NumPy tridimensional en un archivo TIFF en escala de grises de 16 bits y varias páginas:
>> > data = numpy . random . randint ( 0 , 2 ** 12 , ( 64 , 301 , 219 ), 'uint16' )
>> > imwrite ( 'temp.tif' , data , photometric = 'minisblack' )
Lea toda la pila de imágenes del archivo TIFF de varias páginas como matriz NumPy:
>> > image_stack = imread ( 'temp.tif' )
>> > image_stack . shape
( 64 , 301 , 219 )
>> > image_stack . dtype
dtype ( 'uint16' )
Lea la imagen de la primera página del archivo TIFF como matriz NumPy:
>> > image = imread ( 'temp.tif' , key = 0 )
>> > image . shape
( 301 , 219 )
Lea imágenes de un rango seleccionado de páginas:
>> > images = imread ( 'temp.tif' , key = range ( 4 , 40 , 2 ))
>> > images . shape
( 18 , 301 , 219 )
Itere sobre todas las páginas del archivo TIFF y lea imágenes sucesivamente:
>> > with TiffFile ( 'temp.tif' ) as tif :
... for page in tif . pages :
... image = page . asarray ()
...
Obtenga información sobre la pila de imágenes en el archivo TIFF sin leer ningún dato de imagen:
>> > tif = TiffFile ( 'temp.tif' )
>> > len ( tif . pages ) # number of pages in the file
64
>> > page = tif . pages [ 0 ] # get shape and dtype of image in first page
>> > page . shape
( 301 , 219 )
>> > page . dtype
dtype ( 'uint16' )
>> > page . axes
'YX'
>> > series = tif . series [ 0 ] # get shape and dtype of first image series
>> > series . shape
( 64 , 301 , 219 )
>> > series . dtype
dtype ( 'uint16' )
>> > series . axes
'QYX'
>> > tif . close ()
Inspeccione la etiqueta "XResolution" de la primera página del archivo TIFF:
>> > with TiffFile ( 'temp.tif' ) as tif :
... tag = tif . pages [ 0 ]. tags [ 'XResolution' ]
...
>> > tag . value
( 1 , 1 )
>> > tag . name
'XResolution'
>> > tag . code
282
>> > tag . count
1
>> > tag . dtype
< DATATYPE . RATIONAL : 5 >
Itere sobre todas las etiquetas en el archivo TIFF:
>> > with TiffFile ( 'temp.tif' ) as tif :
... for page in tif . pages :
... for tag in page . tags :
... tag_name , tag_value = tag . name , tag . value
...
Sobrescriba el valor de una etiqueta existente, por ejemplo, XResolución:
>> > with TiffFile ( 'temp.tif' , mode = 'r+' ) as tif :
... _ = tif . pages [ 0 ]. tags [ 'XResolution' ]. overwrite (( 96000 , 1000 ))
...
Escriba una matriz de punto flotante de 5 dimensiones usando el formato BigTIFF, componentes de color separados, mosaicos, nivel de compresión Zlib 8, predictor de diferenciación horizontal y metadatos adicionales:
>> > data = numpy . random . rand ( 2 , 5 , 3 , 301 , 219 ). astype ( 'float32' )
>> > imwrite (
... 'temp.tif' ,
... data ,
... bigtiff = True ,
... photometric = 'rgb' ,
... planarconfig = 'separate' ,
... tile = ( 32 , 32 ),
... compression = 'zlib' ,
... compressionargs = { 'level' : 8 },
... predictor = True ,
... metadata = { 'axes' : 'TZCYX' },
... )
Escriba una serie temporal de volúmenes de 10 fps con un tamaño de vóxel xyz de 2,6755 x 2,6755 x 3,9474 micrones ^ 3 en un archivo TIFF con formato ImageJ hyperstack:
>> > volume = numpy . random . randn ( 6 , 57 , 256 , 256 ). astype ( 'float32' )
>> > image_labels = [ f' { i } ' for i in range ( volume . shape [ 0 ] * volume . shape [ 1 ])]
>> > imwrite (
... 'temp.tif' ,
... volume ,
... imagej = True ,
... resolution = ( 1.0 / 2.6755 , 1.0 / 2.6755 ),
... metadata = {
... 'spacing' : 3.947368 ,
... 'unit' : 'um' ,
... 'finterval' : 1 / 10 ,
... 'fps' : 10.0 ,
... 'axes' : 'TZYX' ,
... 'Labels' : image_labels ,
... },
... )
Lea el volumen y los metadatos del archivo Hyperstack de ImageJ:
>> > with TiffFile ( 'temp.tif' ) as tif :
... volume = tif . asarray ()
... axes = tif . series [ 0 ]. axes
... imagej_metadata = tif . imagej_metadata
...
>> > volume . shape
( 6 , 57 , 256 , 256 )
>> > axes
'TZYX'
>> > imagej_metadata [ 'slices' ]
57
>> > imagej_metadata [ 'frames' ]
6
Asigne en memoria los datos de imágenes contiguas en el archivo Hyperstack de ImageJ:
>> > memmap_volume = memmap ( 'temp.tif' )
>> > memmap_volume . shape
( 6 , 57 , 256 , 256 )
>> > del memmap_volume
Cree un archivo TIFF que contenga una imagen vacía y escriba en la matriz NumPy asignada en memoria (nota: esto no funciona con compresión o mosaico):
>> > memmap_image = memmap (
... 'temp.tif' , shape = ( 256 , 256 , 3 ), dtype = 'float32' , photometric = 'rgb'
... )
>> > type ( memmap_image )
< class 'numpy.memmap' >
>> > memmap_image [ 255 , 255 , 1 ] = 1.0
>> > memmap_image . flush ()
>> > del memmap_image
Escriba dos matrices NumPy en un archivo TIFF de varias series (nota: otros lectores TIFF no reconocerán las dos series; use el formato OME-TIFF para una mejor interoperabilidad):
>> > series0 = numpy . random . randint ( 0 , 255 , ( 32 , 32 , 3 ), 'uint8' )
>> > series1 = numpy . random . randint ( 0 , 255 , ( 4 , 256 , 256 ), 'uint16' )
>> > with TiffWriter ( 'temp.tif' ) as tif :
... tif . write ( series0 , photometric = 'rgb' )
... tif . write ( series1 , photometric = 'minisblack' )
...
Lea la segunda serie de imágenes del archivo TIFF:
>> > series1 = imread ( 'temp.tif' , series = 1 )
>> > series1 . shape
( 4 , 256 , 256 )
Escriba sucesivamente los fotogramas de una serie contigua en un archivo TIFF:
>> > data = numpy . random . randint ( 0 , 255 , ( 30 , 301 , 219 ), 'uint8' )
>> > with TiffWriter ( 'temp.tif' ) as tif :
... for frame in data :
... tif . write ( frame , contiguous = True )
...
Agregue una serie de imágenes al archivo TIFF existente (nota: esto no funciona con archivos ImageJ hyperstack o OME-TIFF):
>> > data = numpy . random . randint ( 0 , 255 , ( 301 , 219 , 3 ), 'uint8' )
>> > imwrite ( 'temp.tif' , data , photometric = 'rgb' , append = True )
Crea un archivo TIFF a partir de un generador de mosaicos:
>> > data = numpy . random . randint ( 0 , 2 ** 12 , ( 31 , 33 , 3 ), 'uint16' )
>> > def tiles ( data , tileshape ):
... for y in range ( 0 , data . shape [ 0 ], tileshape [ 0 ]):
... for x in range ( 0 , data . shape [ 1 ], tileshape [ 1 ]):
... yield data [ y : y + tileshape [ 0 ], x : x + tileshape [ 1 ]]
...
>> > imwrite (
... 'temp.tif' ,
... tiles ( data , ( 16 , 16 )),
... tile = ( 16 , 16 ),
... shape = data . shape ,
... dtype = data . dtype ,
... photometric = 'rgb' ,
... )
Escriba un archivo OME-TIFF multidimensional, multiresolución (piramidal) y multiserie con metadatos opcionales. Las imágenes de subresolución se escriben en SubIFD. Limite la codificación paralela a 2 subprocesos. Escriba una imagen en miniatura como una serie de imágenes separada:
>> > data = numpy . random . randint ( 0 , 255 , ( 8 , 2 , 512 , 512 , 3 ), 'uint8' )
>> > subresolutions = 2
>> > pixelsize = 0.29 # micrometer
>> > with TiffWriter ( 'temp.ome.tif' , bigtiff = True ) as tif :
... metadata = {
... 'axes' : 'TCYXS' ,
... 'SignificantBits' : 8 ,
... 'TimeIncrement' : 0.1 ,
... 'TimeIncrementUnit' : 's' ,
... 'PhysicalSizeX' : pixelsize ,
... 'PhysicalSizeXUnit' : 'µm' ,
... 'PhysicalSizeY' : pixelsize ,
... 'PhysicalSizeYUnit' : 'µm' ,
... 'Channel' : { 'Name' : [ 'Channel 1' , 'Channel 2' ]},
... 'Plane' : { 'PositionX' : [ 0.0 ] * 16 , 'PositionXUnit' : [ 'µm' ] * 16 },
... 'Description' : 'A multi-dimensional, multi-resolution image' ,
... 'MapAnnotation' : { # for OMERO
... 'Namespace' : 'openmicroscopy.org/PyramidResolution' ,
... '1' : '256 256' ,
... '2' : '128 128' ,
... },
... }
... options = dict (
... photometric = 'rgb' ,
... tile = ( 128 , 128 ),
... compression = 'jpeg' ,
... resolutionunit = 'CENTIMETER' ,
... maxworkers = 2 ,
... )
... tif . write (
... data ,
... subifds = subresolutions ,
... resolution = ( 1e4 / pixelsize , 1e4 / pixelsize ),
... metadata = metadata ,
... ** options ,
... )
... # write pyramid levels to the two subifds
... # in production use resampling to generate sub-resolution images
... for level in range ( subresolutions ):
... mag = 2 ** ( level + 1 )
... tif . write (
... data [..., :: mag , :: mag , :],
... subfiletype = 1 ,
... resolution = ( 1e4 / mag / pixelsize , 1e4 / mag / pixelsize ),
... ** options ,
... )
... # add a thumbnail image as a separate series
... # it is recognized by QuPath as an associated image
... thumbnail = ( data [ 0 , 0 , :: 8 , :: 8 ] >> 2 ). astype ( 'uint8' )
... tif . write ( thumbnail , metadata = { 'Name' : 'thumbnail' })
...
Acceda a los niveles de imagen en el archivo OME-TIFF piramidal:
>> > baseimage = imread ( 'temp.ome.tif' )
>> > second_level = imread ( 'temp.ome.tif' , series = 0 , level = 1 )
>> > with TiffFile ( 'temp.ome.tif' ) as tif :
... baseimage = tif . series [ 0 ]. asarray ()
... second_level = tif . series [ 0 ]. levels [ 1 ]. asarray ()
... number_levels = len ( tif . series [ 0 ]. levels ) # includes base level
...
Itere y decodifique mosaicos comprimidos JPEG individuales en el archivo TIFF: