Segmentación de imágenes con StarDist#

StarDist es un método de segmentación de imágenes basado en aprendizaje profundo para segmentar objetos como núcleos celulares.

Ver también

Como de costumbre, comenzamos cargando una imagen de ejemplo.

from stardist.models import StarDist2D
from csbdeep.utils import normalize
from stardist import random_label_cmap

import stackview
import matplotlib.pyplot as plt
import numpy as np
from skimage.data import human_mitosis
image = human_mitosis()
stackview.insight(image)
shape(512, 512)
dtypeuint8
size256.0 kB
min7
max255

Cargando un modelo#

Los modelos son archivos que típicamente contienen una red neuronal capaz de segmentar una imagen. StarDist viene con algunos modelos preentrenados para demostrar cómo funciona el algoritmo en un caso de uso general como la segmentación de núcleos. Si tal modelo preentrenado no funciona bien en tus datos (sé un buen científico y verifica eso cuidadosamente), necesitarás entrenar tu propio modelo que se ajuste a tus datos. Para el entrenamiento, probablemente necesitarás una GPU potente, para aplicar un modelo (paso de predicción) a una imagen 2D no es necesaria una GPU.

# creates a pretrained model
model = StarDist2D.from_pretrained('2D_versatile_fluo')
Found model '2D_versatile_fluo' for 'StarDist2D'.
Loading network weights from 'weights_best.h5'.
Loading thresholds from 'thresholds.json'.
Using default values: prob_thresh=0.479071, nms_thresh=0.3.

Normalizando la imagen de entrada#

Muchos algoritmos que utilizan redes neuronales necesitan datos de entrada normalizados para trabajar. Por ejemplo, puedes determinar el percentil 1% y el 99.8% (eso es muy común) y normalizar tu imagen para que las intensidades que se extienden entre estos percentiles estén después en el rango entre 0 y 1. Necesitamos hacer esto porque el modelo fue entrenado en una imagen en este rango y podría no ser capaz de segmentar imágenes con rangos de intensidad diferentes.

axis_norm = (0,1)
image = normalize(image, 1,99.8, axis=axis_norm)

Segmentar la imagen y etiquetar los objetos individuales a menudo se llama “segmentación de instancias” o “predicción” en la comunidad de inteligencia artificial.

labels, details = model.predict_instances(image)

stackview.insight(labels)
1/1 [==============================] - 0s 127ms/step
shape(512, 512)
dtypeint32
size1024.0 kB
min0
max317

Visualización de resultados#

Los resultados de segmentación de células / núcleos se pueden verificar mejor si la imagen de etiquetas resultante se superpone a la imagen original

plt.figure(figsize=(5,5))
plt.imshow(image, clim=(0,1), cmap='gray')
plt.imshow(labels, cmap=random_label_cmap(), alpha=0.5)
plt.axis('off');
../_images/4648d5a57dc1a7c80d78f9c3fbec4988adea0d8a03b2c386e5a6fb3988047e7e.png

… o dibujando contornos alrededor de las regiones segmentadas.

# create a new plot
fig, axes = plt.subplots(1,1)

# add two images
axes.imshow(image, cmap=plt.cm.gray)
axes.contour(labels, [0.5], linewidths=1.2, colors='r')
<matplotlib.contour.QuadContourSet at 0x22b34c4f1f0>
../_images/f39ea03af19a1ee75cbefb87b9241abb773b6cbd2868ab14af5522ca56ad5682.png

Nota: El modelo que aplicamos aquí a blobs.gif no fue entrenado en él. Sin embargo, el resultado no se ve tan mal.

Más modelos preentrenados disponibles#

StarDist ofrece más modelos preentrenados disponibles.

StarDist2D.from_pretrained() 
There are 4 registered models for 'StarDist2D':

Name                  Alias(es)
────                  ─────────
'2D_versatile_fluo'   'Versatile (fluorescent nuclei)'
'2D_versatile_he'     'Versatile (H&E nuclei)'
'2D_paper_dsb2018'    'DSB 2018 (from StarDist 2D paper)'
'2D_demo'             None

Ejercicio#

Carga ../../data/blobs.tif y aplica Cellpose a él.