Fusion d’objets à l’aide de l’apprentissage automatique#

L’ObjectMerger est un Classificateur de Forêt Aléatoire faisant partie de la bibliothèque apoc qui peut apprendre quelles étiquettes fusionner et lesquelles ne pas fusionner. Il permet le post-traitement des images d’étiquettes après que les objets ont été (intentionnellement ou non) sur-segmentés.

import apoc
from skimage.io import imread, imshow
import pyclesperanto_prototype as cle
import numpy as np

Un exemple courant peut être dérivé d’une image montrant des intensités dans les membranes cellulaires.

image = imread('../../data/membrane2d.tif')
cle.asarray(image)
cle._ image
shape(256, 256)
dtypefloat32
size256.0 kB
min277.0
max44092.0

Comme les membranes ont des intensités différentes selon la région de l’image, nous devons d’abord corriger cela.

background_subtracted = cle.divide_by_gaussian_background(image, sigma_x=10, sigma_y=10)
background_subtracted
cle._ image
shape(256, 256)
dtypefloat32
size256.0 kB
min0.15839748
max11.448771

Pour des raisons techniques, il est également recommandé de transformer l’image d’intensité en une image de type entier. Par conséquent, une normalisation peut être nécessaire. Il est important que les images utilisées pour l’entraînement et les images utilisées pour la prédiction aient des intensités dans la même plage.

oversegmented = imread("../../data/membrane2d_oversegmented.tif")
cle.asarray(oversegmented).astype(np.uint32)
cle._ image
shape(256, 256)
dtypeuint32
size256.0 kB
min1.0
max54.0

Une annotation sert à indiquer à l’algorithme quels objets segmentés doivent être fusionnés et lesquels ne doivent pas l’être.

annotation = imread("../../data/membrane2d_merge_annotation.tif")
cle.asarray(annotation).astype(np.uint32)
cle._ image
shape(256, 256)
dtypeuint32
size256.0 kB
min0.0
max2.0

À des fins de visualisation, nous pouvons superposer l’annotation avec l’image de la membrane.

cle.imshow(background_subtracted, max_display_intensity=4, continue_drawing=True)
cle.imshow(annotation, alpha=0.6, labels=True)
../_images/ed4124ba7532565c50e80bc09e8a750e648ef841fefa532d76468f463025b4fb.png

Pour montrer plus précisément ce qui doit être annoté, nous superposons également l’image des bords d’étiquettes et l’annotation. Notez que les bords qui ne sont pas censés être fusionnés sont de petits points annotant toujours soigneusement seulement deux objets (qui ne doivent pas être fusionnés).

cle.imshow(cle.detect_label_edges(oversegmented), continue_drawing=True)
cle.imshow(annotation, alpha=0.6, labels=True)
../_images/3e3e7c26276223990a47c1d3fa12c738cead94714793ea0d4cfdfc692f647b4b.png

Entraînement du fusionneur#

Le LabelMerger peut être entraîné en utilisant trois caractéristiques :

  • touch_portion : La quantité relative de contact d’un objet avec un autre. Par exemple, dans un tissu symétrique en nid d’abeille, les cellules voisines ont une portion de contact de 1/6 entre elles.

  • touch_count : Le nombre de pixels où les objets se touchent. Lors de l’utilisation de ce paramètre, assurez-vous que les images utilisées pour l’entraînement et la prédiction ont la même taille de voxel.

  • mean_touch_intensity : L’intensité moyenne entre les objets qui se touchent. Si une cellule est sur-segmentée, plusieurs objets sont trouvés à l’intérieur de cette cellule. La zone où ces objets se touchent a une intensité plus faible que la zone où deux cellules se touchent. Ainsi, ils peuvent être différenciés. La normalisation de l’image comme montré ci-dessus est essentielle.

  • centroid_distance : La distance (en pixels ou voxels) entre les centroïdes des objets étiquetés.

Note : il est recommandé d’utiliser la plupart des caractéristiques uniquement dans des images isotropes.

feature_definition = "touch_portion mean_touch_intensity"

classifier_filename = "label_merger.cl"

apoc.erase_classifier(classifier_filename)
classifier = apoc.ObjectMerger(opencl_filename=classifier_filename)

classifier.train(features=feature_definition,
                 labels=oversegmented,
                 sparse_annotation=annotation,
                 image=background_subtracted) 
merged_labels = classifier.predict(labels=oversegmented, image=background_subtracted)
merged_labels
cle._ image
shape(256, 256)
dtypeuint32
size256.0 kB
min1.0
max31.0