Adding image converter
This commit is contained in:
122
src/utils/image_converters.py
Normal file
122
src/utils/image_converters.py
Normal file
@@ -0,0 +1,122 @@
|
||||
import numpy as np
|
||||
|
||||
from roifile import ImagejRoi
|
||||
from tifffile import TiffFile, TiffWriter
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class UT:
|
||||
"""
|
||||
Docstring for UT
|
||||
|
||||
Operetta files along with rois drawn in ImageJ
|
||||
"""
|
||||
|
||||
def __init__(self, roifile_fn: Path):
|
||||
self.roifile_fn = roifile_fn
|
||||
self.rois = ImagejRoi.fromfile(self.roifile_fn)
|
||||
self.stem = self.roifile_fn.stem.strip("-RoiSet")
|
||||
self.image, self.image_props = self._load_images()
|
||||
|
||||
def _load_images(self):
|
||||
"""Loading sequence of tif files
|
||||
array sequence is CZYX
|
||||
"""
|
||||
print(self.roifile_fn.parent, self.stem)
|
||||
fns = list(self.roifile_fn.parent.glob(f"{self.stem}*.tif*"))
|
||||
stems = [fn.stem.split(self.stem)[-1] for fn in fns]
|
||||
n_ch = len(set([stem.split("-ch")[-1].split("t")[0] for stem in stems]))
|
||||
n_p = len(set([stem.split("-")[0] for stem in stems]))
|
||||
n_t = len(set([stem.split("t")[1] for stem in stems]))
|
||||
print(n_ch, n_p, n_t)
|
||||
|
||||
with TiffFile(fns[0]) as tif:
|
||||
img = tif.asarray()
|
||||
w, h = img.shape
|
||||
dtype = img.dtype
|
||||
self.image_props = {
|
||||
"channels": n_ch,
|
||||
"planes": n_p,
|
||||
"tiles": n_t,
|
||||
"width": w,
|
||||
"height": h,
|
||||
"dtype": dtype,
|
||||
}
|
||||
|
||||
image_stack = np.zeros((n_ch, n_p, w, h), dtype=dtype)
|
||||
for fn in fns:
|
||||
with TiffFile(fn) as tif:
|
||||
img = tif.asarray()
|
||||
stem = fn.stem.split(self.stem)[-1]
|
||||
ch = int(stem.split("-ch")[-1].split("t")[0])
|
||||
p = int(stem.split("-")[0].lstrip("p"))
|
||||
t = int(stem.split("t")[1])
|
||||
print(fn.stem, "ch", ch, "p", p, "t", t)
|
||||
image_stack[ch - 1, p - 1] = img
|
||||
|
||||
print(image_stack.shape)
|
||||
|
||||
return image_stack, self.image_props
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
return self.image_props["width"]
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
return self.image_props["height"]
|
||||
|
||||
@property
|
||||
def nchannels(self):
|
||||
return self.image_props["channels"]
|
||||
|
||||
@property
|
||||
def nplanes(self):
|
||||
return self.image_props["planes"]
|
||||
|
||||
def export_rois(
|
||||
self,
|
||||
path: Path,
|
||||
subfolder: str = "labels",
|
||||
class_index: int = 0,
|
||||
):
|
||||
"""Export rois to a file"""
|
||||
with open(path / subfolder / f"{self.stem}.txt", "w") as f:
|
||||
for roi in self.rois:
|
||||
# TODO add image coordinates normalization
|
||||
coords = ""
|
||||
for x, y in roi.subpixel_coordinates:
|
||||
coords += f"{x/self.width} {y/self.height}"
|
||||
f.write(f"{class_index} {coords}\n")
|
||||
|
||||
return
|
||||
|
||||
def export_image(
|
||||
self,
|
||||
path: Path,
|
||||
subfolder: str = "images",
|
||||
plane_mode: str = "max projection",
|
||||
channel: int = 0,
|
||||
):
|
||||
"""Export image to a file"""
|
||||
|
||||
if plane_mode == "max projection":
|
||||
self.image = np.max(self.image[channel], axis=0)
|
||||
print(self.image.shape)
|
||||
|
||||
with TiffWriter(path / subfolder / f"{self.stem}.tif") as tif:
|
||||
tif.write(self.image)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("input", type=Path)
|
||||
parser.add_argument("output", type=Path)
|
||||
args = parser.parse_args()
|
||||
|
||||
for rfn in args.input.glob("*.zip"):
|
||||
ut = UT(rfn)
|
||||
ut.export_rois(args.output, class_index=0)
|
||||
ut.export_image(args.output, plane_mode="max projection", channel=0)
|
||||
Reference in New Issue
Block a user