{ "cells": [ { "cell_type": "markdown", "id": "a326bb5d-0d7f-4e82-9813-6d84ec14fdeb", "metadata": {}, "source": [ "# The mode filter for correcting semantic segmentation results\n", "In descriptive statistics there exist multiple summary measures. The mean and the median filter for example allows locally averaging an image in different ways. The [mode](https://en.wikipedia.org/wiki/Mode_(statistics)) filter is less common but still useful in some scenarios. The mode of a pixel in its neighborhood corresponds to the most popular intensity among existing intensities. Thus, it can be used to get rid of indivdual pixels being wrongly classified in a [semantic segmentation](https://en.wikipedia.org/wiki/Image_segmentation#Groups_of_image_segmentation) result." ] }, { "cell_type": "code", "execution_count": 1, "id": "c901239c-ef6b-4ed7-ae9e-50cda4cc08da", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pyclesperanto_prototype as cle\n", "import stackview" ] }, { "cell_type": "markdown", "id": "87d6429a-4b83-45da-8e5a-dec6205d2e31", "metadata": {}, "source": [ "For demonstrating the filter, we create a semantic segmentation of blobs." ] }, { "cell_type": "code", "execution_count": 2, "id": "bc8fc582-5b5f-4366-90d5-6e8001700dcb", "metadata": {}, "outputs": [], "source": [ "blobs = cle.imread(\"../../data/blobs.tif\")" ] }, { "cell_type": "code", "execution_count": 3, "id": "34bc0cbd-d3b5-4fe5-afda-bc463ed33f30", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(254, 256)
dtypeuint32
size254.0 kB
min1.0
max3.0
\n", "\n", "
" ], "text/plain": [ "cl.OCLArray([[1, 1, 1, ..., 3, 2, 2],\n", " [1, 1, 1, ..., 3, 3, 3],\n", " [1, 1, 1, ..., 3, 3, 3],\n", " ...,\n", " [2, 2, 2, ..., 1, 1, 1],\n", " [2, 2, 2, ..., 1, 1, 1],\n", " [2, 2, 2, ..., 1, 1, 1]], dtype=uint32)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "semantic_segmentation = (blobs > 70) + \\\n", " (blobs > 200) + 1\n", "\n", "semantic_segmentation.astype(np.uint32)" ] }, { "cell_type": "markdown", "id": "5a05a5cf-3885-4008-b6d5-e88154b6abe4", "metadata": {}, "source": [ "Using the functions `mode_sphere` and `mode_box` we can make the result less noisy." ] }, { "cell_type": "code", "execution_count": 7, "id": "b666d7d6-ea7d-4802-9ec4-d13814567071", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(254, 256)
dtypeuint32
size254.0 kB
min1.0
max3.0
\n", "\n", "
" ], "text/plain": [ "cl.OCLArray([[1, 1, 1, ..., 3, 3, 3],\n", " [1, 1, 1, ..., 3, 3, 3],\n", " [1, 1, 1, ..., 3, 3, 3],\n", " ...,\n", " [2, 2, 2, ..., 1, 1, 1],\n", " [2, 2, 2, ..., 1, 1, 1],\n", " [2, 2, 2, ..., 1, 1, 1]], dtype=uint32)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cle.mode_sphere(semantic_segmentation, radius_x=2, radius_y=2).astype(np.uint32)" ] }, { "cell_type": "code", "execution_count": 8, "id": "cc69d6e0-1989-4ffa-b7b7-25f8aee0af8e", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(254, 256)
dtypeuint32
size254.0 kB
min1.0
max3.0
\n", "\n", "
" ], "text/plain": [ "cl.OCLArray([[1, 1, 1, ..., 3, 3, 3],\n", " [1, 1, 1, ..., 3, 3, 3],\n", " [1, 1, 1, ..., 3, 3, 3],\n", " ...,\n", " [2, 2, 2, ..., 1, 1, 1],\n", " [2, 2, 2, ..., 1, 1, 1],\n", " [2, 2, 2, ..., 1, 1, 1]], dtype=uint32)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cle.mode_sphere(semantic_segmentation, radius_x=4, radius_y=4).astype(np.uint32)" ] }, { "cell_type": "markdown", "id": "de18f21b-5e46-4240-90ad-6d38985f7898", "metadata": {}, "source": [ "When the radius becomes wider and wider, the result contains less and less local information." ] }, { "cell_type": "code", "execution_count": 10, "id": "a4a00b9c-eb1c-4ecd-b462-7fbbff5356c0", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(254, 256)
dtypeuint32
size254.0 kB
min1.0
max3.0
\n", "\n", "
" ], "text/plain": [ "cl.OCLArray([[1, 1, 1, ..., 3, 3, 3],\n", " [1, 1, 1, ..., 3, 3, 3],\n", " [1, 1, 1, ..., 3, 3, 3],\n", " ...,\n", " [1, 1, 1, ..., 1, 1, 1],\n", " [1, 1, 1, ..., 1, 1, 1],\n", " [1, 1, 1, ..., 1, 1, 1]], dtype=uint32)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cle.mode_sphere(semantic_segmentation, radius_x=10, radius_y=10).astype(np.uint32)" ] }, { "cell_type": "markdown", "id": "6485201b-184d-40db-a68c-87a1ae624a1a", "metadata": {}, "source": [ "Tuning the radius manually may help finding a good configuration." ] }, { "cell_type": "code", "execution_count": 5, "id": "a4e143f9-57d2-497d-b5ba-dccb9d38d38d", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "29760847e4dd421190ee3ae2666768d4", "version_major": 2, "version_minor": 0 }, "text/plain": [ "VBox(children=(interactive(children=(FloatSlider(value=1.0, description='radius', step=1.0), Output()), _dom_c…" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def mode_sphere(image, radius:float = 1):\n", " return cle.mode_sphere(image, radius_x=radius, radius_y=radius).astype(np.uint32)\n", "\n", "stackview.interact(mode_sphere, semantic_segmentation, zoom_factor=1.5)" ] }, { "cell_type": "code", "execution_count": null, "id": "6d02a820-d624-446a-b0b2-7b7421eee8c1", "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.13" } }, "nbformat": 4, "nbformat_minor": 5 }