示例#1
0
def filter_blend_z_membrane(a_membrane,
                            a_raw,
                            a_threshold,
                            a_exterior_mask,
                            kwargs,
                            df_thresholds,
                            p_out=None):
    """
    a_membrane = the binary membrane stack
    a_raw = the image stack (raw)
    a_threshold= the thresholded stack (=the otsu cutoff)
    a_exterior_mask = the exterior mask
    """
    a_peaks_flooded, d_log = locate_z_membrane(a_raw=a_raw,
                                               a_membrane_mask=np.where(
                                                   a_threshold, 0, 1),
                                               a_exterior_mask=a_exterior_mask,
                                               df_thresholds=df_thresholds,
                                               **kwargs)

    # z-membrane gets '3' as a value, just for ease of indentification
    a_membrane_blend_z = np.where(a_peaks_flooded, 3, a_membrane)
    # keep empty slices empty
    a_membrane_blend_z[np.sum(a_membrane, axis=(1, 2)) == 0] = 0

    if p_out:
        with warnings.catch_warnings():
            p_out.parent.mkdir(parents=True, exist_ok=True)
            imsave_fiji(p_out, a_membrane_blend_z.astype('uint16'))

    return a_membrane_blend_z, d_log
示例#2
0
def get_exterior_mask(a_stack, p_out=None, verbose=False):
    '''
    This filter will build a non-convex exterior mask based on the
    alpha-complex approach. After Delaunay triangulation, exterior
    triangles are filtered out by checking if their circumcenter falls
    inside the convex hull. The outline of the interior triangles is
    then retrieved and a mask is created This approach can be an
    alternative for the active contour, In theory the same approach
    could be applied in 3D, but runtime is a bottleneck given the
    large amount of circumcenters"""
    '''

    a_exterior_mask = np.zeros(a_stack.shape, dtype='uint16')

    prev_slice = None

    with warnings.catch_warnings():
        warnings.simplefilter("ignore")

        for ix_slice, a_slice in enumerate(a_stack):
            if not a_slice.any():
                a_exterior_mask[ix_slice] = a_slice
            try:
                a_points = _downsample_membrane_points(a_slice)
                a_circumcenters, a_circumradii, tri = _get_voronoi_points(
                    a_points)
                a_selector_inside_hull, hull = _test_points_inside_convex_hull(
                    a_check=a_circumcenters, a_points_hull=a_points)
                a_non_convex_hull_simplices = \
                    tri.simplices[a_selector_inside_hull]
                a_boundary_edges = _get_boundary_edges(
                    a_non_convex_hull_simplices)
                l_polygon_loop = _get_polygon_loop(a_boundary_edges,
                                                   verbose=False)
                # orders matters, has to be sequential outline of a polygon
                a_exterior_mask[ix_slice] = polygon2mask(
                    a_slice.shape, a_points[l_polygon_loop])
                prev_slice = a_exterior_mask[ix_slice]
            except Exception as e:
                # traceback.print_exc()
                if prev_slice is not None and prev_slice.any():
                    if verbose:
                        print(f"{ix_slice}<", end="")
                    a_exterior_mask[ix_slice] = prev_slice
                else:
                    if verbose:
                        print(f"{ix_slice}x", end="")
                    a_exterior_mask[ix_slice] = a_slice

    if p_out:
        with warnings.catch_warnings():
            p_out.parent.mkdir(parents=True, exist_ok=True)
            imsave_fiji(p_out, a_exterior_mask.astype('uint16'))

    return a_exterior_mask
示例#3
0
def filter_rescale(stack, kwargs, p_out=None):

    l_out = zoom_data(stack, verbose=False, **kwargs)
    img_rescaled, zoom, spacing = l_out

    if p_out:
        with warnings.catch_warnings():
            p_out.parent.mkdir(parents=True, exist_ok=True)
            imsave_fiji(p_out, img_rescaled.astype('uint16'))

    return img_rescaled, zoom
示例#4
0
def filter_remove_small_objects(a_stack, kwargs, p_out=None):
    '''
    Clean up : remove 3D blobs
    '''
    remove_small_objects(a_stack.astype(bool), in_place=True, **kwargs)

    if p_out:
        with warnings.catch_warnings():
            p_out.parent.mkdir(parents=True, exist_ok=True)
            imsave_fiji(p_out, a_stack.astype('uint16'))

    return a_stack
示例#5
0
def filter_frangi(a_stack, kwargs, scale_max=True, p_out=None):
    a_frangi = np.zeros(a_stack.shape, dtype='float32')

    for ix_slice, a_slice in enumerate(a_stack):
        a_frangi[ix_slice] = frangi(a_slice, **kwargs)

    if scale_max:
        if np.max(a_frangi) > 0:
            a_frangi = a_frangi * (10000 / np.max(a_frangi))

    if p_out:
        with warnings.catch_warnings():
            p_out.parent.mkdir(parents=True, exist_ok=True)
            imsave_fiji(p_out, a_frangi.astype('float32'))

    return a_frangi
