Objekte mit maschinellem Lernen zusammenführen#

Der ObjectMerger ist ein Random Forest Classifier, der Teil der apoc-Bibliothek ist und lernen kann, welche Beschriftungen zusammengeführt werden sollen und welche nicht. Er ermöglicht die Nachbearbeitung von Beschriftungsbildern, nachdem Objekte (absichtlich oder unabsichtlich) übersegmentiert wurden.

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

Ein häufiges Beispiel kann von einem Bild abgeleitet werden, das Intensitäten in Zellmembranen zeigt.

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

Da die Membranen je nach Region im Bild unterschiedliche Intensitäten aufweisen, müssen wir dies zunächst korrigieren.

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

Aus technischen Gründen wird auch empfohlen, das Intensitätsbild in ein Bild vom Typ Integer umzuwandeln. Daher kann eine Normalisierung erforderlich sein. Es ist wichtig, dass Bilder, die für das Training verwendet werden, und Bilder, die für die Vorhersage verwendet werden, Intensitäten im gleichen Bereich haben.

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

Eine Annotation dient dazu, dem Algorithmus mitzuteilen, welche segmentierten Objekte zusammengeführt werden sollen und welche nicht.

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

Zu Visualisierungszwecken können wir die Annotation mit dem Membranbild überlagern.

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

Um genauer zu zeigen, was annotiert werden muss, überlagern wir auch das Label-Edge-Bild und die Annotation. Beachten Sie, dass die Kanten, die nicht zusammengeführt werden sollen, kleine Punkte sind, die immer sorgfältig nur zwei Objekte annotieren (die nicht zusammengeführt werden sollen).

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

Training des Mergers#

Der LabelMerger kann mit drei Merkmalen trainiert werden:

  • touch_portion: Der relative Anteil, den ein Objekt ein anderes berührt. Z.B. in einem symmetrischen, wabenartigen Gewebe haben benachbarte Zellen einen Berührungsanteil von 1/6 zueinander.

  • touch_count: Die Anzahl der Pixel, an denen sich Objekte berühren. Wenn Sie diesen Parameter verwenden, stellen Sie sicher, dass Bilder, die für Training und Vorhersage verwendet werden, die gleiche Voxelgröße haben.

  • mean_touch_intensity: Die durchschnittliche Intensität zwischen sich berührenden Objekten. Wenn eine Zelle übersegmentiert ist, werden mehrere Objekte innerhalb dieser Zelle gefunden. Der Bereich, in dem sich diese Objekte berühren, hat eine geringere Intensität als der Bereich, in dem sich zwei Zellen berühren. So können sie unterschieden werden. Die Normalisierung des Bildes wie oben gezeigt ist entscheidend.

  • centroid_distance: Der Abstand (in Pixeln oder Voxeln) zwischen den Schwerpunkten der markierten Objekte.

Hinweis: Die meisten Merkmale werden empfohlen, nur in isotropen Bildern verwendet zu werden.

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