Beispiel #1
0
def test_log_filter():
    # float64
    y_float64 = stack.cast_img_float64(y)
    filtered_y_float64 = stack.log_filter(y_float64, 2)
    expected_y_float64 = np.array(
        [[0., 0., 0.02995949, 0.06212277, 0.07584532],
         [0., 0., 0.02581818, 0.05134284, 0.06123539],
         [0., 0., 0.01196859, 0.0253716, 0.02853162], [0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0.]],
        dtype=np.float64)
    assert_allclose(filtered_y_float64, expected_y_float64, rtol=1e-6)
    assert filtered_y_float64.dtype == np.float64

    # float32
    y_float32 = stack.cast_img_float32(y)
    filtered_y = stack.log_filter(y_float32, 2)
    expected_y = stack.cast_img_float32(expected_y_float64)
    assert_allclose(filtered_y, expected_y, rtol=1e-6)
    assert filtered_y.dtype == np.float32

    # uint8
    filtered_y = stack.log_filter(y, 2)
    expected_y = stack.cast_img_uint8(expected_y_float64)
    assert_array_equal(filtered_y, expected_y)
    assert filtered_y.dtype == np.uint8

    # uint16
    y_uint16 = stack.cast_img_uint16(y)
    filtered_y = stack.log_filter(y_uint16, 2)
    expected_y = stack.cast_img_uint16(expected_y_float64)
    assert_array_equal(filtered_y, expected_y)
    assert filtered_y.dtype == np.uint16
Beispiel #2
0
def test_cast_float64(dtype):
    # from integer to np.float64
    if np.issubdtype(dtype, np.integer):
        x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
        tensor = np.array(x).reshape((3, 3)).astype(dtype)
        tensor[0, 0] = np.iinfo(dtype).min
        tensor[2, 2] = np.iinfo(dtype).max

    # from float to np.float64
    else:
        x = [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6], [0.7, 0.8, 1.0]]
        tensor = np.array(x).reshape((3, 3)).astype(dtype)

    # cast in float64
    tensor_float64 = stack.cast_img_float64(tensor)
    assert tensor_float64.dtype == np.float64

    # check value
    if dtype in [np.uint8, np.uint16, np.uint32, np.uint64]:
        assert tensor_float64.min() == 0
        assert tensor_float64.max() == 1
    elif dtype in [np.int8, np.int16, np.int32, np.int64]:
        assert tensor_float64.min() == -1
        assert tensor_float64.max() == 1
    else:
        assert_array_almost_equal(tensor_float64, tensor)
Beispiel #3
0
def test_cast_float64(dtype):
    # from integer to np.float64
    if np.issubdtype(dtype, np.integer):
        x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
        tensor = np.array(x).reshape((3, 3)).astype(dtype)
        tensor[2, 2] = np.iinfo(dtype).max

    # from float to np.float64
    else:
        x = [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6], [0.7, 0.8, 1.0]]
        tensor = np.array(x).reshape((3, 3)).astype(dtype)

    # cast in float64
    tensor_float64 = stack.cast_img_float64(tensor)
    assert tensor_float64.dtype == np.float64
Beispiel #4
0
def test_gaussian_filter():
    # float64
    y_float64 = stack.cast_img_float64(y)
    filtered_y_float64 = stack.gaussian_filter(y_float64, 2)
    expected_y_float64 = np.array(
        [[0.08928096, 0.1573019, 0.22897881, 0.28086597, 0.3001061],
         [0.08668051, 0.14896399, 0.21282558, 0.25752308, 0.27253406],
         [0.07634613, 0.12664142, 0.17574502, 0.20765944, 0.2155001],
         [0.05890843, 0.09356377, 0.12493327, 0.1427122, 0.14374558],
         [0.03878372, 0.05873308, 0.07492625, 0.08201409, 0.07939603]],
        dtype=np.float64)
    assert_allclose(filtered_y_float64, expected_y_float64, rtol=1e-6)
    assert filtered_y_float64.dtype == np.float64

    # float32
    y_float32 = stack.cast_img_float32(y)
    filtered_y = stack.gaussian_filter(y_float32, 2)
    expected_y = stack.cast_img_float32(expected_y_float64)
    assert_allclose(filtered_y, expected_y, rtol=1e-6)
    assert filtered_y.dtype == np.float32

    # uint8
    with pytest.raises(ValueError):
        stack.gaussian_filter(y, 2, allow_negative=True)
    filtered_y = stack.gaussian_filter(y, 2)
    expected_y = stack.cast_img_uint8(expected_y_float64)
    assert_array_equal(filtered_y, expected_y)
    assert filtered_y.dtype == np.uint8

    # uint16
    y_uint16 = stack.cast_img_uint16(y)
    with pytest.raises(ValueError):
        stack.gaussian_filter(y_uint16, 2, allow_negative=True)
    filtered_y = stack.gaussian_filter(y_uint16, 2)
    expected_y = stack.cast_img_uint16(expected_y_float64)
    assert_array_equal(filtered_y, expected_y)
    assert filtered_y.dtype == np.uint16