示例#6
0
def filter_skeletonize(a_stack, p_out=None):
    '''
    skeletonize a binary image
    '''

    a_membrane = np.zeros(a_stack.shape, dtype='uint16')

    for ix_slice, a_slice in enumerate(a_stack):
        a_membrane[ix_slice] = skeletonize(a_slice)

    if p_out:
        with warnings.catch_warnings():
            p_out.parent.mkdir(parents=True, exist_ok=True)
            imsave_fiji(p_out, a_membrane.astype('uint16'))

    return a_membrane
示例#7
0
def filter_reconstruction(a_stack, df_thresholds, kwargs, p_out=None):
    '''
    This is a downhill filter. It expects as input the frangi output
    '''

    a_threshold = np.zeros(a_stack.shape, dtype='uint16')
    for ix_slice, a_slice in enumerate(a_stack):
        thresholds = df_thresholds.iloc[ix_slice]
        seed = a_slice.copy()
        if thresholds.has_signal:
            seed[seed < thresholds['abs_thresh_slice_seed']] = 0
            a_threshold[ix_slice] = reconstruction(
                seed=seed, mask=a_slice, **
                kwargs) >= thresholds['abs_thresh_slice']
        else:
            a_threshold[ix_slice] = np.zeros_like(a_slice)

    if p_out:
        with warnings.catch_warnings():
            p_out.parent.mkdir(parents=True, exist_ok=True)
            imsave_fiji(p_out, a_threshold.astype('uint16'))

    return a_threshold
示例#8
0
def smooth_exterior_mask(a_exterior_mask,
                         p_out=None,
                         weight_center=3,
                         weight_top_bottom=2,
                         weight_left_right=1):
    """ smooths an exterior mask (entire time lapse),
    by default it will smooth over time"""

    # print("...Smoothing the exterior mask...", flush=True)
    a_ext_mask_smoothed = np.zeros_like(a_exterior_mask)

    single_stack = True if len(a_exterior_mask.shape) == 3 else False

    if not single_stack:
        t_dim, z_dim, _, _ = a_exterior_mask.shape
    else:
        z_dim, _, _ = a_exterior_mask.shape
        t_dim = 1

    for t in range(t_dim):
        for z in range(z_dim):
            if single_stack:
                a_slice = a_exterior_mask[z, :]
            else:
                a_slice = a_exterior_mask[t, z, :]
            z_plus = 1 if z < z_dim - 1 else 0
            t_plus = 1 if t < t_dim - 1 else 0
            z_min = 1 if z > 0 else 0
            t_min = 1 if t > 0 else 0

            if single_stack:
                a_ext_mask_smoothed[z, :] \
                    = a_ext_mask_smoothed[z, :] + \
                    (a_slice * weight_center)
                a_ext_mask_smoothed[z - z_min, :] \
                    = a_ext_mask_smoothed[z - z_min, :] + \
                    (a_slice * weight_top_bottom)
                a_ext_mask_smoothed[z + z_plus, :] \
                    = a_ext_mask_smoothed[z + z_plus, :] +\
                    (a_slice * weight_top_bottom)
            else:
                a_ext_mask_smoothed[t, z, :] \
                    = a_ext_mask_smoothed[t, z, :] +\
                    (a_slice * weight_center)
                a_ext_mask_smoothed[t, z - z_min, :] \
                    = a_ext_mask_smoothed[t, z - z_min, :] +\
                    (a_slice * weight_top_bottom)
                a_ext_mask_smoothed[t, z + z_plus, :] \
                    = a_ext_mask_smoothed[t, z + z_plus, :] +\
                    (a_slice * weight_top_bottom)
                a_ext_mask_smoothed[t - t_min, z, :] \
                    = a_ext_mask_smoothed[t - t_min, z, :] +\
                    (a_slice * weight_left_right)
                a_ext_mask_smoothed[t + t_plus, z, :] \
                    = a_ext_mask_smoothed[t + t_plus, z, :] +\
                    (a_slice * weight_left_right)

    if single_stack:
        WEIGHT_THRESHOLD = (weight_center + 2 * (weight_top_bottom)) / 1.5
    else:
        WEIGHT_THRESHOLD = (weight_center + 2 * (weight_top_bottom) + 2 *
                            (weight_left_right)) / 1.5

    a_ext_mask_smoothed_binary = a_ext_mask_smoothed > WEIGHT_THRESHOLD

    if p_out:
        with warnings.catch_warnings():
            p_out.parent.mkdir(parents=True, exist_ok=True)
            imsave_fiji(p_out, a_ext_mask_smoothed_binary.astype('uint8'))

    return a_ext_mask_smoothed_binary