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