Label neighbor filters#
In this notebook, we demonstrate how neighbor-based filters work in the contexts of measurements of cells in tissues. We also determine neighbor of neighbors and extend the radius of such filters.
See also
import pyclesperanto_prototype as cle
import numpy as np
import matplotlib
from numpy.random import random
cle.select_device("RTX")
<Apple M1 Max on Platform: Apple (2 refs)>
# Generate artificial cells as test data
tissue = cle.artificial_tissue_2d()
touch_matrix = cle.generate_touch_matrix(tissue)
cle.imshow(tissue, labels=True)
![../_images/07c4b3ca02caadf21e1c98169501b7d74079d11d679cf8232167a4c0ddfcc3df.png](../_images/07c4b3ca02caadf21e1c98169501b7d74079d11d679cf8232167a4c0ddfcc3df.png)
Associate artificial measurements to the cells#
centroids = cle.label_centroids_to_pointlist(tissue)
coordinates = cle.pull_zyx(centroids)
values = random([coordinates.shape[1]])
for i, y in enumerate(coordinates[1]):
if (y < 128):
values[i] = values[i] * 10 + 45
else:
values[i] = values[i] * 10 + 90
measurements = cle.push_zyx(np.asarray([values]))
# visualize measurments in space
parametric_image = cle.replace_intensities(tissue, measurements)
cle.imshow(parametric_image, min_display_intensity=0, max_display_intensity=100, color_map='jet')
![../_images/655d215e56014d9838228d794c9e26917f506de41b8ff2a54c547f1e9b249b80.png](../_images/655d215e56014d9838228d794c9e26917f506de41b8ff2a54c547f1e9b249b80.png)
Local averaging smoothes edges#
By averaging measurments locally, we can reduce the noise, but we also introduce a stripe where the region touch
local_mean_measurements = cle.mean_of_touching_neighbors(measurements, touch_matrix)
parametric_image = cle.replace_intensities(tissue, local_mean_measurements)
cle.imshow(parametric_image, min_display_intensity=0, max_display_intensity=100, color_map='jet')
![../_images/29c23321011c001b7ad520cbccd166702b077b9ba2925ad88982e6bd5f23c0bf.png](../_images/29c23321011c001b7ad520cbccd166702b077b9ba2925ad88982e6bd5f23c0bf.png)
Edge preserving filters: median#
By averaging using a median filter, we can also reduce noise while keeping the edge between the regions sharp
local_median_measurements = cle.median_of_touching_neighbors(measurements, touch_matrix)
parametric_image = cle.replace_intensities(tissue, local_median_measurements)
cle.imshow(parametric_image, min_display_intensity=0, max_display_intensity=100, color_map='jet')
![../_images/34b20172b6d785026cd239419aee2e12e0b916fe6d8686564541a85354bec18b.png](../_images/34b20172b6d785026cd239419aee2e12e0b916fe6d8686564541a85354bec18b.png)
Increasing filter radius: neighbors of neighbors#
In order to increase the radius of the operation, we need to determin neighbors of touching neighbors
neighbor_matrix = cle.neighbors_of_neighbors(touch_matrix)
local_median_measurements = cle.median_of_touching_neighbors(measurements, neighbor_matrix)
parametric_image = cle.replace_intensities(tissue, local_median_measurements)
cle.imshow(parametric_image, min_display_intensity=0, max_display_intensity=100, color_map='jet')
![../_images/3767139b2a5bb360d2676b6db058ab36d9dc42793da3a1c5c707e90c257e1395.png](../_images/3767139b2a5bb360d2676b6db058ab36d9dc42793da3a1c5c707e90c257e1395.png)
Short-cuts for visualisation only#
If you’re not so much interested in the vectors of measurements, there are shortcuts: For example for visualizing the mean value of neighboring pixels with different radii:
# visualize measurments in space
measurement_image = cle.replace_intensities(tissue, measurements)
print('original')
cle.imshow(measurement_image, min_display_intensity=0, max_display_intensity=100, color_map='jet')
for radius in range(0, 5):
print('Radius', radius)
# note: this function takes a parametric image the label map instead of a vector and the touch_matrix used above
parametric_image = cle.mean_of_touching_neighbors_map(measurement_image, tissue, radius=radius)
cle.imshow(parametric_image, min_display_intensity=0, max_display_intensity=100, color_map='jet')
original
![../_images/655d215e56014d9838228d794c9e26917f506de41b8ff2a54c547f1e9b249b80.png](../_images/655d215e56014d9838228d794c9e26917f506de41b8ff2a54c547f1e9b249b80.png)
Radius 0
![../_images/655d215e56014d9838228d794c9e26917f506de41b8ff2a54c547f1e9b249b80.png](../_images/655d215e56014d9838228d794c9e26917f506de41b8ff2a54c547f1e9b249b80.png)
Radius 1
![../_images/d04198d48091ccb86ad6b12c1c5ca08eb03793fc231881a8c7494bc666118eee.png](../_images/d04198d48091ccb86ad6b12c1c5ca08eb03793fc231881a8c7494bc666118eee.png)
Radius 2
![../_images/e719d77f5d1ac5048f88fe39257bad97f56ad0fd48f31395021912c2ce99247d.png](../_images/e719d77f5d1ac5048f88fe39257bad97f56ad0fd48f31395021912c2ce99247d.png)
Radius 3
![../_images/c8fa14c993a5ae89d5bd0b6eb9cdfe4a8d76f38ddc8dc011f89a0a77a9309e7c.png](../_images/c8fa14c993a5ae89d5bd0b6eb9cdfe4a8d76f38ddc8dc011f89a0a77a9309e7c.png)
Radius 4
![../_images/184432db811e01dcbe47e859bfcc5e98bc087e5229260aa211ee56babf0af9d7.png](../_images/184432db811e01dcbe47e859bfcc5e98bc087e5229260aa211ee56babf0af9d7.png)