def _ripley_values_2d(radii, rna_coord, mask_cyt): rna_coord_2d = rna_coord[:, 1:3] # sort rna coordinates sorted_indices = np.lexsort((rna_coord_2d[:, 1], rna_coord_2d[:, 0])) rna_coord_2d_sorted = rna_coord_2d[sorted_indices] # compute distance matrix between rna and rna density distances = distance_matrix(rna_coord_2d_sorted, rna_coord_2d_sorted, p=2) factor = len(rna_coord_2d_sorted)**2 / mask_cyt.sum() # cast cytoplasm mask in np.uint8 mask_cyt_8bit = stack.cast_img_uint8(mask_cyt) # for each radius, get neighbors and weight values = [] for r in radii: mask_distance = distances.copy() mask_distance = mask_distance <= r nb_neighbors = np.sum(mask_distance, axis=0) - 1 weights = stack.mean_filter(mask_cyt_8bit, kernel_shape="disk", kernel_size=r) weights = weights.astype(np.float32) / 255. rna_weights = weights[rna_coord_2d_sorted[:, 0], rna_coord_2d_sorted[:, 1]] nb_neighbors_weighted = np.multiply(nb_neighbors, rna_weights) value = nb_neighbors_weighted.sum() / factor values.append(value) values = np.array(values, dtype=np.float32) values_corrected = np.sqrt(values / np.pi) - np.array(radii) return values_corrected
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
def test_cast_uint8(dtype): # from integer to np.uint8 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.uint8 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 uint8 if dtype in [np.uint8, np.int8]: tensor_uint8 = stack.cast_img_uint8(tensor) else: with pytest.warns(UserWarning): tensor_uint8 = stack.cast_img_uint8(tensor) assert tensor_uint8.dtype == np.uint8
def test_cast_uint8(dtype): # from integer to np.uint8 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.uint8 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 uint8 tensor_uint8 = stack.cast_img_uint8(tensor) assert tensor_uint8.dtype == np.uint8 # check value assert tensor_uint8.max() == 255 if dtype == np.uint8: assert_array_equal(tensor_uint8, tensor)
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
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
def build_cyt_relief(image_projected, nuc_labelled, mask_cyt, alpha=0.8): """Compute a 2-d representation of the cytoplasm to be used by watershed algorithm. Cells are represented as watershed, with a low values to the center and maximum values at their borders. The equation used is: relief = alpha * relief_pixel + (1 - alpha) * relief_distance - 'relief_pixel' exploit the differences in pixel intensity values. - 'relief_distance' use the distance from the nuclei. Parameters ---------- image_projected : np.ndarray, np.uint Projected image of the cytoplasm with shape (y, x). nuc_labelled : np.ndarray, Result of the nuclei segmentation with shape (y, x). mask_cyt : np.ndarray, bool Binary mask of the cytoplasm with shape (y, x). alpha : float or int Weight of the pixel intensity values to compute the relief. A value of 0 and 1 respectively return 'relief_distance' and 'relief_pixel'. Returns ------- relief : np.ndarray, np.uint Relief image of the cytoplasm with shape (y, x). """ # check parameters stack.check_array(image_projected, ndim=2, dtype=[np.uint8, np.uint16]) stack.check_array(nuc_labelled, ndim=2, dtype=[np.uint8, np.uint16, np.int64, bool]) stack.check_array(mask_cyt, ndim=2, dtype=[bool]) stack.check_parameter(alpha=(float, int)) # use pixel intensity of the cytoplasm channel to compute the seed. if alpha == 1: relief = image_projected.copy() max_intensity = np.iinfo(image_projected.dtype).max relief = max_intensity - relief relief[nuc_labelled > 0] = 0 relief[mask_cyt == 0] = max_intensity relief = stack.rescale(relief) # use distance from the nuclei elif alpha == 0: binary_mask_nuc = nuc_labelled > 0 relief = ndi.distance_transform_edt(~binary_mask_nuc) relief[mask_cyt == 0] = relief.max() relief = np.true_divide(relief, relief.max(), dtype=np.float32) if image_projected.dtype == np.uint8: relief = stack.cast_img_uint8(relief) else: relief = stack.cast_img_uint16(relief) # use both previous methods elif 0 < alpha < 1: relief_pixel = image_projected.copy() max_intensity = np.iinfo(image_projected.dtype).max relief_pixel = max_intensity - relief_pixel relief_pixel[nuc_labelled > 0] = 0 relief_pixel[mask_cyt == 0] = max_intensity relief_pixel = stack.rescale(relief_pixel) relief_pixel = stack.cast_img_float32(relief_pixel) binary_mask_nuc = nuc_labelled > 0 relief_distance = ndi.distance_transform_edt(~binary_mask_nuc) relief_distance[mask_cyt == 0] = relief_distance.max() relief_distance = np.true_divide(relief_distance, relief_distance.max(), dtype=np.float32) relief = alpha * relief_pixel + (1 - alpha) * relief_distance if image_projected.dtype == np.uint8: relief = stack.cast_img_uint8(relief) else: relief = stack.cast_img_uint16(relief) else: raise ValueError("Parameter 'alpha' is wrong. Must be comprised " "between 0 and 1. Currently 'alpha' is {0}" .format(alpha)) return relief