{ "cells": [ { "cell_type": "markdown", "id": "6b25ab6a-6e72-499b-8e1c-596a1acf326e", "metadata": {}, "source": [ "# Innere und \u00e4u\u00dfere Zellgrenzen\n", "Bei der Untersuchung von Geweben, Organismen und Organoiden ist oft die Position und Orientierung der Zelle und ihrer Membranen innerhalb des Gewebes relevant. Zum Beispiel unterscheiden wir zwischen apikalen (an einer Spitze, am Ende, \u00e4u\u00dferen) und basalen (an der Basis, inneren) Seiten von Zellen innerhalb des Gewebes. Ausgehend von einem Zellsegmentierungs-Labelbild k\u00f6nnen wir Pixel identifizieren, die au\u00dferhalb oder innerhalb einer aus Zellen bestehenden Struktur liegen. Im folgenden Beispiel arbeiten wir mit einem synthetischen zweidimensionalen Bild einiger Zellen, die ein Organoid bilden. Die gleichen Funktionen funktionieren auch in 3D." ] }, { "cell_type": "code", "execution_count": 1, "id": "626f5f39-5098-4073-85ad-dba507e02258", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pyclesperanto_prototype as cle" ] }, { "cell_type": "markdown", "id": "d90dcfb3-062f-47f1-8bf7-f9d33778e364", "metadata": {}, "source": [ "Zuerst erstellen wir unseren synthetischen Datensatz. Er besteht aus 6 Zellzentren, die wir zu einem Organoid erweitert haben." ] }, { "cell_type": "code", "execution_count": 2, "id": "451f06eb-7ed0-444f-8ff7-bb8978993b00", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(100, 100)" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "points = np.asarray([\n", " [50, 50],\n", " [60, 60],\n", " [25, 40],\n", " [70, 30],\n", " [35, 65],\n", " [50, 25]\n", "]).T\n", "image = np.zeros((100, 100))\n", "spots = cle.pointlist_to_labelled_spots(points, image)\n", "cells = cle.dilate_labels(spots, radius=15)\n", "spots.shape" ] }, { "cell_type": "markdown", "id": "09eabbdf-6694-4708-b79d-5c20f554c481", "metadata": {}, "source": [ "Dies sind unsere Zellen:" ] }, { "cell_type": "code", "execution_count": 3, "id": "4118d3d7-a155-482b-bf7f-c2c4d877b099", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(100, 100)
dtypeuint32
size39.1 kB
min0.0
max6.0
\n", "\n", "
" ], "text/plain": [ "cl.OCLArray([[0, 0, 0, ..., 0, 0, 0],\n", " [0, 0, 0, ..., 0, 0, 0],\n", " [0, 0, 0, ..., 0, 0, 0],\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": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cells" ] }, { "cell_type": "markdown", "id": "a6a69fe3-ccf7-4bfc-b768-d7465cec1f3c", "metadata": {}, "source": [ "Und das ist das Organoid:" ] }, { "cell_type": "code", "execution_count": 4, "id": "430c2545-b765-427e-a001-6af31c372547", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(100, 100)
dtypeuint8
size9.8 kB
min0.0
max1.0
\n", "\n", "
" ], "text/plain": [ "cl.OCLArray([[0, 0, 0, ..., 0, 0, 0],\n", " [0, 0, 0, ..., 0, 0, 0],\n", " [0, 0, 0, ..., 0, 0, 0],\n", " ...,\n", " [0, 0, 0, ..., 0, 0, 0],\n", " [0, 0, 0, ..., 0, 0, 0],\n", " [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "organoid = cells > 0\n", "organoid" ] }, { "cell_type": "markdown", "id": "0772ee71-ff4e-4581-a111-d146c6c119dd", "metadata": {}, "source": [ "Wir identifizieren nun die Pixel, die sich an den Grenzen der Zellen befinden." ] }, { "cell_type": "code", "execution_count": 5, "id": "50881a14-b5a2-4855-943c-949fcb631b6a", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(100, 100)
dtypeuint32
size39.1 kB
min0.0
max6.0
\n", "\n", "
" ], "text/plain": [ "cl.OCLArray([[0, 0, 0, ..., 0, 0, 0],\n", " [0, 0, 0, ..., 0, 0, 0],\n", " [0, 0, 0, ..., 0, 0, 0],\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": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cell_borders = cle.reduce_labels_to_label_edges(cells)\n", "cell_borders" ] }, { "cell_type": "markdown", "id": "16f151e4-f006-459b-bce7-23b05b571f25", "metadata": {}, "source": [ "Wir k\u00f6nnen genau dasselbe mit dem Organoid machen, um die Pixel auf seiner Oberfl\u00e4che zu identifizieren." ] }, { "cell_type": "code", "execution_count": 6, "id": "0e02357b-f746-4867-b881-e9c962b653d3", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(100, 100)
dtypeuint32
size39.1 kB
min0.0
max1.0
\n", "\n", "
" ], "text/plain": [ "cl.OCLArray([[0, 0, 0, ..., 0, 0, 0],\n", " [0, 0, 0, ..., 0, 0, 0],\n", " [0, 0, 0, ..., 0, 0, 0],\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": [ "organoid_border = cle.reduce_labels_to_label_edges(organoid)\n", "organoid_border" ] }, { "cell_type": "markdown", "id": "d9d1ec4e-8f1f-4e45-b12a-ad37c18b020d", "metadata": {}, "source": [ "Indem wir die Zellgrenzen mit der Organoidgrenze maskieren - technisch gesehen ist das eine pixelweise Multiplikation - k\u00f6nnen wir die \u00e4u\u00dferen Grenzen identifizieren." ] }, { "cell_type": "code", "execution_count": 7, "id": "aa965a78-ef82-4e60-8909-eed3d68c0cd2", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(100, 100)
dtypeuint32
size39.1 kB
min0.0
max6.0
\n", "\n", "
" ], "text/plain": [ "cl.OCLArray([[0, 0, 0, ..., 0, 0, 0],\n", " [0, 0, 0, ..., 0, 0, 0],\n", " [0, 0, 0, ..., 0, 0, 0],\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": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "outer_borders = cle.mask(cell_borders, organoid_border).astype(np.uint32)\n", "outer_borders" ] }, { "cell_type": "markdown", "id": "11ef81d3-49ef-4bee-9bb6-2b491ec9d6ef", "metadata": {}, "source": [ "Wenn wir die \u00e4u\u00dferen Grenzen von allen Zellgrenzen abziehen, erhalten wir die inneren Grenzen" ] }, { "cell_type": "code", "execution_count": 8, "id": "452340c1-987d-41b1-8431-f9882cad6e10", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(100, 100)
dtypeuint32
size39.1 kB
min0.0
max6.0
\n", "\n", "
" ], "text/plain": [ "cl.OCLArray([[0, 0, 0, ..., 0, 0, 0],\n", " [0, 0, 0, ..., 0, 0, 0],\n", " [0, 0, 0, ..., 0, 0, 0],\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": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "inner_borders = (cell_borders - outer_borders).astype(np.uint32)\n", "inner_borders" ] }, { "cell_type": "markdown", "id": "afc73d32-96d9-4b23-b712-8fadde7a8edc", "metadata": {}, "source": [ "Bei der Nachbearbeitung dieser Labelbilder sollten Sie etwas vorsichtig sein, da diese Bilder m\u00f6glicherweise nicht sequenziell beschriftet sind. Es gibt Bibliotheken und Funktionen, die m\u00f6glicherweise Probleme mit solchen Labelbildern haben (z.B. `cle.statistics_of_labelled_pixels()`). Sie k\u00f6nnen die vorhandenen Labels in einem Labelbild mit `np.unique()` ausgeben und die Labelbilder mit `cle.relabel_sequential()` sequenziell machen." ] }, { "cell_type": "code", "execution_count": 9, "id": "a40a6826-5f21-4ba4-aafa-a2992a6332e1", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0, 2, 3, 4, 5, 6], dtype=uint32)" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.unique(outer_borders)" ] }, { "cell_type": "code", "execution_count": 10, "id": "7da3ec85-4bd0-4433-aa73-46641e24dbcf", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0, 1, 2, 3, 4, 5, 6], dtype=uint32)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.unique(inner_borders)" ] }, { "cell_type": "code", "execution_count": null, "id": "32e866b1-b41b-4965-a717-9c57d190fa73", "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 }