Comparaison visuelle d’étiquetage#
Une première étape importante lors de la comparaison des algorithmes de segmentation est de visualiser les résultats des algorithmes individuels et de montrer les différences entre eux.
import numpy as np
from skimage.io import imread
from pyclesperanto_prototype import imshow
import matplotlib.pyplot as plt
import pandas as pd
En visualisant simplement les images, nous pouvons voir qu’aucune paire des quatre algorithmes comparés ne produit la même image d’étiquettes.
filenames = [
"blobs_labels_imagej.tif",
"blobs_labels_skimage.tif",
"blobs_labels_clesperanto_python.tif",
"blobs_labels_clesperanto_imagej.tif"
]
for filename in filenames:
print(filename)
label_image = imread(filename)
imshow(label_image, labels=True)
blobs_labels_imagej.tif
blobs_labels_skimage.tif
blobs_labels_clesperanto_python.tif
blobs_labels_clesperanto_imagej.tif
Comme les objets correspondants ont des couleurs différentes dans cette visualisation, nous pouvons conclure qu’au moins les étiquettes des objets sont différentes. Nous ne pouvons pas encore conclure si la méthode de seuillage d’Otsu donne des résultats différents dans les implémentations données.
Images de différence#
Pour voir le chevauchement entre les différentes images, nous allons produire des images binaires à partir des images d’étiquettes et visualiser la différence entre ces images binaires.
Nous comparons d’abord le résultat d’ImageJ et le résultat de scikit-image pour démontrer la procédure.
binary_blobs_imagej = imread(filenames[0]) > 0
binary_blobs_skimage = imread(filenames[1]) > 0
imshow(binary_blobs_imagej)
imshow(binary_blobs_skimage)
En regardant attentivement ces deux images, on peut déjà voir que les objets sont un peu plus grands dans la deuxième image.
Pour produire l’image de différence, nous utiliserons la méthode logical_xor de numpy. Elle mettra tous les pixels de l’image différence à 1, là où l’une des deux images binaires d’entrée est 1, mais pas les deux. C’est ce qu’on appelle l’opérateur OU exclusif.
difference = np.logical_xor(binary_blobs_imagej, binary_blobs_skimage)
fig, axs = plt.subplots(figsize=(10,10))
axs.imshow(difference)
<matplotlib.image.AxesImage at 0x24619eb5130>
À partir de cette image binaire, nous pouvons compter le nombre de pixels qui sont différents entre ces deux approches :
np.sum(difference)
830
Une matrice de comptage des pixels différents#
Nous allons maintenant programmer deux boucles for qui itèrent sur des paires d’images d’étiquettes et les comparent en utilisant la même approche. Le résultat sera une matrice 4x4 avec le nombre de pixels qui sont différents lors de la comparaison des implémentations d’algorithmes correspondantes.
matrix = {"Algorithms": filenames}
for filename_A in filenames:
image_A = imread(filename_A)
measurements = []
for filename_B in filenames:
image_B = imread(filename_B)
difference = np.logical_xor(image_A, image_B)
number_of_different_pixels = np.sum(difference)
measurements.append(number_of_different_pixels)
matrix[filename_A] = measurements
pd.DataFrame(matrix)
| Algorithms | blobs_labels_imagej.tif | blobs_labels_skimage.tif | blobs_labels_clesperanto_python.tif | blobs_labels_clesperanto_imagej.tif | |
|---|---|---|---|---|---|
| 0 | blobs_labels_imagej.tif | 0 | 830 | 830 | 830 |
| 1 | blobs_labels_skimage.tif | 830 | 0 | 0 | 0 |
| 2 | blobs_labels_clesperanto_python.tif | 830 | 0 | 0 | 0 |
| 3 | blobs_labels_clesperanto_imagej.tif | 830 | 0 | 0 | 0 |
À partir de cette matrice, nous pouvons conclure que seul le résultat d’ImageJ est différent des trois autres implémentations.
Exercice#
Nous devrions également confirmer rapidement cela en examinant une autre image de différence, par exemple entre l’implémentation clesperanto en Jython et scikit-image en Python. Visualisez les deux images binaires et l’image de différence entre ces deux. Comptez également le nombre de pixels qui sont différents entre ces deux images.