Definiciones de vecindad#

En pyclesperanto, los grafos de adyacencia de vecinos se utilizan para investigar las relaciones entre objetos etiquetados vecinos, como células. Este cuaderno demuestra las definiciones de vecindad consideradas.

Ver también

import pyclesperanto_prototype as cle
import numpy as np
import matplotlib
from numpy.random import random

cle.select_device("RTX")
<NVIDIA GeForce RTX 3050 Ti Laptop GPU on Platform: NVIDIA CUDA (1 refs)>

Para visualizar las relaciones entre objetos vecinos, comenzamos con una rejilla celular artificial. Las células están alineadas aproximadamente en una rejilla de panal. La intensidad en estas células se distribuye uniformemente. Solo una célula en el centro de la rejilla tiene una intensidad mucho mayor.

# Generate artificial cells as test data
tissue = cle.artificial_tissue_2d()

# fill it with random measurements
values = random([int(cle.maximum_of_all_pixels(tissue))])
for i, y in enumerate(values):
    if (i != 95):
        values[i] = values[i] * 10 + 45
    else:
        values[i] = values[i] * 10 + 90

measurements = cle.push(np.asarray([values]))

# visualize measurments in space
example_image = cle.replace_intensities(tissue, measurements)

Datos de ejemplo#

Echemos un vistazo a una imagen con píxeles de forma arbitraria. Llamémoslos “células”. En nuestra imagen de ejemplo, hay una célula en el centro con mayor intensidad:

cle.imshow(example_image, min_display_intensity=30, max_display_intensity=90, color_map='jet')
../_images/d7d926c86544ecf6335e0ccb2fc4fa54179889e138c2457cb0f9be07609e3628.png

Vecinos que se tocan#

Podemos mostrar todas las células que pertenecen a la vecindad “que se toca” visualizando el grafo de vecinos que se tocan como una malla.

mesh = cle.draw_mesh_between_touching_labels(tissue)

# make lines a bit thicker for visualization purposes
mesh = cle.maximum_sphere(mesh, radius_x=1, radius_y=1)

cle.imshow(mesh)
../_images/0af8b1ea909d38d9af32f1e88dd64f7281eaa76fff04b60b382cf0c1ff6b59bd.png

Si aplicamos un filtro de máximo local a esta rejilla, podemos ver cómo la alta intensidad de la única célula en el centro se extiende a las células vecinas que la tocan directamente.

local_maximum = cle.maximum_of_touching_neighbors_map(example_image, tissue)

cle.imshow(local_maximum, min_display_intensity=30, max_display_intensity=90, color_map='jet')
../_images/b7774907cdd6c8b4a210de8e73e715a00823880f3ce4ba5246da0963be3c38dd.png

Vecinos de vecinos que se tocan#

También puedes extender la vecindad considerando vecinos de vecinos (de vecinos (de vecinos)). Qué tan lejos llegas, se puede configurar con un parámetro de radio.

  • Radio==0 significa que no se tienen en cuenta los vecinos,

  • radio==1 es idéntico a los vecinos que se tocan,

  • radio > 1 son vecinos de vecinos.

for radius in range(0, 5):
    local_maximum = cle.maximum_of_touching_neighbors_map(example_image, tissue, radius=radius)
    cle.imshow(local_maximum, min_display_intensity=30, max_display_intensity=90, color_map='jet')
../_images/d7d926c86544ecf6335e0ccb2fc4fa54179889e138c2457cb0f9be07609e3628.png ../_images/937c09d5a4703a8a5c1c4efc1a2bc826797bb70fd4fbb51db3ff15e16213dd92.png ../_images/f28bc37ac691e096018731805c08b6b2666d6c44d8f1f448a2870998ab5cffcd.png ../_images/f2010d4271d10f6e6b75ee55fa629b769a1ff2e3c25c72fc7c012daeec4860fb.png ../_images/945a539fff33a984011a2f2101f541798686ab2187bff7961f76bb047314d695.png

N vecinos más cercanos#

También puedes definir una vecindad a partir de las distancias entre células. Como medida de distancia, usamos la distancia euclidiana entre los centroides de las etiquetas. También en este caso puedes configurar qué tan lejos debe llegar la vecindad estableciendo el número de vecinos más cercanos n. Como se mencionó anteriormente, las vecindades incluyen la célula central. Por lo tanto, la vecindad de un objeto y su n=1 vecino más cercano contiene dos vecinos.

