跳转到主要内容

读写TIFF文件

项目描述

Tifffile是一个Python库,用于

  1. 将NumPy数组存储在TIFF(标记图像文件格式)文件中,并

  2. 从用于生物成像的类似TIFF的文件中读取图像和元数据。

图像和元数据可以从TIFF、BigTIFF、OME-TIFF、GeoTIFF、Adobe DNG、ZIF(可缩放图像文件格式)、MetaMorph STK、蔡司LSM、ImageJ超堆栈、Micro-Manager MMStack和NDTiff、SGI、NIHImage、奥林巴斯FluoView和SIS、ScanImage、分子动力学GEL、Aperio SVS、莱卡SCN、罗氏BIF、珀金埃尔默QPTIFF(QPI、PKI)、Hamamatsu NDPI、Argos AVS和飞利浦DP格式的文件中读取。

图像数据可以作为NumPy数组或Zarr数组/组从条带、瓦片、页面(IFD)、子IFD、高阶序列和金字塔层读取。

图像数据可以以多页、体积、金字塔、内存映射、瓦片、预测或压缩的形式写入与TIFF、BigTIFF、OME-TIFF和ImageJ超堆栈兼容的文件。

通过imagecodecs库支持许多压缩和预测方案,包括LZW、PackBits、Deflate、PIXTIFF、LZMA、LERC、Zstd、JPEG(8位和12位,无损)、JPEG 2000、JPEG XR、JPEG XL、WebP、PNG、EER、Jetraw、24位浮点数和水平差分。

Tifffile还可以用于检查TIFF结构、从多维度文件序列中读取图像数据、写入fsspec ReferenceFileSystem用于TIFF文件和图像文件序列、修补TIFF标签值以及解析许多专有元数据格式。

作者:

克里斯托夫·戈尔克

许可协议:

BSD 3-Clause

版本:

2024.9.20

DOI:

10.5281/zenodo.6795860

快速入门

Python包索引安装tifffile包及其所有依赖项

python -m pip install -U tifffile[all]

tifffile也可在其他包仓库中找到,例如Anaconda、Debian和MSYS2。

tifffile库通过docstrings进行类型注解和文档化

python -c "import tifffile; help(tifffile)"

tifffile可以用作控制台脚本来检查和预览TIFF文件

python -m tifffile --help

请参见示例,了解如何使用编程接口。

源代码和支持可在GitHub上找到。

image.sc论坛也提供支持

要求

本修订版本已测试以下要求和依赖项(其他版本可能也适用)

  • CPython 3.10.11, 3.11.9, 3.12.6, 3.13.0rc2 64位

  • NumPy 2.1.1

  • Imagecodecs 2024.6.1(编码或解码LZW、JPEG等压缩段所需)

  • Matplotlib 3.9.2(绘图所需)

  • Lxml 5.3.0(仅用于验证和打印XML所需)

  • Zarr 2.18.3(仅用于打开Zarr存储所需)

  • Fsspec 2024.9.0(仅用于打开ReferenceFileSystem文件所需)

修订版本

2024.9.20

  • 通过5107个测试。

  • 修复写入ImageJ文件中的颜色查找表(破坏性更改)。

  • 改进类型。

  • 移除对Python 3.9的支持。

2024.8.30

  • 支持写入OME数据集和一些结构化注释元素。

