Trennung sich berührender Objekte#

Ein häufiger Anwendungsfall für den Watershed-Algorithmus ist die Trennung sich berührender Objekte. In diesem Notebook werden wir Objekte in Binärbildern trennen, die eine rundliche Form haben und sich gegenseitig berühren.

from skimage.io import imread
import napari_segment_blobs_and_things_with_membranes as nsbatwm
import napari_simpleitk_image_processing as nsitk
import stackview

Ausgangspunkt dafür ist ein Binärbild, das beispielsweise durch Schwellenwertbildung erstellt wurde.

nuclei = imread('../../data/mitosis_mod.tif')

stackview.insight(nuclei)
shape(70, 70)
dtypeuint8
size4.8 kB
min8
max255
binary = nsbatwm.threshold_otsu(nuclei).astype(bool)

binary
<__array_function__ internals>:180: RuntimeWarning: Converting input from bool to <class 'numpy.uint8'> for compatibility.
nsbatwm made image
shape(70, 70)
dtypebool
size4.8 kB
minFalse
maxTrue

Wir können dann die sich berührenden Objekte trennen, indem wir nur das Binärbild berücksichtigen. Der zugrunde liegende Algorithmus zielt darauf ab, ähnliche Ergebnisse wie ImageJs binärer Watershed-Algorithmus zu produzieren, und die Implementierung hier funktioniert auch in 3D.

split_objects = nsbatwm.split_touching_objects(binary)
split_objects
nsbatwm made image
shape(70, 70)
dtypebool
size4.8 kB
minFalse
maxTrue

Die Funktion split_touching_objects hat auch einen Parameter sigma, der es ermöglicht zu steuern, wie aggressiv Objekte getrennt werden sollen. Um mehr Trennungen vorzunehmen, geben Sie eine kleinere Zahl als 3.5 ein, was der Standardwert ist.

split_objects2 = nsbatwm.split_touching_objects(binary, sigma=2)
split_objects2
nsbatwm made image
shape(70, 70)
dtypebool
size4.8 kB
minFalse
maxTrue

Es ist auch möglich, ein Labelbild als Ergebnis zu erhalten. Beachten Sie, dass in diesem Fall die schwarze Linie/Lücke zwischen den Objekten nicht vorhanden sein wird.

touching_labels = nsitk.touching_objects_labeling(binary)
touching_labels
n-sitk made image
shape(70, 70)
dtypeuint32
size19.1 kB
min0
max13