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

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

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

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

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

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
Radius 0
../_images/655d215e56014d9838228d794c9e26917f506de41b8ff2a54c547f1e9b249b80.png
Radius 1
../_images/d04198d48091ccb86ad6b12c1c5ca08eb03793fc231881a8c7494bc666118eee.png
Radius 2
../_images/e719d77f5d1ac5048f88fe39257bad97f56ad0fd48f31395021912c2ce99247d.png
Radius 3
../_images/c8fa14c993a5ae89d5bd0b6eb9cdfe4a8d76f38ddc8dc011f89a0a77a9309e7c.png
Radius 4
../_images/184432db811e01dcbe47e859bfcc5e98bc087e5229260aa211ee56babf0af9d7.png