2024.8.28

  • 修复LSM扫描类型和维度顺序(#269,破坏性更改)。

  • 使用IO[bytes]代替BinaryIO进行类型注解(#268)。

2024.8.24

  • 写入非形状文件时不删除尾随长度为1的维度(破坏性更改)。

  • 修复以特定模数轴顺序写入OME-TIFF。

  • 使imshow能够识别NaN。

2024.8.10

  • 放宽JPEG、JPEG2K和JPEGXL压缩的bitspersample检查(#265)。

2024.7.24

  • 修复通过Zarr存储读取连续多页系列(#67)。

2024.7.21

  • 修复由numpy类型引起的乘积函数中的整数溢出。

  • 允许标签读取函数失败。

2024.7.2

  • 启用memmap以创建具有非本地字节顺序的空文件。

  • 弃用Python 3.9,支持Python 3.13。

2024.6.18

  • 确保TiffPage.nodata可转换为dtype(破坏性更改,#260)。

  • 支持Argos AVS幻灯片。

2024.5.22

  • 从Sequence派生TiffPages、TiffPageSeries、FileSequence、StoredShape。

  • 截断循环IFD链,不抛出TiffFileError(破坏性更改)。

  • 弃用对TiffPages.pages和FileSequence.files的访问。

  • 启用TIFF命名空间中枚举的弃用警告。

  • 移除一些弃用代码(破坏性更改)。

  • 向TiffPage添加iccprofile属性,并向TiffWriter.write添加参数。

  • 不检测VSI为SIS格式。

  • 限制记录的异常消息长度。

  • 修复GitHub上docstring示例未正确渲染的问题(#254,#255)。

2024.5.10

  • 支持在DNG 1.7中读取JPEGXL压缩。

  • 读取IDEAS软件创建的无效TIFF。

2024.5.3

  • 修复读取未完整写入的LSM。

  • 修复读取具有额外行图块的Philips DP(破坏性更改)。

2024.4.24

  • 修复与numpy 2的兼容性问题(#252)。

2024.4.18

  • 修复Philips幻灯片中缺失最后行图块时的write_fsspec。

  • 在write_fsspec中添加不引号文件名的选项。

  • 允许使用deflate、LZMA和Zstd压缩 bilevel 图像。

2024.2.12

  • 弃用dtype,在FileSequence.asarray中添加chunkdtype参数。

  • 将imreadargs参数传递给FileSequence.imread。

2024.1.30

  • 修复与numpy 2的兼容性问题(#238)。

  • 启用弃用警告的元组压缩参数。

  • 在xml2dict中解析数字序列。

2023.12.9

  • 以float32读取32位Indica Labs TIFF。

  • 修复读取没有时间轴的大LSM文件时未绑定的局部错误。

  • 如果可用,使用os.sched_getaffinity获取CPU数量(#231)。

  • 将默认工作线程数限制为32。

2023.9.26

  • 在写入时,懒洋洋地将dask数组转换为ndarray。

  • 允许指定读写时的缓冲区大小。

  • 修复了在读取某些损坏的文件时发生的 IndexError(ZarrTiffStore #227)。

2023.9.18

  • 在以体素瓦片写入非体素数据时引发异常(#225)。

  • 改进了压缩多页文件的并发写入。

  • 修复了带预测器的big-endian文件的fsspec引用(#216)。

2023.8.30

  • 支持独占文件创建模式(#221, #223)。

2023.8.25

  • 验证形状元数据与页面形状兼容。

  • 在从imread返回选择时支持输出参数(#222)。

2023.8.12

  • 支持解压缩EER帧。

  • 便于过滤记录的警告(#216)。

  • 从UIC1Tag读取更多标签(#217)。

  • 修复了main中的文件提前关闭问题(#218)。

  • 不要在main中强制使用matplotlib后端tkagg(#219)。

  • 添加py.typed标记。

  • 放弃对imagecodecs < 2023.3.16的支持。

2023.7.18

  • ...

有关旧版本,请参阅CHANGES文件。

注意

TIFF,标记图像文件格式,由Aldus公司和美国Adobe系统公司创建。

Tifffile支持TIFF6规范的子集,主要包括8位、16位、32位和64位整数,16位、32位和64位浮点数,灰度图和多采样图像。具体来说,不实现CCITT和OJPEG压缩,没有JPEG压缩的色度子采样,颜色空间转换,不同类型的样本,或IPTC、ICC和XMP元数据。

除了经典的TIFF外,tifffile还支持几种类似于TIFF的格式,这些格式并不严格遵循TIFF6规范。某些格式允许文件和数据大小超过经典TIFF的4GB限制。

  • BigTIFF由版本号43标识,使用不同的文件头、IFD和标签结构,具有64位偏移量。该格式还添加了64位数据类型。Tifffile可以读写BigTIFF文件。

  • ImageJ超堆栈在第一个IFD之后连续存储所有图像数据,可能超过4GB。大于4GB的文件只包含一个IFD。从第一个IFD的ImageDescription标签中可以确定多达6维图像数据的大小和形状,该标签是Latin-1编码的。Tifffile可以读写ImageJ超堆栈。

  • OME-TIFF文件在一个或多个TIFF或BigTIFF文件中存储多达8维图像数据。第一个IFD的ImageDescription标签中发现的UTF-8编码的OME-XML元数据定义了在多维图像数据中TIFF IFD的位置。Tifffile可以读取OME-TIFF文件(除多文件金字塔外)并将NumPy数组写入单个文件的OME-TIFF。

  • Micro-Manager NDTiff在一个或多个经典TIFF文件中存储多维图像数据。包含在单独的NDTiff.index二进制文件中的元数据定义了图像数组中TIFF IFD的位置。每个TIFF文件还包含在偏移8处的非TIFF二进制结构中的元数据。金字塔数据集的降采样图像数据存储在单独的文件夹中。Tifffile可以读取NDTiff文件。版本0和1系列,瓦片、拼接和多分辨率金字塔不受支持。

  • Micro-Manager MMStack在一个或多个经典TIFF文件中存储6维图像数据。包含在非TIFF二进制结构和JSON字符串中的元数据定义了图像堆栈的维度和图像帧数据在文件和图像堆栈中的位置。TIFF结构和元数据通常损坏或错误。Tifffile可以读取MMStack文件。

  • 蔡司LSM文件存储所有小于4GB的IFD,并在4GB以上的图像数据周围使用32位StripOffsets。每个系列和位置的StripOffsets需要单独展开。StripByteCounts标签包含未压缩数据的字节数。Tifffile可以读取任意大小的LSM文件。

  • MetaMorph堆栈,STK文件包含在第一页的图像数据之后连续存储的附加图像平面。平面的总数等于UIC2tag的计数。Tifffile可以读取STK文件。

  • ZIF(可缩放图像文件格式)是BigTIFF的一个子规范,包含了SGI的ImageDepth扩展和额外的压缩方案。仅允许使用JPEG、PNG、JPEG XR和JPEG 2000压缩的小端、分块、交错、每样本8位的图像。Tifffile可以读取和写入ZIF文件。

  • Hamamatsu NDPI文件在文件头、IFD和标记结构中使用了某些64位偏移量。单个LONG类型的标记值可以超过32位。64位标记值和偏移量的高字节存储在IFD结构之后。Tifffile可以读取大于4GB的NDPI文件。当压缩段尺寸大于65530或缺少重启标记时,使用常见的JPEG库无法解码。Tifffile通过分别解码重启标记之间的MCUs来绕过这一限制,但性能较差。BitsPerSample、SamplesPerPixel和PhotometricInterpretation标记可能包含错误值,可以使用标记65441的值来纠正。

  • Philips TIFF幻灯片存储分块页面的填充ImageWidth和ImageLength标记值。可以使用XML格式描述的第一页的DICOM_PIXEL_SPACING属性来纠正这些值。分块偏移量和字节数可能为0。Tifffile可以读取Philips幻灯片。

  • Ventana/Roche BIF幻灯片将分块和元数据存储在BigTIFF容器中。分块可能重叠,需要根据XMP标记中的TileJointInfo元素进行拼接。体积扫描使用ImageDepth扩展存储。Tifffile可以读取BIF并解码单个分块,但不执行拼接。

  • ScanImage可选择性地允许大于2GB的损坏非BigTIFF文件。可以使用IFD和标记值在整个文件中的偏移量常量差来恢复StripOffsets和StripByteCounts的值。如果图像数据在每个页面上连续存储,Tifffile可以读取此类文件。

  • GeoTIFF稀疏文件允许分块或分块偏移量和字节数为0。在读取时,此类段被隐式设置为0或NODATA值。Tifffile可以读取GeoTIFF稀疏文件。

  • Tifffile shaped文件将多维图像系列数组的形状和用户提供的元数据以JSON格式存储在系列的第一个页面的ImageDescription标记中。该格式允许多个系列、子IFD、具有零偏移量和字节数的稀疏段以及截断系列,其中只包含系列的第一页,并且图像数据在每个页面上连续存储。除了Tifffile之外,没有其他软件支持截断格式。

用于从Python读取、写入、检查或操作科学TIFF文件的库包括:aicsimageioapeer-ometiff-librarybigtifffabio.TiffIOGDALimreadlarge_imageopenslide-pythonopentilepylibtiffpylsmpymimagepython-bioformatspytiffscanimagetiffreader-pythonSimpleITKslideiotiffslidetifftoolstyfxtiffndtiff

参考文献

示例

将NumPy数组写入单页RGB TIFF文件

>>> data = numpy.random.randint(0, 255, (256, 256, 3), 'uint8')
>>> imwrite('temp.tif', data, photometric='rgb')

以NumPy数组形式读取TIFF文件中的图像

>>> image = imread('temp.tif')
>>> image.shape
(256, 256, 3)

使用photometricplanarconfig参数将3x3x3 NumPy数组写入交错RGB、平面RGB或3页灰度TIFF

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

使用extrasamples参数指定如何解释额外组件,例如,对于具有未关联alpha通道的RGBA图像

>>> data = numpy.random.randint(0, 255, (256, 256, 4), 'uint8')
>>> imwrite('temp.tif', data, photometric='rgb', extrasamples=['unassalpha'])

将3维NumPy数组写入多页、16位灰度TIFF文件

>>> data = numpy.random.randint(0, 2**12, (64, 301, 219), 'uint16')
>>> imwrite('temp.tif', data, photometric='minisblack')

将多页TIFF文件中的整个图像栈以NumPy数组形式读取

>>> image_stack = imread('temp.tif')
>>> image_stack.shape
(64, 301, 219)
>>> image_stack.dtype
dtype('uint16')

将TIFF文件的第一页中的图像以NumPy数组形式读取

>>> image = imread('temp.tif', key=0)
>>> image.shape
(301, 219)

读取选定范围内的页面中的图像

>>> images = imread('temp.tif', key=range(4, 40, 2))
>>> images.shape
(18, 301, 219)

迭代TIFF文件中的所有页面并逐个读取图像

>>> with TiffFile('temp.tif') as tif:
...     for page in tif.pages:
...         image = page.asarray()
...

在不读取任何图像数据的情况下获取TIFF文件中图像栈的信息

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

检查TIFF文件第一页的“XResolution”标签

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

迭代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
...

覆盖现有标签的值,例如,XResolution

>>> with TiffFile('temp.tif', mode='r+') as tif:
...     _ = tif.pages[0].tags['XResolution'].overwrite((96000, 1000))
...

使用BigTIFF格式、分离的颜色组件、平铺、Zlib压缩级别8、水平差分预测器和附加元数据写入5维浮点数组

>>> 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'},
... )

将xyz体素大小为2.6755x2.6755x3.9474微米的10 fps体量序列写入ImageJ超堆叠格式TIFF文件

>>> 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,
...     },
... )

从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

将ImageJ超堆叠文件中的连续图像数据内存映射

>>> memmap_volume = memmap('temp.tif')
>>> memmap_volume.shape
(6, 57, 256, 256)
>>> del memmap_volume

创建包含空图像的TIFF文件并将其写入内存映射的NumPy数组(注意:此操作不适用于压缩或平铺)

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

将两个NumPy数组写入多序列TIFF文件(注意:其他TIFF阅读器将无法识别两个序列;使用OME-TIFF格式以获得更好的互操作性)

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

从TIFF文件中读取第二个图像序列

>>> series1 = imread('temp.tif', series=1)
>>> series1.shape
(4, 256, 256)

依次将一个连续序列的帧写入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)
...

将图像序列追加到现有TIFF文件中(注意:此操作不适用于ImageJ超栈或OME-TIFF文件)

>>> data = numpy.random.randint(0, 255, (301, 219, 3), 'uint8')
>>> imwrite('temp.tif', data, photometric='rgb', append=True)

从瓦片生成器创建TIFF文件

>>> 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',
... )

使用可选元数据写入多维、多分辨率(金字塔式)、多序列OME-TIFF文件。子分辨率图像写入SubIFDs。限制并行编码为2个线程。将缩略图图像作为单独的图像序列写入

>>> 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'})
...

访问金字塔OME-TIFF文件中的图像级别

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

迭代并解码TIFF文件中的单个JPEG压缩瓦片

>>> with TiffFile('temp.ome.tif') as tif:
...     fh = tif.filehandle
...     for page in tif.pages:
...         for index, (offset, bytecount) in enumerate(
...             zip(page.dataoffsets, page.databytecounts)
...         ):
...             _ = fh.seek(offset)
...             data = fh.read(bytecount)
...             tile, indices, shape = page.decode(
...                 data, index, jpegtables=page.jpegtables
...             )
...

使用Zarr读取TIFF文件中瓦片金字塔图像的部分

>>> import zarr
>>> store = imread('temp.ome.tif', aszarr=True)
>>> z = zarr.open(store, mode='r')
>>> z
<zarr.hierarchy.Group '/' read-only>
>>> z[0]  # base layer
<zarr.core.Array '/0' (8, 2, 512, 512, 3) uint8 read-only>
>>> z[0][2, 0, 128:384, 256:].shape  # read a tile from the base layer
(256, 256, 3)
>>> store.close()

将Zarr存储库中的基础层作为dask数组加载

>>> import dask.array
>>> store = imread('temp.ome.tif', aszarr=True)
>>> dask.array.from_zarr(store, 0)
dask.array<...shape=(8, 2, 512, 512, 3)...chunksize=(1, 1, 128, 128, 3)...
>>> store.close()

将Zarr存储库以JSON格式写入fsspec ReferenceFileSystem

>>> store = imread('temp.ome.tif', aszarr=True)
>>> store.write_fsspec('temp.ome.tif.json', url='file://')
>>> store.close()

将fsspec ReferenceFileSystem作为Zarr组打开

>>> import fsspec
>>> import imagecodecs.numcodecs
>>> imagecodecs.numcodecs.register_codecs()
>>> mapper = fsspec.get_mapper(
...     'reference://', fo='temp.ome.tif.json', target_protocol='file'
... )
>>> z = zarr.open(mapper, mode='r')
>>> z
<zarr.hierarchy.Group '/' read-only>

创建包含空、瓦片图像序列的OME-TIFF文件,并通过Zarr接口写入(注意:此操作不支持压缩)

>>> imwrite(
...     'temp2.ome.tif',
...     shape=(8, 800, 600),
...     dtype='uint16',
...     photometric='minisblack',
...     tile=(128, 128),
...     metadata={'axes': 'CYX'},
... )
>>> store = imread('temp2.ome.tif', mode='r+', aszarr=True)
>>> z = zarr.open(store, mode='r+')
>>> z
<zarr.core.Array (8, 800, 600) uint16>
>>> z[3, 100:200, 200:300:2] = 1024
>>> store.close()

使用两个I/O工作线程从TIFF文件序列中读取图像作为NumPy数组

>>> imwrite('temp_C001T001.tif', numpy.random.rand(64, 64))
>>> imwrite('temp_C001T002.tif', numpy.random.rand(64, 64))
>>> image_sequence = imread(
...     ['temp_C001T001.tif', 'temp_C001T002.tif'], ioworkers=2, maxworkers=1
... )
>>> image_sequence.shape
(2, 64, 64)
>>> image_sequence.dtype
dtype('float64')

以NumPy或Zarr数组的形式从一系列TIFF文件中读取图像堆栈

>>> image_sequence = TiffSequence('temp_C0*.tif', pattern=r'_(C)(\d+)(T)(\d+)')
>>> image_sequence.shape
(1, 2)
>>> image_sequence.axes
'CT'
>>> data = image_sequence.asarray()
>>> data.shape
(1, 2, 64, 64)
>>> store = image_sequence.aszarr()
>>> zarr.open(store, mode='r')
<zarr.core.Array (1, 2, 64, 64) float64 read-only>
>>> image_sequence.close()

将Zarr存储库以JSON格式写入fsspec ReferenceFileSystem

>>> store = image_sequence.aszarr()
>>> store.write_fsspec('temp.json', url='file://')

将fsspec ReferenceFileSystem作为Zarr数组打开

>>> import fsspec
>>> import tifffile.numcodecs
>>> tifffile.numcodecs.register_codec()
>>> mapper = fsspec.get_mapper(
...     'reference://', fo='temp.json', target_protocol='file'
... )
>>> zarr.open(mapper, mode='r')
<zarr.core.Array (1, 2, 64, 64) float64 read-only>

从命令行检查TIFF文件

$ python -m tifffile temp.ome.tif

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面