Beispiel #5
0
def test_background_removal_gaussian():
    # float64
    y_float64 = stack.cast_img_float64(y)
    filtered_y_float64 = stack.remove_background_gaussian(y_float64, 2)
    expected_y_float64 = np.array(
        [[0., 0., 0.01415845, 0.36227129, 0.],
         [0., 0., 0.25776265, 0.66404555, 0.43726986],
         [0., 0., 0.11052949, 0.59626213, 0.], [0., 0.42016172, 0., 0., 0.],
         [0., 0., 0., 0., 0.]],
        dtype=np.float64)
    assert_allclose(filtered_y_float64, expected_y_float64, rtol=1e-6)
    assert filtered_y_float64.dtype == np.float64

    # float32
    y_float32 = stack.cast_img_float32(y)
    filtered_y = stack.remove_background_gaussian(y_float32, 2)
    expected_y = stack.cast_img_float32(expected_y_float64)
    assert_allclose(filtered_y, expected_y, rtol=1e-6)
    assert filtered_y.dtype == np.float32

    # uint8
    with pytest.raises(ValueError):
        stack.gaussian_filter(y, 2, allow_negative=True)
    filtered_y = stack.remove_background_gaussian(y, 2)
    expected_y = stack.cast_img_uint8(expected_y_float64)
    assert_array_equal(filtered_y, expected_y)
    assert filtered_y.dtype == np.uint8

    # uint16
    y_uint16 = stack.cast_img_uint16(y)
    with pytest.raises(ValueError):
        stack.gaussian_filter(y_uint16, 2, allow_negative=True)
    filtered_y = stack.remove_background_gaussian(y_uint16, 2)
    expected_y = stack.cast_img_uint16(expected_y_float64)
    assert_array_equal(filtered_y, expected_y)
    assert filtered_y.dtype == np.uint16
Beispiel #6
0
def get_watershed_relief(image, nuc_label, alpha):
    """Build a representation of cells as watershed.

    In a watershed algorithm we consider cells as watershed to be flooded. The
    watershed relief is inversely proportional to both the pixel intensity and
    the closeness to nuclei. Pixels with a high intensity or close to labelled
    nuclei have a low watershed relief value. They will be flooded in priority.
    Flooding the watersheds allows to propagate nuclei labels through potential
    cytoplasm areas. The lines separating watershed are the final segmentation
    of the cells.

    Parameters
    ----------
    image : np.ndarray, np.uint
        Cells image with shape (z, y, x) or (y, x).
    nuc_label : np.ndarray, np.int64
        Result of the nuclei segmentation with shape (y, x) and nuclei
        instances labelled.
    alpha : float or int
        Weight of the pixel intensity values to compute the relief.

    Returns
    -------
    watershed_relief : np.ndarray, np.uint16
        Watershed representation of cells with shape (y, x).

    """
    # check parameters
    stack.check_array(image,
                      ndim=[2, 3],
                      dtype=[np.uint8, np.uint16])
    stack.check_array(nuc_label, ndim=2, dtype=np.int64)
    stack.check_parameter(alpha=(int, float))

    # use pixel intensity of the cells image
    if alpha == 1:
        # if a 3-d image is provided we sum its pixel values
        image = stack.cast_img_float64(image)
        if image.ndim == 3:
            image = image.sum(axis=0)
        # rescale image
        image = stack.rescale(image)
        # build watershed relief
        watershed_relief = image.max() - image
        watershed_relief[nuc_label > 0] = 0
        watershed_relief = np.true_divide(watershed_relief,
                                          watershed_relief.max(),
                                          dtype=np.float64)
        watershed_relief = stack.cast_img_uint16(watershed_relief,
                                                 catch_warning=True)

    # use distance from the nuclei
    elif alpha == 0:
        # build watershed relief
        nuc_mask = nuc_label > 0
        watershed_relief = ndi.distance_transform_edt(~nuc_mask)
        watershed_relief = np.true_divide(watershed_relief,
                                          watershed_relief.max(),
                                          dtype=np.float64)
        watershed_relief = stack.cast_img_uint16(watershed_relief,
                                                 catch_warning=True)

    # use a combination of both previous methods
    elif 0 < alpha < 1:
        # if a 3-d image is provided we sum its pixel values
        image = stack.cast_img_float64(image)
        if image.ndim == 3:
            image = image.sum(axis=0)
        # rescale image
        image = stack.rescale(image)
        # build watershed relief
        relief_pixel = image.max() - image
        relief_pixel[nuc_label > 0] = 0
        relief_pixel = np.true_divide(relief_pixel,
                                      relief_pixel.max(),
                                      dtype=np.float64)
        nuc_mask = nuc_label > 0
        relief_distance = ndi.distance_transform_edt(~nuc_mask)
        relief_distance = np.true_divide(relief_distance,
                                         relief_distance.max(),
                                         dtype=np.float64)
        watershed_relief = alpha * relief_pixel + (1 - alpha) * relief_distance
        watershed_relief = stack.cast_img_uint16(watershed_relief,
                                                 catch_warning=True)

    else:
        raise ValueError("Parameter 'alpha' is wrong. It must be comprised "
                         "between 0 and 1. Currently 'alpha' is {0}"
                         .format(alpha))

    return watershed_relief