Segmentation d’image avec StarDist#

StarDist est une méthode de segmentation d’image basée sur l’apprentissage profond pour segmenter des objets tels que les noyaux cellulaires.

Voir également

Comme d’habitude, nous commençons par charger une image d’exemple.

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

Chargement d’un modèle#

Les modèles sont des fichiers qui contiennent généralement un réseau neuronal capable de segmenter une image. StarDist est livré avec quelques modèles pré-entraînés pour démontrer comment l’algorithme fonctionne sur un cas d’utilisation général tel que la segmentation des noyaux. Si un tel modèle pré-entraîné ne fonctionne pas bien sur vos données (soyez un bon scientifique et vérifiez cela soigneusement !), vous devez entraîner votre propre modèle qui s’adapte à vos données. Pour l’entraînement, vous aurez probablement besoin d’un GPU puissant, pour appliquer un modèle (étape de prédiction) à une image 2D, aucun GPU n’est nécessaire.

# 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.

Normalisation de l’image d’entrée#

De nombreux algorithmes utilisant des réseaux neuronaux ont besoin de données d’entrée normalisées pour fonctionner. Par exemple, vous pouvez déterminer le 1% et le 99,8% percentile (c’est très courant) et normaliser votre image de sorte que les intensités réparties entre ces percentiles soient ensuite dans la plage entre 0 et 1. Nous devons faire cela car le modèle a été entraîné sur une image dans cette plage et pourrait ne pas être capable de segmenter des images avec des plages d’intensité différentes.

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

La segmentation de l’image et l’étiquetage des objets individuels sont souvent appelés “segmentation d’instance” ou “prédiction” dans la communauté de l’intelligence artificielle.

labels, details = model.predict_instances(image)

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

Visualisation des résultats#

Les résultats de segmentation des cellules / noyaux peuvent être vérifiés au mieux si l’image d’étiquettes résultante est superposée à l’image originale

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

… ou en dessinant des contours autour des régions segmentées.

# 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

Note : Le modèle que nous avons appliqué ici à blobs.gif n’a pas été entraîné dessus. Le résultat n’a pourtant pas l’air si mauvais.

Plus de modèles pré-entraînés disponibles#

StarDist offre plus de modèles pré-entraînés 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

Exercice#

Chargez ../../data/blobs.tif et appliquez-y Cellpose.