Contar vecinos en contacto#

En este notebook visualizamos qué células en un tejido son vecinas dibujando una malla. Además, podemos cambiar la intensidad de la malla para que se corresponda con la distancia entre los centroides de las células.

import pyclesperanto_prototype as cle
import numpy as np
import pandas as pd

Datos de prueba#

Vamos a generar una estructura similar a un tejido que consiste en células que típicamente tienen aproximadamente 6 vecinos.

cells = cle.artificial_tissue_2d(
    delta_x=48, 
    delta_y=32, 
    random_sigma_x=7, 
    random_sigma_y=7, 
    width=250, 
    height=250)

cle.imshow(cells, labels=True)
../_images/a239d30a5f638c6d12d046b9a4753ec2bb40d0b9731c9978630416c34e95cb81.png

Malla entre células vecinas#

Antes de contar los vecinos, deberíamos visualizar las relaciones de vecindad. Podemos hacer esto dibujando una malla entre los centroides de las células vecinas que se tocan.

mesh = cle.draw_mesh_between_touching_labels(cells)

cle.imshow(mesh)
../_images/73eb44d8f84fd09a8bea5023ec835deda60879a71faccce7e1cfa0b327748bad.png

También podemos combinar ambas visualizaciones en una sola imagen. Ten en cuenta que estas imágenes no deben usarse más adelante para análisis cuantitativos. Solo sirven para propósitos de visualización.

Conexiones de centroides y bordes celulares#

Una forma común de visualizar tejidos en este contexto es dibujando los bordes celulares y la malla de centroides en diferentes colores.

visualization = mesh * 2 + cle.detect_label_edges(cells)

cle.imshow(visualization, color_map='jet')
../_images/06b49f4a39272a25bef41589fbe180a68febfa282f5fc85afccd2680da88a553.png

Analizar y visualizar el número de vecinos en contacto#

También podemos contar los vecinos en contacto y visualizar el resultado como una imagen paramétrica en colores.

neighbor_count_image = cle.touching_neighbor_count_map(cells)

cle.imshow(neighbor_count_image, color_map='jet', colorbar=True, min_display_intensity=0)
../_images/d25f8180795fcae6816e5176e9d82106bfe9bf4f8f4698be1faae724792c27e6.png

Ten en cuenta que los números a lo largo del borde de la imagen pueden no ser precisos. Por lo tanto, deberíamos excluir las células correspondientes del análisis posterior.

cells_ex_border = cle.exclude_labels_on_edges(cells)

cle.imshow(cells_ex_border, labels=True)
../_images/2661182fc554bd374db54a176ad01c6affed0f2d22399fe67678a21a9c723517.png

Después de corregir la imagen de etiquetas, también podemos corregir la imagen paramétrica.

neighbor_count_image_ex_border = neighbor_count_image * (cells_ex_border != 0)

cle.imshow(neighbor_count_image_ex_border, color_map='jet', colorbar=True, min_display_intensity=0)
../_images/059356bb30ff5d2327058e3058156e4dd3bf37bb48fc7f3edb81e2803bdd131e.png

Ahora, podemos medir el número de vecinos. Podemos simplemente leer esos números y ponerlos en una lista …

cle.read_intensities_from_map(cells_ex_border, neighbor_count_image_ex_border)
cl.Array([[0., 5., 6., 7., 6., 6., 7., 6., 6., 5., 5., 6., 6., 7., 6., 6.,
        6., 6., 6., 6., 6.]], dtype=float32)

… también podemos leer estos valores junto con todas las demás estadísticas y ponerlos en un DataFrame de pandas.

statistics = cle.statistics_of_labelled_pixels(neighbor_count_image_ex_border, cells_ex_border)

table = pd.DataFrame(statistics)

# renombrar una columna
table = table.rename(columns={"mean_intensity": "number_of_neighbors"})

# filtrar solo un subconjunto de todas las columnas; solo lo que nos interesa
table = table[["label", "number_of_neighbors", "centroid_x", "centroid_y"]]

table
label number_of_neighbors centroid_x centroid_y
0 1 5.0 74.592697 23.731028
1 2 6.0 173.741379 35.582230
2 3 7.0 49.460915 51.928082
3 4 6.0 91.783768 52.666199
4 5 6.0 142.728210 62.962471
5 6 7.0 189.973206 68.526794
6 7 6.0 73.699181 88.797356
7 8 6.0 115.321083 90.665649
8 9 5.0 163.097733 99.824242
9 10 5.0 58.206852 122.341309
10 11 6.0 98.847565 134.280228
11 12 6.0 147.731705 127.326218
12 13 7.0 200.522903 112.817368
13 14 6.0 67.880905 162.991592
14 15 6.0 122.943306 157.515717
15 16 6.0 171.010025 153.333328
16 17 6.0 43.426266 189.492981
17 18 6.0 96.272728 192.326477
18 19 6.0 140.815964 194.446030
19 20 6.0 193.817596 193.019318

Ejercicio#

Analiza un campo de visión más grande con más células y varía los parámetros random_sigma_x y random_sigma_y de la función artificial_tissue_2d. Utiliza un mapa de conteo de vecinos en contacto para contar el número de vecinos en contacto antes y después de aplicar un filtro de mediana al mapa.