Mesures de qualité de la segmentation d’images#
Pour déterminer la qualité d’un algorithme de segmentation, et pour comparer différents algorithmes, nous avons besoin d’une métrique. Une métrique courante est l’Indice de Jaccard, qui est une mesure de chevauchement entre une segmentation de référence et la segmentation produite par un algorithme par exemple. Si nous travaillons avec des images étiquetées, une méthode équitable consiste à déterminer le chevauchement de chaque objet annoté avec l’objet le plus chevauchant dans la segmentation automatique. Si nous faisons la moyenne de cette valeur sur tous les objets annotés, nous obtenons l’Indice de Jaccard Sparse tel que défini dans The Segmentation Game.
import os
import napari
import napari_segment_blobs_and_things_with_membranes as nsbatwm
from the_segmentation_game import metrics
from skimage.io import imread
Pour démontrer cela, nous choisissons une image d’exemple aléatoire du jeu de données BBBC007 (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_folder = "../../data/BBBC007_batch/"
sparse_annotation_folder = "../../data/BBBC007_sparse_instance_annotation/"
test_image_filename = "17P1_POS0013_D_1UL.tif"
Pour visualiser l’image et l’annotation manuelle correspondante, nous utilisons napari.
viewer = napari.Viewer()
L’image d’exemple#
image = imread(folder + test_image_filename)
viewer.add_image(image)
napari.utils.nbscreenshot(viewer)
L’annotation manuelle#
sparse_labels = imread(sparse_annotation_folder + test_image_filename)
viewer.add_labels(sparse_labels)
napari.utils.nbscreenshot(viewer)
# cacher la dernière couche d'étiquettes
viewer.layers[-1].visible = False
La segmentation automatique#
À des fins de démonstration, nous utilisons la soustraction de fond et l’étiquetage de Voronoi-Otsu pour segmenter automatiquement les noyaux dans cette image.
def my_segmentation_algorithm(input_image):
# soustraction de fond
background_subtracted = nsbatwm.white_tophat(input_image, radius = 10)
# segmentation d'instance / étiquetage
labels_result = nsbatwm.voronoi_otsu_labeling(background_subtracted, spot_sigma=5, outline_sigma=1)
return labels_result
labels = my_segmentation_algorithm(image)
viewer.add_labels(labels)
napari.utils.nbscreenshot(viewer)
Estimation de la qualité : Indice de Jaccard Sparse#
À partir des deux images étiquetées chargées et produites ci-dessus, nous pouvons calculer l’Indice de Jaccard Sparse.
metrics.jaccard_index_sparse(sparse_labels, labels)
0.8357392602053431
Exercice#
Utilisez la boucle for suivante et les extraits de code ci-dessus pour calculer la qualité de segmentation de toutes les images du dossier. Fournissez la qualité moyenne sur toutes les images.
for image_filename in os.listdir(image_folder):
print(image_folder + image_filename)
../../data/BBBC007_batch/17P1_POS0013_D_1UL.tif
../../data/BBBC007_batch/20P1_POS0005_D_1UL.tif
../../data/BBBC007_batch/20P1_POS0007_D_1UL.tif
../../data/BBBC007_batch/20P1_POS0010_D_1UL.tif
../../data/BBBC007_batch/A9 p7d.tif
../../data/BBBC007_batch/AS_09125_040701150004_A02f00d0.tif