{
"cells": [
{
"cell_type": "markdown",
"id": "2d31db30-a623-4b57-b87b-aa4c456b1933",
"metadata": {},
"source": [
"## Trennung sich ber\u00fchrender Objekte\n",
"Ein h\u00e4ufiger Anwendungsfall f\u00fcr den Watershed-Algorithmus ist die Trennung sich ber\u00fchrender Objekte. In diesem Notebook werden wir Objekte in Bin\u00e4rbildern trennen, die eine rundliche Form haben und sich gegenseitig ber\u00fchren."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "80d09227-5427-40b3-b477-9d11877c35cf",
"metadata": {},
"outputs": [],
"source": [
"from skimage.io import imread\n",
"import napari_segment_blobs_and_things_with_membranes as nsbatwm\n",
"import napari_simpleitk_image_processing as nsitk\n",
"import stackview"
]
},
{
"cell_type": "markdown",
"id": "4b0d6b44-0d78-467b-bed7-071f67819f56",
"metadata": {},
"source": [
"Ausgangspunkt daf\u00fcr ist ein Bin\u00e4rbild, das beispielsweise durch [Schwellenwertbildung](image-segmentation:thresholding) erstellt wurde."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "87cb2de1-5fb3-443c-8048-c1803e524655",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"\n",
" \n",
" | \n",
"\n",
"\n",
"\n",
"shape | (70, 70) | \n",
"dtype | uint8 | \n",
"size | 4.8 kB | \n",
"min | 8 | max | 255 | \n",
" \n",
" \n",
" | \n",
"
\n",
"
"
],
"text/plain": [
"StackViewNDArray([[ 19, 29, 44, ..., 88, 115, 113],\n",
" [ 19, 29, 55, ..., 87, 101, 112],\n",
" [ 25, 36, 61, ..., 90, 90, 106],\n",
" ...,\n",
" [ 20, 21, 20, ..., 57, 33, 40],\n",
" [ 22, 25, 25, ..., 41, 34, 40],\n",
" [ 20, 25, 18, ..., 41, 35, 39]], dtype=uint8)"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nuclei = imread('../../data/mitosis_mod.tif')\n",
"\n",
"stackview.insight(nuclei)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "df9d6678-fb39-4bcb-9001-04c00264498b",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<__array_function__ internals>:180: RuntimeWarning: Converting input from bool to for compatibility.\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
" \n",
" | \n",
"\n",
"nsbatwm made image \n",
"\n",
"shape | (70, 70) | \n",
"dtype | bool | \n",
"size | 4.8 kB | \n",
"min | False | max | True | \n",
" \n",
" \n",
" | \n",
"
\n",
"
"
],
"text/plain": [
"StackViewNDArray([[False, False, False, ..., True, True, True],\n",
" [False, False, False, ..., True, True, True],\n",
" [False, False, False, ..., True, True, True],\n",
" ...,\n",
" [False, False, False, ..., False, False, False],\n",
" [False, False, False, ..., False, False, False],\n",
" [False, False, False, ..., False, False, False]])"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"binary = nsbatwm.threshold_otsu(nuclei).astype(bool)\n",
"\n",
"binary"
]
},
{
"cell_type": "markdown",
"id": "63e40577",
"metadata": {},
"source": [
"Wir k\u00f6nnen dann die sich ber\u00fchrenden Objekte trennen, indem wir nur das Bin\u00e4rbild ber\u00fccksichtigen. Der zugrunde liegende Algorithmus zielt darauf ab, \u00e4hnliche Ergebnisse wie [ImageJs bin\u00e4rer Watershed-Algorithmus](https://imagej.nih.gov/ij/docs/menus/process.html#watershed) zu produzieren, und die Implementierung hier funktioniert auch in 3D."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "a4740a57",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
" \n",
" | \n",
"\n",
"nsbatwm made image \n",
"\n",
"shape | (70, 70) | \n",
"dtype | bool | \n",
"size | 4.8 kB | \n",
"min | False | max | True | \n",
" \n",
" \n",
" | \n",
"
\n",
"
"
],
"text/plain": [
"StackViewNDArray([[False, False, False, ..., True, True, True],\n",
" [False, False, False, ..., True, True, True],\n",
" [False, False, False, ..., True, True, True],\n",
" ...,\n",
" [False, False, False, ..., False, False, False],\n",
" [False, False, False, ..., False, False, False],\n",
" [False, False, False, ..., False, False, False]])"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"split_objects = nsbatwm.split_touching_objects(binary)\n",
"split_objects"
]
},
{
"cell_type": "markdown",
"id": "87a98644-7bba-4d21-a2c0-75aaf16574e6",
"metadata": {},
"source": [
"Die Funktion `split_touching_objects` hat auch einen Parameter `sigma`, der es erm\u00f6glicht 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."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "94006d68-6c1e-4723-a244-c697e672f3b0",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
" \n",
" | \n",
"\n",
"nsbatwm made image \n",
"\n",
"shape | (70, 70) | \n",
"dtype | bool | \n",
"size | 4.8 kB | \n",
"min | False | max | True | \n",
" \n",
" \n",
" | \n",
"
\n",
"
"
],
"text/plain": [
"StackViewNDArray([[False, False, False, ..., True, True, True],\n",
" [False, False, False, ..., True, True, True],\n",
" [False, False, False, ..., True, True, True],\n",
" ...,\n",
" [False, False, False, ..., False, False, False],\n",
" [False, False, False, ..., False, False, False],\n",
" [False, False, False, ..., False, False, False]])"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"split_objects2 = nsbatwm.split_touching_objects(binary, sigma=2)\n",
"split_objects2"
]
},
{
"cell_type": "markdown",
"id": "8d3b4ab7-7a2a-4945-a13a-f39afaba8495",
"metadata": {},
"source": [
"Es ist auch m\u00f6glich, ein Labelbild als Ergebnis zu erhalten. Beachten Sie, dass in diesem Fall die schwarze Linie/L\u00fccke zwischen den Objekten nicht vorhanden sein wird."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "5ed59887-f13f-4ca9-bee3-b2fda27ecbc5",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
" \n",
" | \n",
"\n",
"n-sitk made image \n",
"\n",
"shape | (70, 70) | \n",
"dtype | uint32 | \n",
"size | 19.1 kB | \n",
"min | 0 | max | 13 | \n",
" \n",
"\n",
" | \n",
"
\n",
"
"
],
"text/plain": [
"StackViewNDArray([[0, 0, 0, ..., 2, 2, 2],\n",
" [0, 0, 0, ..., 2, 2, 2],\n",
" [0, 0, 0, ..., 2, 2, 2],\n",
" ...,\n",
" [0, 0, 0, ..., 0, 0, 0],\n",
" [0, 0, 0, ..., 0, 0, 0],\n",
" [0, 0, 0, ..., 0, 0, 0]], dtype=uint32)"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"touching_labels = nsitk.touching_objects_labeling(binary)\n",
"touching_labels"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a91eafee-498a-4a93-9c6a-7715ce7a9b6b",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.15"
}
},
"nbformat": 4,
"nbformat_minor": 5
}