Source code for ark.utils.masking_utils

import os
import numpy as np

from alpineer import io_utils, misc_utils, load_utils
from ark.utils import data_utils
from ark.segmentation.ez_seg.composites import composite_builder
from ark.segmentation.ez_seg.ez_object_segmentation import _create_object_mask
from ark import settings


[docs]def generate_signal_masks(img_dir, mask_dir, channels, mask_name, intensity_thresh_perc="auto", sigma=2, min_object_area=5000, max_hole_area=1000): """Creates a single signal mask for each FOV when given the channels to aggregate. Args: img_dir (str): path to the image tiff directory mask_dir (str): path where the masks will be saved channels (list): list of channels to combine to create a single mask for mask_name (str): name for the new mask file created intensity_thresh_perc (int): percentile to threshold intensity values in the image, defaults to "auto" which will calculate an appropriate percentile for the user sigma (float): sigma for gaussian blur min_object_area (int): minimum size of masked objects to include max_hole_area (int): maximum size of holes to leave in masked objects """ # check correct image directory path io_utils.validate_paths([img_dir]) fovs = io_utils.list_folders(img_dir) # check valid channel name channel_list = io_utils.remove_file_extensions( io_utils.list_files(os.path.join(img_dir, fovs[0]))) misc_utils.verify_in_list(input_channels=channels, all_channels=channel_list) # create composite image (or read in single image) composite_imgs = composite_builder( img_dir, img_sub_folder='', fov_list=fovs, images_to_add=channels, images_to_subtract=[], image_type='total', composite_method='total') for fov in fovs: # create mask img = composite_imgs[fov] img_size = img.shape[0] * img.shape[1] mask = _create_object_mask(img, 'blob', sigma, intensity_thresh_perc, max_hole_area, fov_dim=400, min_object_area=min_object_area, max_object_area=img_size) # save mask save_dir = os.path.join(mask_dir, fov) if not os.path.exists(save_dir): os.makedirs(save_dir) data_utils.save_fov_mask(mask_name, save_dir, mask)
[docs]def create_cell_mask(seg_mask, cell_table, fov_name, cell_types, cluster_col=settings.CELL_TYPE, sigma=10, min_object_area=0, max_hole_area=1000): """Generates a binary from the cells listed in `cell_types` Args: seg_mask (numpy.ndarray): segmentation mask cell_table (pandas.DataFrame): cell table containing segmentation IDs and cell types fov_name (str): name of the fov to process cell_types (list): list of cell types to include in the mask cluster_col (str): column in cell table containing cell cluster sigma (float): sigma for gaussian smoothing min_object_area (int): minimum size of object to include, default 0 max_hole_area (int): maximum size of a hole to leave without filling, default 0 Returns: numpy.ndarray: binary mask """ # get cell labels for fov and cell type cell_subset = cell_table[cell_table['fov'] == fov_name] cell_subset = cell_subset[cell_subset[cluster_col].isin(cell_types)] cell_labels = cell_subset['label'].values # create mask for cell type cell_mask = np.isin(seg_mask, cell_labels).astype(np.int32) img_size = cell_mask.shape[0] * cell_mask.shape[1] # binarize and blur mask, no minimum size requirement or hole removal for cell masks cell_mask = _create_object_mask(cell_mask, 'blob', sigma, None, max_hole_area, fov_dim=0, min_object_area=min_object_area, max_object_area=img_size) cell_mask[cell_mask > 0] = 1 return cell_mask
[docs]def generate_cell_masks(seg_dir, mask_dir, cell_table, cell_types, mask_name, cluster_col=settings.CELL_TYPE, sigma=10, min_object_area=0, max_hole_area=1000): """Creates a single cell mask for each FOV when given the cell types to aggregate. Args: seg_dir (str): path to the cell segmentation tiff directory mask_dir (str): path where the masks will be saved cell_table (pd.DataFrame): Dataframe containing all cell labels and their cell type cell_types (list): list of cell phenotypes that will be used to create the mask cluster_col (str): column in cell table containing cell cluster mask_name (str): name for the new mask file created sigma (float): sigma for gaussian smoothing min_object_area (int): minimum size of objects to include, default 0 max_hole_area (int): maximum size of a hole to leave without filling, default 0 """ fovs = np.unique(cell_table.fov) for fov in fovs: seg_mask = load_utils.load_imgs_from_dir( data_dir=seg_dir, files=[fov + '_whole_cell.tiff'], xr_dim_name='compartments', xr_channel_names=['whole_cell'] ) # create mask mask = create_cell_mask( np.array(seg_mask[0, :, :, 0]), cell_table, fov, cell_types, cluster_col, sigma, min_object_area, max_hole_area) # save mask save_dir = os.path.join(mask_dir, fov) os.makedirs(save_dir, exist_ok=True) data_utils.save_fov_mask(mask_name, save_dir, mask)