for n in range(1, 10):
    print("n = ", n)
    mesh = cle.draw_mesh_between_n_closest_labels(tissue, n=n)

    # make lines a bit thicker for visualization purposes
    mesh = cle.maximum_sphere(mesh, radius_x=1, radius_y=1)

    cle.imshow(mesh)
n =  1
../_images/d656eb1a5154bca27c8d1fb78e0b7e46f1f86af0ab3b42f3e18243424063ed2b.png
n =  2
../_images/2e49cdcd16f3bade47e4faf0e54c41524d0e0435f6f871c553be3cbe694dd7a9.png
n =  3
../_images/a093bd2f6225e603000d314f060fd02ed13dc1da445330534fa686b0a640c3e0.png
n =  4
../_images/c3e53103e1b12bc9fd25f2b5a62cc4c3d2165195a5fd35c76c18bf75c727f9dd.png
n =  5
../_images/c797f58dca46a5f5edeff4d2c77b6b5ad7a0bfbbff77a8073be15031fdb5d475.png
n =  6
../_images/67f14c5ac595fc5cec6a8675d7c2199982c23bb1d233bb6c238e309e65865e81.png
n =  7
../_images/4092d9a3336aeda1d77ea4d76009178f27821ed6de932f7a3fed6758ddb99873.png
n =  8
../_images/893ed88198daad76e2f79f306675b374d70e5752b1c6ca59c8618a8ae72a029f.png
n =  9
../_images/c5b8b833cf8c215b2fdd6abe090bd4b90a6ce276574f47a5992a301985e4bb81.png

Esto también se puede visualizar usando el filtro de máximo local. En comparación con los vecinos de vecinos, el radio de la vecindad se puede ajustar de manera más granular usando los n vecinos más cercanos. Ten en cuenta que al calcular el máximo en esa vecindad, no cada aumento de n += 1 hace que el tamaño del área roja aumente. Esto se debe a que no es el píxel máximo el que empuja su intensidad hacia los vecinos, son los vecinos los que atraen esa intensidad al aplicar el filtro máximo.

for n in range(1, 10):
    print("n = ", n)

    local_maximum = cle.maximum_of_n_nearest_neighbors_map(example_image, tissue, n=n)
    cle.imshow(local_maximum, min_display_intensity=30, max_display_intensity=90, color_map='jet')
n =  1
../_images/c5d50a6b2e9276b3153bb73ba8818b4ab641b576448f8019397f4fe24ac58902.png
n =  2
../_images/4c750cb2ca914e976256ac62a60a7cb37e799dbf17d80c6f07a77f101a9d84f5.png
n =  3
../_images/2b3a3237123f27c4f75fa0326cfafd07cfb876a8e35ed43050abbc0c740dd58f.png
n =  4
../_images/80a180391d431765218b9a5696ac24796673c063db1d496050f4d9bcfcf4b6e8.png
n =  5
../_images/18ea82622be83d8af6169fa677e8386a343f66e3eda2256161c2231de63d954d.png
n =  6
../_images/69964cc561c9b54fca824b45095b376f6b741a7ef1cd8e34438800e35c89c296.png
n =  7
../_images/3f7f807e2058a0908f542b520e57f2c13dbe179978c07b1c816af7f922f6d933.png
n =  8
../_images/45f1038a27241fc688f06a1092083b1442a4d70c86fe3dfae0b7445aac8b2bcc.png
n =  9
../_images/af0bbc5251c4da8e607b1281eb5be6fb455c21ac06fe91b323ed28670b9eb5db.png

Vecinos proximales#

También podemos calcular el máximo local de células con distancias entre centroides por debajo de un umbral superior dado.

local_maximum = cle.maximum_of_proximal_neighbors_map(example_image, tissue, max_distance=20)
cle.imshow(local_maximum, min_display_intensity=30, max_display_intensity=90, color_map='jet')
../_images/1c5f0b099f33d085a6b73d9b859198639f83a7bb9ee80109b45852b22d6b6cc0.png
local_maximum = cle.maximum_of_proximal_neighbors_map(example_image, tissue, max_distance=50)
cle.imshow(local_maximum, min_display_intensity=30, max_display_intensity=90, color_map='jet')
../_images/4e040a00671b46ec514b05b0179e9c414e3da8d092dcf9fc085ead2aa5e733a9.png

Ejercicio#

Dibuja una malla entre vecinos proximales con diferentes distancias, por ejemplo, en un bucle for.