Python 与tif一起保存图像元数据的最佳方法是什么?
在我作为一名研究生的工作中,我捕获显微镜图像并使用python将其保存为原始tif。我想添加元数据,如我使用的显微镜名称、放大级别和成像激光波长。这些细节对于我如何后期处理图像都很重要 我应该可以用tif做这个,对吗?因为它有一个标题 我能够在PIL图像中添加信息:Python 与tif一起保存图像元数据的最佳方法是什么?,python,python-imaging-library,tiff,Python,Python Imaging Library,Tiff,在我作为一名研究生的工作中,我捕获显微镜图像并使用python将其保存为原始tif。我想添加元数据,如我使用的显微镜名称、放大级别和成像激光波长。这些细节对于我如何后期处理图像都很重要 我应该可以用tif做这个,对吗?因为它有一个标题 我能够在PIL图像中添加信息: im.info['microscope'] = 'george' 但是当我保存并加载该图像时,我添加的信息就消失了 我愿意接受所有建议。如果我也这样做了,我将只保存一个单独的带有元数据的.txt文件,但如果能将其嵌入到图像中,那就
im.info['microscope'] = 'george'
但是当我保存并加载该图像时,我添加的信息就消失了
我愿意接受所有建议。如果我也这样做了,我将只保存一个单独的带有元数据的.txt文件,但如果能将其嵌入到图像中,那就太好了。您可以尝试在TIFF图像的
标记属性中设置标记。这是一个ImageFileDirectory
对象。请参见TiffImagePlugin.py
或者,如果安装了libtiff
,则可以在保存文件后,使用子流程
模块调用命令在标题中设置字段。有许多可用的标签
根据:
如果需要10个以上的私有标记,TIFF规范建议,与其使用大量私有标记,不如分配一个私有标记,将其定义为数据类型IFD,并使用它指向所谓的“私有IFD”。在这个私有IFD中,下一步可以使用任何想要的标记。这些私有IFD标记不需要在Adobe中正确注册,它们位于自己的命名空间中,对特定类型的IFD是私有的
但不确定PIL是否支持这一点
我应该可以用tif做这个,对吗?因为它有一个标题
没有
首先,你的前提是错误的,但这是一个骗局。TIFF确实有一个标题,但它不允许您在其中存储任意元数据
但是TIFF是一种带标签的文件格式,是一系列不同类型的块,因此标题在这里并不重要。而且,您始终可以创建自己的私有块(任意ID>32767)并在其中存储您想要的任何内容
问题是,除了您自己的代码之外,没有任何东西会知道您存储在那里的内容。所以,您可能需要存储EXIF或XMP或其他一些标准格式,以便使用元数据扩展TIFF。但即使在那里,EXIF或您选择的任何东西都不会有“microscope”的标记,因此最终您将不得不在某个字符串字段中存储类似“microscope=george\nspam=eggs\n”的内容,然后自己解析它
但真正的问题是,PIL/Piddle并没有为您提供存储EXIF或XMP或其他类似内容的简单方法
首先,它不适用于任意的额外数据。在节省时间时,它通常被忽略
如果查看的是PIL文档,您将看到它将额外的数据读入一个特殊属性,Image.tag
,并且可以通过将tiffinfo
关键字参数传递到Image.save
方法来保存数据。但额外的数据是从TIFF标记ID到二进制大块数据的映射。您可以从未记录的PIL.ExifTags.TAGS
dict获取Exif标记ID(或者自己在线查找),但这是PIL将为您提供的最大支持
另外,请注意,首先访问标签
并使用tiffinfo
需要一个合理的最新版本;旧版本和经典的PIL不支持它。(具有讽刺意味的是,他们确实对JPG文件提供了部分EXIF支持,但从来没有完成过,而且已经被删除了……)此外,尽管它似乎没有文档记录,但如果您构建的枕头没有libtiff
,它似乎忽略了tiffinfo
所以最终,你可能想做的是:
- 选择所需的元数据格式
- 使用不同于PIL/Pillow的库来读写元数据。(例如,您可以将
GExiv2
或pyexif
用于EXIF。)
对于内部使用,请尝试在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'])
请注意,JSON使用unicode字符串
与其他显微镜软件兼容,考虑保存文件,在IMAGE描述标签中存储定义的元数据作为XML。
< P>是在Python中保存具有大量元数据的显微镜图像的一种选择。
它没有太多的外部文档,但是文档非常好,因此您只需在python中键入help(tiffile)就可以获得大量信息,或者查看
您可以查看源代码(第750行)中的TiffWriter.save函数,了解可用于编写元数据的不同关键字参数
一种是使用description,它接受字符串。当您阅读图像时,它将显示为标记“ImageDescription”
另一种方法是使用参数,它接受元组列表。它允许您写入中存在的任何标记名。最简单的方法之一是将它们作为字符串写入,因为这样就不必指定长度
您还可以使用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,
)
阅读图像时,可以看到以下标记:
frames = tifffile.TiffFile(save_name)
page = frames.pages[0]
print(page.tags["ImageDescription"].value)
“这是我的描述”
print(page.tags["MicroManagerMetadata"].value)
输出:{'ChannelIndex':1,'Slice':5}
print(page.tags["ProcessingSoftware"].value)
我的意大利面代码已经提到OME-TIFF开放标准-谢谢。非常同意它非常适合您的数据存储。OpenMicroscope已经为OME-TIFF提供了此类元数据。您可以在中轻松地使用Python语法,这将允许您编写OME-TIFF。事实上,到今天为止,您可以直接从Python使用生物格式!