Détection des maxima locaux#
Pour détecter les maxima locaux, pixels entourés de pixels d’intensité plus faible, nous pouvons utiliser certaines fonctions dans scikit-image et clesperanto.
Voir aussi
from skimage.feature import peak_local_max
import pyclesperanto_prototype as cle
from skimage.io import imread, imshow
from skimage.filters import gaussian
import matplotlib.pyplot as plt
Nous commençons par charger une image et recadrer une région à des fins de démonstration. Nous avons utilisé l’ensemble d’images BBBC007v1 version 1 (Jones et al., Proc. ICCV Workshop on Computer Vision for Biomedical Image Applications, 2005), disponible dans la Broad Bioimage Benchmark Collection [Ljosa et al., Nature Methods, 2012].
image = imread("../../data/BBBC007_batch/A9 p7d.tif")[-100:, 0:100]
cle.imshow(image)
Prétraitement#
Une étape de prétraitement courante avant de détecter les maxima est le floutage de l’image. Cela a du sens pour éviter de détecter des maxima qui ne sont que des variations d’intensité résultant du bruit.
preprocessed = gaussian(image, sigma=2, preserve_range=True)
cle.imshow(preprocessed)
peak_local_max#
La fonction peak_local_max permet de détecter les maxima qui ont une intensité plus élevée que les pixels environnants et les autres maxima selon un seuil défini.
coordinates = peak_local_max(preprocessed, threshold_abs=5)
coordinates
array([[23, 85],
[11, 29],
[41, 40],
[88, 34],
[72, 83],
[69, 89],
[31, 72],
[75, 16],
[80, 22],
[ 6, 56]], dtype=int64)
Ces coordonnées peuvent être visualisées en utilisant la fonction plot de matplotlib.
cle.imshow(preprocessed, continue_drawing=True)
plt.plot(coordinates[:, 1], coordinates[:, 0], 'r.')
[<matplotlib.lines.Line2D at 0x2309908fbb0>]
S’il y a trop de maxima détectés, on peut modifier les résultats en changeant le paramètre sigma du flou gaussien ci-dessus ou en modifiant le seuil passé à la fonction peak_local_max.
detect_maxima_box#
La fonction peak_local_max a tendance à prendre beaucoup de temps, par exemple lors du traitement de grandes données d’images 3D. Ainsi, une alternative sera présentée : detect_maxima_box de clesperanto est un filtre d’image qui attribue aux pixels la valeur 1 lorsque les pixels environnants ont une intensité plus faible. Il est généralement rapide même sur de grandes données d’images 3D.
local_maxima_image = cle.detect_maxima_box(preprocessed)
local_maxima_image
|
|
cle._ image
|
Évidemment, cela donne une image binaire. Cette image binaire peut être convertie en une image étiquetée en attribuant des numéros différents aux spots individuels. À partir de cette image étiquetée, nous pouvons supprimer les maxima détectés aux bords de l’image, ce qui peut être utile dans ce cas.
all_labeled_spots = cle.label_spots(local_maxima_image)
labeled_spots = cle.exclude_labels_on_edges(all_labeled_spots)
labeled_spots
|
|
cle._ image
|
Pour visualiser ces spots sur l’image originale, il peut être judicieux d’augmenter la taille des spots - juste à des fins de visualisation.
label_visualization = cle.dilate_labels(labeled_spots, radius=3)
cle.imshow(preprocessed, continue_drawing=True)
cle.imshow(label_visualization, labels=True, alpha=0.5)
Dans la partie inférieure centrale de cette image, nous voyons maintenant un maximum local qui a été détecté dans l’arrière-plan. Nous pouvons supprimer ces maxima dans les régions de plus faible intensité par seuillage.
binary_image = cle.threshold_otsu(preprocessed)
binary_image
|
|
cle._ image
|
Nous pouvons maintenant exclure les étiquettes de l’image des spots où l’intensité dans l’image binaire n’est pas dans la plage [0..1].
final_spots = cle.exclude_labels_with_map_values_out_of_range(
binary_image,
labeled_spots,
minimum_value_range=1,
maximum_value_range=1
)
final_spots
|
|
cle._ image
|
Nous pouvons ensuite visualiser à nouveau les spots en utilisant la stratégie introduite ci-dessus, mais cette fois sur l’image originale.
label_visualization2 = cle.dilate_labels(final_spots, radius=3)
cle.imshow(image, continue_drawing=True)
cle.imshow(label_visualization2, labels=True, alpha=0.5)