在tif的同时保存图像元数据的最佳方法是什么?

2024-05-19 14:00:58 发布

您现在位置:Python中文网/ 问答频道 /正文

在我的研究生工作中,我捕获显微镜图像并使用python将其保存为原始tif。我想添加元数据,如我使用的显微镜名称、放大级别和成像激光波长。这些细节对于我后期处理图像非常重要。

我应该可以用tif来做,对吧?因为它有头?

我可以添加到PIL图像中的信息中:

im.info['microscope'] = 'george'

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

我接受所有的建议。如果我也有,我将只保存一个单独的.txt文件和元数据,但它将是非常好的嵌入到图像中。


Tags: 数据图像info名称信息pil级别细节
3条回答

Tifffile是在python中使用大量元数据保存显微镜图像的一个选项。

它没有很多外部文档,但是文档很好,所以您可以通过在python中键入帮助(tifffile)来获取大量信息,或者查看source code

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

一种是使用description,它接受一个字符串。当您阅读图像时,它将显示为标签“ImageDescription”。

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

您还可以使用ijmetadata编写ImageJ元数据,可接受的类型列在源代码here中。

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

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)

Out:'这是我的描述'

print(page.tags["MicroManagerMetadata"].value)

输出:{'ChannelIndex':1,'Slice':5}

print(page.tags["ProcessingSoftware"].value)

输出:我的意大利面代码

对于内部使用,请尝试在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字符串。

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

I should be able to do this with a tif, right? Since it has a header?

没有

首先,你的假设是错误的,但那是个危险的想法。TIFF确实有一个头,但它不允许您在其中存储任意元数据。

但是TIFF是一种标记文件格式,是一系列不同类型的块,所以这里的头并不重要。而且您始终可以创建自己的私有块(任何ID>;32767),并在其中存储您想要的任何内容。

问题是,除了你自己的代码之外,什么都不知道你在那里存储了什么。因此,您可能希望存储EXIF或XMP或其他一些标准格式,以便用元数据扩展TIFF。但即使在那里,EXIF或任何你选择的东西都不会有“microse”的标签,所以最终你将不得不在某个字符串字段中存储类似“microse=george\nspam=eggs”的内容,然后自己解析它。

但真正的问题是PIL/枕头并不能给你一个简单的方法来存储EXIF或XMP或其他类似的东西。

首先,^{}不是用于任意额外数据的。在节省时间方面,它通常被忽略。

如果您查看TIFF的PIL文档,您将看到它将额外的数据读入一个特殊的属性Image.tag,并且可以通过向tiffinfo方法传递一个Image.save关键字参数来保存数据。但这些额外的数据是从TIFF标记id到二进制数据块的映射。您可以从未记录的PIL.ExifTags.TAGSdict(或通过自己在网上查找)获取Exif标记id,但这与PIL将为您提供的支持一样多。

另外,请注意,首先访问tag和使用tiffinfo需要Pillow的最新版本;旧版本和经典PIL不支持它。(具有讽刺意味的是,他们确实对JPG文件有部分EXIF支持,这些文件从未完成过,而且已经被删除……)此外,尽管似乎没有文档记录,但如果您构建的枕头没有libtiff,它似乎忽略了tiffinfo

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

  • 选择所需的元数据格式。
  • 使用与PIL/hellow不同的库来读写元数据。(例如,可以对EXIF使用GExiv2pyexif。)

相关问题 更多 >