使用Python保存图像元数据和tif的最佳方法是什么?

Bec*_*cca 11 python tiff python-imaging-library

在我作为研究生的工作中,我捕获显微镜图像并使用python将它们保存为原始tif.我想添加元数据,例如我正在使用的显微镜​​名称,放大倍数和成像激光波长.这些细节对于我如何对图像进行后期处理非常重要.

我应该可以用tif做到这一点,对吗?既然它有一个标题?

我能够在PIL图像中添加信息:

im.info['microscope'] = 'george'
Run Code Online (Sandbox Code Playgroud)

但是当我保存并加载该图像时,我添加的信息就消失了.

我对所有建议持开放态度.如果我也有,我只会用元数据保存一个单独的.txt文件,但将它嵌入图像中会非常好.谢谢.

aba*_*ert 9

我应该可以用tif做到这一点,对吗?既然它有一个标题?

没有.

首先,你的前提是错误的,但这是一个红色的鲱鱼.TIFF确实有一个标题,但它不允许您在其中存储任意元数据.

但是TIFF是一种标记文件格式,是一系列不同类型的块,所以标题在这里并不重要.您可以随时创建自己的私人块(任何ID> 32767)并存储您想要的任何内容.

问题是,除了你自己的代码之外什么也不知道你在那里存储了什么.因此,您可能想要的是存储EXIF或XMP或其他一些标准化格式,以便使用元数据扩展TIFF.但即使在那里,EXIF或你选择的任何东西都没有"显微镜"的标签,所以最终你最终不得不在某些字符串中存储类似"microscope = george \nspam = eggs \n"的内容字段,然后自己解析.

但真正的问题是PIL/Pillow没有为您提供存储EXIF或XMP或类似其他任何东西的简便方法.

首先,Image.info不是任意额外数据.在节省时间,它通常被忽略.

如果您查看TIFF的PIL文档,您将看到它将其他数据读入特殊属性Image.tag,并可以通过将tiffinfo关键字参数传递给Image.save方法来保存数据.但是,附加数据是从TIFF标签ID到二进制数据库的映射.您可以从未记录的PIL.ExifTags.TAGS字典中获取Exif标记ID (或者通过自己在线查找),但这与PIL将为您提供的支持一样多.

另请注意,首先访问tag和使用枕头tiffinfo需要合理的最新版本; 旧版本和经典PIL不支持它.(具有讽刺意味的是,他们确实对JPG文件提供了部分EXIF支持,这些文件从未完成并且已经被删除......)此外,虽然它似乎没有记录,但如果你没有构建Pillow 似乎无视.libtifftiffinfo

所以最终,你可能想要做的是:

  • 选择所需的元数据格式.
  • 使用与PIL/Pillow不同的库来读取和写入该元数据.(例如,您可以使用GExiv2pyexif用于EXIF.)


cgo*_*lke 8

对于内部使用,请尝试将元数据保存为TIFF ImageDescription标记中的JSON,例如

from __future__ import print_function, unicode_literals

import json
import numpy
import tifffile  # http://www.lfd.uci.edu/~gohlke/code/tifffile.py.html

data = numpy.arange(256).reshape((16, 16)).astype('u1')
metadata = dict(microscope='george', shape=data.shape, dtype=data.dtype.str)
print(data.shape, data.dtype, metadata['microscope'])

metadata = json.dumps(metadata)
tifffile.imsave('microscope.tif', data, description=metadata)

with tifffile.TiffFile('microscope.tif') as tif:
    data = tif.asarray()
    metadata = tif[0].image_description
metadata = json.loads(metadata.decode('utf-8'))
print(data.shape, data.dtype, metadata['microscope'])
Run Code Online (Sandbox Code Playgroud)

请注意,JSON使用unicode字符串.

要与其他显微镜软件兼容,请考虑保存OME-TIFF文件,该文件将定义的元数据作为XML存储在ImageDescription标记中.


小智 6

Tifffile是一种在python中保存带有大量元数据的显微镜图像的选项.

它没有很多外部文档,但是docstings很棒,所以只需在python中输入help(tifffile)就可以得到很多信息,或者查看源代码.

您可以在源代码(第750行)中查看TiffWriter.save函数,以获取可用于编写元数据的不同关键字参数.

一种是使用description,它接受一个字符串.当您阅读图像时,它将显示为标记"ImageDescription".

另一种方法是使用extratags参数,该参数接受元组列表.这允许您编写TIFF.TAGS()中存在的任何标记名称.最简单的方法之一是将它们写为字符串,因为这样您就不必指定长度.

您还可以使用ijmetadata编写ImageJ元数据,此处的源代码中列出了可接受的类型.

例如,如果您编写以下内容:

import json
import numpy as np
import tifffile

im = np.random.randint(0, 255, size=(150, 100), dtype=np.uint8)
# Description
description = "This is my description"
# Extratags
metadata_tag = json.dumps({"ChannelIndex": 1, "Slice": 5})
extra_tags = [("MicroManagerMetadata", 's', 0, metadata_tag, True),
              ("ProcessingSoftware", 's', 0, "my_spaghetti_code", True)]
# ImageJ metadata. 'Info' tag needs to be a string
ijinfo = {"InitialPositionList": [{"Label": "Pos1"}, {"Label": "Pos3"}]}
ijmetadata = {"Info": json.dumps(ijinfo)}
# Write file
tifffile.imsave(
    save_name,
    im,
    ijmetadata=ijmetadata,
    description=description,
    extratags=extra_tags,
)
Run Code Online (Sandbox Code Playgroud)

阅读图像时,您可以看到以下标记:

frames = tifffile.TiffFile(save_name)
page = frames.pages[0]
print(page.tags["ImageDescription"].value)
Run Code Online (Sandbox Code Playgroud)

出:'这是我的描述'

print(page.tags["MicroManagerMetadata"].value)
Run Code Online (Sandbox Code Playgroud)

Out:{'ChannelIndex':1,'Slice':5}

print(page.tags["ProcessingSoftware"].value)
Run Code Online (Sandbox Code Playgroud)

出:my_spaghetti_code