Beispiel #1
0
def remove_large_objects(ar, max_size=128, connectivity=1):
    if max_size == -1:  # shortcut for efficiency
        return ar

    out = ar.copy()

    if out.dtype == bool:
        selem = generate_binary_structure(ar.ndim, connectivity)
        ccs = np.zeros_like(ar, dtype=np.int32)
        label_image(ar, selem, output=ccs)
    else:
        ccs = out

    try:
        component_sizes = np.bincount(ccs.ravel())
    except ValueError:
        raise ValueError("Negative value labels are not supported. Try "
                         "relabeling the input with `scipy.ndimage.label` or "
                         "`skimage.morphology.label`.")

    too_big = component_sizes > max_size
    too_big_mask = too_big[ccs]
    out[too_big_mask] = 0

    return out
def find_big_ones_clusters(bin_mask,
                           min_cluster_length=None,
                           min_cluster_order=None):
    labeled_mask, _ = label_image(bin_mask)
    cluster_labels, cluster_sizes = np.unique(labeled_mask,
                                               return_counts=True)

    # sort from max to min
    sorted_indexes = np.flip(cluster_sizes.argsort())
    cluster_sizes = cluster_sizes[sorted_indexes]
    cluster_labels = cluster_labels[sorted_indexes]

    min_cluster_length = cluster_sizes[min_cluster_order] if min_cluster_order else min_cluster_length
    big_clusters_indexes = cluster_sizes > min_cluster_length

    big_ones_cluster_labels = cluster_labels[big_clusters_indexes]

    #  TODO:refactor this part
    contour_mask = np.zeros(bin_mask.shape, dtype=bool)
    for label in big_ones_cluster_labels:
        if label == 0:
            continue
        contour_mask = np.logical_or(contour_mask, _create_mask_layer_for_label(labeled_mask, label))

    return contour_mask
Beispiel #3
0
def find_mask_longest_contours(bin_img_with_contours,
                               filter_by_contour_length=False,
                               max_number_of_contours=None,
                               min_contour_length=None):
    labeled_img, _ = label_image(bin_img_with_contours)
    unique_labels, unique_counts = np.unique(labeled_img, return_counts=True)

    longest_contours_indexes = np.flip(unique_counts.argsort())

    if not filter_by_contour_length:
        if len(longest_contours_indexes) < max_number_of_contours:
            max_number_of_contours = len(longest_contours_indexes)
        longest_contours_labels = unique_labels[longest_contours_indexes][
            0:max_number_of_contours]
    else:
        longest_contours_lens = unique_counts[longest_contours_indexes][
            0:max_number_of_contours]
        longest_contours_lens_lower_max = longest_contours_lens > min_contour_length
        longest_contours_indexes_sampled = longest_contours_indexes[
            longest_contours_lens_lower_max]
        longest_contours_labels = unique_labels[
            longest_contours_indexes_sampled]

    # print("number of selected contour: ", len(longest_contours_labels))
    contour_mask = np.zeros(labeled_img.shape, dtype=bool)
    for label in longest_contours_labels:
        if label == 0:
            continue
        contour_mask = np.logical_or(
            contour_mask, _create_mask_layer_for_label(labeled_img, label))
    return contour_mask
def _apply_convective_criterion4(convective_flag_matrix, min_size_pixels):
    """Applies criterion 4 for convective classification.

    Criterion 4 states: if pixel (i, j) is marked convective but is not part of
    a connected region with size of >= K pixels, (i, j) is not actually
    convective.

    :param convective_flag_matrix: M-by-N numpy array of Boolean flags (True
        if convective, False if not).
    :param min_size_pixels: Minimum size of connected region.
    :return: convective_flag_matrix: Updated version of input.
    """

    region_id_matrix = label_image(convective_flag_matrix.astype(int),
                                   structure=numpy.full((3, 3), 1.))[0]
    num_regions = numpy.max(region_id_matrix)

    for i in range(num_regions):
        these_indices = numpy.where(region_id_matrix == i + 1)
        if len(these_indices[0]) >= min_size_pixels:
            continue

        convective_flag_matrix[these_indices] = False

    return convective_flag_matrix
Beispiel #5
0
def get_pore_volume_distribution(levitatting_volume, structure_neighbors_num):
    structure = get_structure(neighbors_num=structure_neighbors_num)
    if levitatting_volume.ndim == 2:
        structure = structure[1]
    connected_components, _ = label_image(levitatting_volume, structure)
    pore_volume_distribution = np.unique(connected_components,
                                         return_counts=True)[1][1:]

    return pore_volume_distribution
Beispiel #6
0
def get_sparse_masks(
        segmented_img: np.ndarray,
        raw_img_shape: tuple,
        edge_method: str,
        selem: int,
        transpose=True
    ) -> np.ndarray:
    # allocate array with same size as the raw input image
    # so that the dims match for CNMF
    img = np.zeros(raw_img_shape, dtype=segmented_img.dtype)

    # fill the allocated array with vals from the NuSeT segmentation
    # sometimes the segmented image has its dims trimmed by a few pixels
    if len(raw_img_shape) == 3:
        img[:, :segmented_img.shape[1], :segmented_img.shape[2]] = segmented_img
        struc = np.array(
            [[[0, 0, 0],
              [0, 0, 0],
              [0, 0, 0]],
             [[1, 1, 1],
              [1, 1, 1],
              [1, 1, 1]],
             [[0, 0, 0],
              [0, 0, 0],
              [0, 0, 0]]]
        )

    else:
        img[:segmented_img.shape[0], :segmented_img.shape[1]] = segmented_img
        struc = None

    areas = label_image(img, structure=struc)
    # A = np.zeros((np.prod(img.shape), areas[1]), dtype=bool)

    selem: np.array = np.ones((selem,)*len(segmented_img.shape))

    if areas[1] < 50:
        print("Less than 50 regions, not parallelizing")
        sparses = []
        for i in tqdm(range(areas[1])):
            sparses.append(
                _get_sparse_mask(areas, i, edge_method, selem)
            )
    else:
        print("Greater than 50 regions, parallelizing with joblib")
        sparses = Parallel(n_jobs=cpu_count(), verbose=5)(
            delayed(_get_sparse_mask)(areas, i, edge_method, selem) for i in range(areas[1])
        )

    if transpose:
        return scipy.sparse.vstack(sparses).T.toarray()
    else:
        return scipy.sparse.vstack(sparses).toarray()
Beispiel #7
0
def get_closed_pores(bin_3d_img, structure_neighbors_num=6):
    """
    function returns a bin_3d_img of closed pores for the
    chosen neighbor voxels configuration

    """
    if not np.asarray(bin_3d_img).dtype == bool:
        bin_3d_img = bin_3d_img.astype(bool)

    structure = get_structure(structure_neighbors_num)
    connected_components, _ = label_image(bin_3d_img, structure)
    levitating_volume = clear_border(connected_components) > 0

    return levitating_volume
Beispiel #8
0
def filter_pores_mask(pore_mask_img, lowest_value, highest_value=None):
    labeled_img, _ = label_image(pore_mask_img)
    unique_labels, unique_counts = np.unique(labeled_img, return_counts=True)

    if highest_value == None:
        highest_value = np.max(unique_counts) + 1
    accepted_labels = unique_labels[np.logical_and(
        unique_labels > 0, unique_counts < highest_value,
        unique_counts > lowest_value)]

    mask = np.zeros(pore_mask_img.shape)
    for elem in accepted_labels:
        # TODO: replace with _create_mask_layer_for_label
        mask += np.where(elem == labeled_img, True, False)
    return mask