Created
February 13, 2023 23:47
-
-
Save kaczmarj/0a706118764e0df73f7a5ba25eb05dfb to your computer and use it in GitHub Desktop.
Repair TIFF image metadata that have MPP in XResolution and YResolution fields.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""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