Skip to content

Instantly share code, notes, and snippets.

@kaczmarj
Created February 13, 2023 23:47
Show Gist options
  • Save kaczmarj/0a706118764e0df73f7a5ba25eb05dfb to your computer and use it in GitHub Desktop.
Save kaczmarj/0a706118764e0df73f7a5ba25eb05dfb to your computer and use it in GitHub Desktop.
Repair TIFF image metadata that have MPP in XResolution and YResolution fields.
"""Repair the TIFF metadata for images where XResolution and YResolution contain MPP.
This script updates the following tags:
- ResolutionUnit --> to centimeter
- XResolution --> from mppx to pixels per centimeter in x dimension
- YResolution --> from mppy to pixels per centimeter in y dimension
"""
import argparse
from pathlib import Path
from typing import Tuple
import tifftools
def get_mpp(path: str) -> Tuple[float, float]:
"""Return tuple of (mpp_x, mpp_y).
MPP = micrometers per pixel.
"""
info = tifftools.read_tiff(path)
# [1490525311, 4294967295] --> 0.34703997
xs = info["ifds"][0]["tags"][int(tifftools.Tag.XRESOLUTION)]["data"]
ys = info["ifds"][0]["tags"][int(tifftools.Tag.YRESOLUTION)]["data"]
assert len(xs) == 2
assert len(ys) == 2
mpp_x = xs[0] / xs[1]
mpp_y = ys[0] / ys[1]
return mpp_x, mpp_y
def mpp_to_resolution_cm(mpp: float):
# (pixel / microns) * (microns / centimeter)
# 10_000 microns per centimeter.
return 1 / mpp * 10_000
def repair(path: str, output_dir: str):
"""Repair the resolution metadata and write to 'output_dir' with the same name as
the original file.
"""
output = Path(output_dir) / Path(path).name
mppx, mppy = get_mpp(path)
print(f"{Path(path).name}\tmppx={mppx}\tmppy={mppy}")
if mppx > 1 or mppy > 1:
raise ValueError(
f"MPP_X and/or MPP_Y are greater than 1: {mppx} and {mppy}. They probably"
" do not represent microns per pixel."
)
xresolution = mpp_to_resolution_cm(mppx)
yresolution = mpp_to_resolution_cm(mppy)
tifftools.tiff_set(
path,
output,
overwrite=False,
setlist=[
(
tifftools.Tag.RESOLUTIONUNIT,
tifftools.constants.ResolutionUnit.CENTIMETER.value,
),
(tifftools.Tag.XRESOLUTION, xresolution),
(tifftools.Tag.YRESOLUTION, yresolution),
],
)
if __name__ == "__main__":
p = argparse.ArgumentParser()
p.add_argument("--output-dir", required=True, help="Path to output directory.")
p.add_argument("tiff", help="Path to input TIFF file.")
args = p.parse_args()
repair(path=args.tiff, output_dir=args.output_dir)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment