コード例 #1
0
def _smooth_instance(image, radius):
    """Apply a median filter to smooth instance boundaries.

    Parameters
    ----------
    image : np.ndarray, np.int64 or bool
        Labelled or masked image with shape (y, x).
    radius : int
        Radius of the kernel for the median filter. The higher the smoother.

    Returns
    -------
    image_cleaned : np.ndarray, np.int64 or bool
        Cleaned image with shape (y, x).

    """
    # smooth instance boundaries for a binary mask
    if image.dtype == bool:
        image_cleaned = image.astype(np.uint8)
        image_cleaned = stack.median_filter(image_cleaned, "disk", radius)
        image_cleaned = image_cleaned.astype(bool)

    # smooth instance boundaries for a labelled image
    else:
        if image.max() <= 65535 and image.min() >= 0:
            image_cleaned = image.astype(np.uint16)
            image_cleaned = stack.median_filter(image_cleaned, "disk", radius)
            image_cleaned = image_cleaned.astype(np.int64)
        else:
            raise ValueError("Segmentation boundaries can't be smoothed "
                             "because more than 65535 has been detected in "
                             "the image. Smoothing is performed with 16-bit "
                             "unsigned integer images.")

    return image_cleaned
コード例 #2
0
def test_median_filter():
    # np.uint8
    filtered_x = stack.median_filter(x, kernel_shape="square", kernel_size=3)
    expected_x = np.array([[2, 2, 0, 0, 0], [2, 1, 0, 0, 0], [1, 1, 1, 0, 0],
                           [0, 0, 0, 0, 0], [0, 0, 1, 0, 0]],
                          dtype=np.uint8)
    assert_array_equal(filtered_x, expected_x)
    assert filtered_x.dtype == np.uint8

    # np.uint16
    filtered_x = stack.median_filter(x.astype(np.uint16),
                                     kernel_shape="square",
                                     kernel_size=3)
    expected_x = expected_x.astype(np.uint16)
    assert_array_equal(filtered_x, expected_x)
    assert filtered_x.dtype == np.uint16
コード例 #3
0
def cyt_watershed(relief, nuc_labelled, mask, smooth=None):
    """Apply watershed algorithm on the cytoplasm to segment cell instances.

    Parameters
    ----------
    relief : np.ndarray, np.uint
        Relief image of the cytoplasm with shape (y, x).
    nuc_labelled : np.ndarray, np.int64
        Result of the nuclei segmentation with shape (y, x).
    mask : np.ndarray, bool
        Binary mask of the cytoplasm with shape (y, x).
    smooth : int
        Smooth the final boundaries applying a median filter on the mask
        (kernel_size=smooth).

    Returns
    -------
    cyt_segmented_final : np.ndarray, np.int64
        Segmentation of the cytoplasm with instance differentiation and shape
        (y, x).

    """
    # TODO how to be sure nucleus label corresponds to cell label?
    # check parameters
    stack.check_array(relief,
                      ndim=2,
                      dtype=[np.uint8, np.uint16])
    stack.check_array(nuc_labelled,
                      ndim=2,
                      dtype=[np.uint8, np.uint16, np.int64])
    stack.check_array(mask,
                      ndim=2,
                      dtype=[bool])
    stack.check_parameter(smooth=(int, type(None)))

    # get markers
    markers = np.zeros_like(relief)
    for r in regionprops(nuc_labelled):
        markers[tuple(map(int, r.centroid))] = r.label
    markers = markers.astype(np.int64)

    # segment cytoplasm
    cyt_segmented = watershed(relief, markers, mask=mask)

    # smooth boundaries
    if smooth is not None:
        cyt_segmented = stack.median_filter(cyt_segmented.astype(np.uint16),
                                            kernel_shape="disk",
                                            kernel_size=smooth)
        cyt_segmented = remove_small_objects(cyt_segmented, 3000)
        cyt_segmented = cyt_segmented.astype(np.int64)

    # be sure to remove potential small disjoint part of the mask
    cyt_segmented_final = np.zeros_like(cyt_segmented)
    for id_cell in range(1, cyt_segmented.max() + 1):
        cell = cyt_segmented == id_cell
        cell_cc = label(cell)

        # one mask for the cell
        if cell_cc.max() == 1:
            mask = cell

        # multiple masks for the cell - we keep the larger one
        else:
            cell_properties = regionprops(cell_cc)
            m = 0
            mask = np.zeros_like(cyt_segmented).astype(bool)
            for cell_properties_ in cell_properties:
                area = cell_properties_.area
                if area > m:
                    m = area
                    mask = cell_cc == cell_properties_.label

        cyt_segmented_final[mask] = id_cell

    return cyt_segmented_final