What is the best way to save image metadata alongside a tif?

Viewed 12603

In my work as a grad student, I capture microscope images and use python to save them as raw tif's. I would like to add metadata such as the name of the microscope I am using, the magnification level, and the imaging laser wavelength. These details are all important for how I post-process the images.

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

I was able to add to the info in a PIL image:

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

but when I save and load that image, the info I added is gone.

I'm open to all suggestions. If I have too, I'll just save a separate .txt file with the metadata, but it would be really nice to have it embedded in the image.

4 Answers

Tifffile is one option for saving microscopy images with lots of metadata in python.

It doesn't have a lot of external documentation, but the docstings are great so you can get a lot of info just by typing help(tifffile) in python, or go look at the source code.

You can look at the TiffWriter.save function in the source code (line 750) for the different keyword arguments you can use to write metadata.

One is to use description, which accepts a string. It will show up as the tag "ImageDescription" when you read your image.

Another is to use the extratags argument, which accepts a list of tuples. That allows you to write any tag name that exist in TIFF.TAGS(). One of the easiest way is to write them as strings because then you don't have to specify length.

You can also write ImageJ metadata with ijmetadata, for which the acceptable types are listed in the source code here.

As an example, if you write the following:

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

You can see the following tags when you read the image:

frames = tifffile.TiffFile(save_name)
page = frames.pages[0]
print(page.tags["ImageDescription"].value)

Out: 'this is my description'

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

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

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

Out: my_spaghetti_code

Related