VisionLanguageGroup's picture
clean up
f10f497
"""
Copyright © 2025 Howard Hughes Medical Institute, Authored by Carsen Stringer , Michael Rariden and Marius Pachitariu.
"""
import os
import numpy as np
import cv2
import tifffile
import logging
from tqdm import tqdm
import re
try:
import nd2
ND2 = True
except:
ND2 = False
try:
import nrrd
NRRD = True
except:
NRRD = False
io_logger = logging.getLogger(__name__)
def load_dax(filename):
### modified from ZhuangLab github:
### https://github.com/ZhuangLab/storm-analysis/blob/71ae493cbd17ddb97938d0ae2032d97a0eaa76b2/storm_analysis/sa_library/datareader.py#L156
inf_filename = os.path.splitext(filename)[0] + ".inf"
if not os.path.exists(inf_filename):
io_logger.critical(
f"ERROR: no inf file found for dax file {filename}, cannot load dax without it"
)
return None
### get metadata
image_height, image_width = None, None
# extract the movie information from the associated inf file
size_re = re.compile(r"frame dimensions = ([\d]+) x ([\d]+)")
length_re = re.compile(r"number of frames = ([\d]+)")
endian_re = re.compile(r" (big|little) endian")
with open(inf_filename, "r") as inf_file:
lines = inf_file.read().split("\n")
for line in lines:
m = size_re.match(line)
if m:
image_height = int(m.group(2))
image_width = int(m.group(1))
m = length_re.match(line)
if m:
number_frames = int(m.group(1))
m = endian_re.search(line)
if m:
if m.group(1) == "big":
bigendian = 1
else:
bigendian = 0
# set defaults, warn the user that they couldn"t be determined from the inf file.
if not image_height:
io_logger.warning("could not determine dax image size, assuming 256x256")
image_height = 256
image_width = 256
### load image
img = np.memmap(filename, dtype="uint16",
shape=(number_frames, image_height, image_width))
if bigendian:
img = img.byteswap()
img = np.array(img)
return img
def imread(filename):
"""
Read in an image file with tif or image file type supported by cv2.
Args:
filename (str): The path to the image file.
Returns:
numpy.ndarray: The image data as a NumPy array.
Raises:
None
Raises an error if the image file format is not supported.
Examples:
>>> img = imread("image.tif")
"""
# ensure that extension check is not case sensitive
ext = os.path.splitext(filename)[-1].lower()
if ext == ".tif" or ext == ".tiff" or ext == ".flex":
with tifffile.TiffFile(filename) as tif:
ltif = len(tif.pages)
try:
full_shape = tif.shaped_metadata[0]["shape"]
except:
try:
page = tif.series[0][0]
full_shape = tif.series[0].shape
except:
ltif = 0
if ltif < 10:
img = tif.asarray()
else:
page = tif.series[0][0]
shape, dtype = page.shape, page.dtype
ltif = int(np.prod(full_shape) / np.prod(shape))
io_logger.info(f"reading tiff with {ltif} planes")
img = np.zeros((ltif, *shape), dtype=dtype)
for i, page in enumerate(tqdm(tif.series[0])):
img[i] = page.asarray()
img = img.reshape(full_shape)
return img
elif ext == ".dax":
img = load_dax(filename)
return img
elif ext == ".nd2":
if not ND2:
io_logger.critical("ERROR: need to 'pip install nd2' to load in .nd2 file")
return None
elif ext == ".nrrd":
if not NRRD:
io_logger.critical(
"ERROR: need to 'pip install pynrrd' to load in .nrrd file")
return None
else:
img, metadata = nrrd.read(filename)
if img.ndim == 3:
img = img.transpose(2, 0, 1)
return img
elif ext != ".npy":
try:
img = cv2.imread(filename, -1) #cv2.LOAD_IMAGE_ANYDEPTH)
if img.ndim > 2:
img = img[..., [2, 1, 0]]
return img
except Exception as e:
io_logger.critical("ERROR: could not read file, %s" % e)
return None
else:
try:
dat = np.load(filename, allow_pickle=True).item()
masks = dat["masks"]
return masks
except Exception as e:
io_logger.critical("ERROR: could not read masks from file, %s" % e)
return None
def imsave(filename, arr):
"""
Saves an image array to a file.
Args:
filename (str): The name of the file to save the image to.
arr (numpy.ndarray): The image array to be saved.
Returns:
None
"""
ext = os.path.splitext(filename)[-1].lower()
if ext == ".tif" or ext == ".tiff":
tifffile.imwrite(filename, data=arr, compression="zlib")
else:
if len(arr.shape) > 2:
arr = cv2.cvtColor(arr, cv2.COLOR_BGR2RGB)
cv2.imwrite(filename, arr)