synapse_net.inference.postprocessing.vesicles
1import numpy as np 2 3from scipy.ndimage import binary_closing 4from skimage.measure import regionprops 5from tqdm import tqdm 6 7 8def close_holes(vesicle_segmentation, closing_iterations=4, min_size=0, verbose=False): 9 assert vesicle_segmentation.ndim == 3 10 props = regionprops(vesicle_segmentation) 11 closed_segmentation = np.zeros_like(vesicle_segmentation) 12 13 for prop in tqdm(props, desc="Close holes in segmentation", disable=not verbose): 14 if prop.area < min_size: 15 continue 16 bb = prop.bbox 17 bb = tuple(slice(beg, end) for beg, end in zip(bb[:3], bb[3:])) 18 mask = vesicle_segmentation[bb] == prop.label 19 closed_mask = np.logical_or(binary_closing(mask, iterations=closing_iterations), mask) 20 closed_segmentation[bb][closed_mask] = prop.label 21 22 return closed_segmentation 23 24 25def filter_border_objects(segmentation: np.ndarray, z_border_only: bool = False) -> np.ndarray: 26 """Filter any object that touches one of the volume borders. 27 28 Args: 29 segmentation: The input segmentation. 30 z_border_only: Whether to only filter the objects that touch the depth axis border (True) 31 or to filter all objects touching an image borhder (False). 32 33 Returns: 34 The filtered segmentation. 35 """ 36 props = regionprops(segmentation) 37 38 filter_ids = [] 39 for prop in props: 40 bbox = np.array(prop.bbox) 41 if z_border_only: 42 z_start, z_stop = bbox[0], bbox[3] 43 if z_start == 0 or z_stop == segmentation.shape[0]: 44 filter_ids.append(prop.label) 45 else: 46 start, stop = bbox[:3], bbox[3:] 47 if (start == 0).any() or (stop == np.array(segmentation.shape)).any(): 48 filter_ids.append(prop.label) 49 50 segmentation[np.isin(segmentation, filter_ids)] = 0 51 return segmentation 52 53 54def filter_border_vesicles(vesicle_segmentation, seg_ids=None, border_slices=4): 55 props = regionprops(vesicle_segmentation) 56 57 filtered_ids = [] 58 for prop in tqdm(props, desc="Filter vesicles at the tomogram border"): 59 seg_id = prop.label 60 if (seg_ids is not None) and (seg_id not in seg_ids): 61 continue 62 63 bb = prop.bbox 64 bb = tuple(slice(beg, end) for beg, end in zip(bb[:3], bb[3:])) 65 mask = vesicle_segmentation[bb] == seg_id 66 67 # Compute the mass per slice. Only keep the vesicle if the maximum of the mass is central. 68 mass_per_slice = [m.sum() for m in mask] 69 max_slice = np.argmax(mass_per_slice) 70 if (max_slice >= border_slices) and (max_slice < mask.shape[0] - border_slices): 71 filtered_ids.append(seg_id) 72 73 # print(len(filtered_ids), "/", len(seg_ids)) 74 return filtered_ids
def
close_holes( vesicle_segmentation, closing_iterations=4, min_size=0, verbose=False):
9def close_holes(vesicle_segmentation, closing_iterations=4, min_size=0, verbose=False): 10 assert vesicle_segmentation.ndim == 3 11 props = regionprops(vesicle_segmentation) 12 closed_segmentation = np.zeros_like(vesicle_segmentation) 13 14 for prop in tqdm(props, desc="Close holes in segmentation", disable=not verbose): 15 if prop.area < min_size: 16 continue 17 bb = prop.bbox 18 bb = tuple(slice(beg, end) for beg, end in zip(bb[:3], bb[3:])) 19 mask = vesicle_segmentation[bb] == prop.label 20 closed_mask = np.logical_or(binary_closing(mask, iterations=closing_iterations), mask) 21 closed_segmentation[bb][closed_mask] = prop.label 22 23 return closed_segmentation
def
filter_border_objects( segmentation: numpy.ndarray, z_border_only: bool = False) -> numpy.ndarray:
26def filter_border_objects(segmentation: np.ndarray, z_border_only: bool = False) -> np.ndarray: 27 """Filter any object that touches one of the volume borders. 28 29 Args: 30 segmentation: The input segmentation. 31 z_border_only: Whether to only filter the objects that touch the depth axis border (True) 32 or to filter all objects touching an image borhder (False). 33 34 Returns: 35 The filtered segmentation. 36 """ 37 props = regionprops(segmentation) 38 39 filter_ids = [] 40 for prop in props: 41 bbox = np.array(prop.bbox) 42 if z_border_only: 43 z_start, z_stop = bbox[0], bbox[3] 44 if z_start == 0 or z_stop == segmentation.shape[0]: 45 filter_ids.append(prop.label) 46 else: 47 start, stop = bbox[:3], bbox[3:] 48 if (start == 0).any() or (stop == np.array(segmentation.shape)).any(): 49 filter_ids.append(prop.label) 50 51 segmentation[np.isin(segmentation, filter_ids)] = 0 52 return segmentation
Filter any object that touches one of the volume borders.
Arguments:
- segmentation: The input segmentation.
- z_border_only: Whether to only filter the objects that touch the depth axis border (True) or to filter all objects touching an image borhder (False).
Returns:
The filtered segmentation.
def
filter_border_vesicles(vesicle_segmentation, seg_ids=None, border_slices=4):
55def filter_border_vesicles(vesicle_segmentation, seg_ids=None, border_slices=4): 56 props = regionprops(vesicle_segmentation) 57 58 filtered_ids = [] 59 for prop in tqdm(props, desc="Filter vesicles at the tomogram border"): 60 seg_id = prop.label 61 if (seg_ids is not None) and (seg_id not in seg_ids): 62 continue 63 64 bb = prop.bbox 65 bb = tuple(slice(beg, end) for beg, end in zip(bb[:3], bb[3:])) 66 mask = vesicle_segmentation[bb] == seg_id 67 68 # Compute the mass per slice. Only keep the vesicle if the maximum of the mass is central. 69 mass_per_slice = [m.sum() for m in mask] 70 max_slice = np.argmax(mass_per_slice) 71 if (max_slice >= border_slices) and (max_slice < mask.shape[0] - border_slices): 72 filtered_ids.append(seg_id) 73 74 # print(len(filtered_ids), "/", len(seg_ids)) 75 return filtered_ids