{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Bead segmentation and measurements\n", "This notebook shows how to detect hot spots / local maxima / beads in an image and how to measure their FWHM. To make the algorithm work, the beads should be sufficiently sparse." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pyclesperanto_prototype as cle\n", "\n", "cle.get_device()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's start by making an image showing local maxima." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(512, 512)
dtypefloat32
size1024.0 kB
min0.0
max0.07532293
\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=float32)" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "from skimage.io import imshow\n", "\n", "random_image = np.random.random([512,512])\n", "binary_image = random_image > 0.9995\n", "\n", "# push to GPU\n", "input_image = cle.push(binary_image * random_image)\n", "\n", "# blur the image\n", "sigma = 3\n", "starting_point = cle.gaussian_blur(input_image, sigma_x=sigma, sigma_y=sigma)\n", "\n", "# show input image\n", "starting_point" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Local maxima detection" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(512, 512)
dtypeuint8
size256.0 kB
min0.0
max1.0
\n", "\n", "
" ], "text/plain": [ "cl.OCLArray([[1, 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": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "maxima = cle.detect_maxima_box(starting_point)\n", "maxima" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Local threshold determination" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[0. 0. 0.07530212 0.01768412 0.01768251 0.01768345\n", " 0.01768355 0.01767614 0.01768117 0.01768287 0.01767613 0.01767726\n", " 0.0176767 0.01767617 0.01770093 0.01768188 0.01769348 0.01768091\n", " 0.01768291 0.01767742 0.01767924 0.01767959 0.02023154 0.01767629\n", " 0.02023292 0.01767845 0.01767934 0.01768218 0.01767849 0.01767824\n", " 0.01768037 0.01767676 0.01767627 0.01768442 0.01767656 0.01768143\n", " 0.01768095 0.01768311 0.01783455 0.01767915 0.01783821 0.01768428\n", " 0.01767994 0.01768341 0.01767852 0.01768236 0.01768361 0.0176807\n", " 0.01768154 0.01767861 0.01767618 0.01767758 0.0176818 0.01768077\n", " 0.01767783 0.01768455 0.01768431 0.01767913 0.01767841 0.01768026\n", " 0.01768074 0.03163752 0.01798327 0.01768441 0.01768178 0.01767889\n", " 0.01798355 0.01768068 0.01768451 0.01768157 0.01767765 0.01768141\n", " 0.01768202 0.01767992 0.01768101 0.01767624 0.01768075 0.01768441\n", " 0.01768228 0.01768184 0.01767698 0.01768225 0.01768155 0.01767988\n", " 0.01767623 0.01768425 0.01768363 0.01767961 0.0176793 0.01767695\n", " 0.01768461 0.01768289 0.01767971 0.01768343 0.01768206 0.01768321\n", " 0.01768432 0.01768064 0.01768478 0.0176841 0.01768007 0.01767708\n", " 0.01768336 0.01768466 0.01770931 0.01788014 0.01787417 0.01771322\n", " 0.0176796 0.01767668 0.01767627 0.01768447 0.01767644 0.01768418\n", " 0.01768373 0.01768188 0.02103141 0.01768014 0.0210342 0.01767998\n", " 0.01767747 0.02028995 0.01767968 0.07532293]]\n", "[[0. 0. 0.03765106 0.00884206 0.00884125 0.00884173\n", " 0.00884178 0.00883807 0.00884058 0.00884144 0.00883806 0.00883863\n", " 0.00883835 0.00883809 0.00885046 0.00884094 0.00884674 0.00884045\n", " 0.00884145 0.00883871 0.00883962 0.00883979 0.01011577 0.00883814\n", " 0.01011646 0.00883923 0.00883967 0.00884109 0.00883925 0.00883912\n", " 0.00884018 0.00883838 0.00883813 0.00884221 0.00883828 0.00884072\n", " 0.00884047 0.00884156 0.00891728 0.00883957 0.0089191 0.00884214\n", " 0.00883997 0.0088417 0.00883926 0.00884118 0.00884181 0.00884035\n", " 0.00884077 0.00883931 0.00883809 0.00883879 0.0088409 0.00884039\n", " 0.00883892 0.00884228 0.00884215 0.00883956 0.00883921 0.00884013\n", " 0.00884037 0.01581876 0.00899163 0.00884221 0.00884089 0.00883945\n", " 0.00899178 0.00884034 0.00884226 0.00884078 0.00883882 0.0088407\n", " 0.00884101 0.00883996 0.00884051 0.00883812 0.00884037 0.00884221\n", " 0.00884114 0.00884092 0.00883849 0.00884112 0.00884077 0.00883994\n", " 0.00883812 0.00884212 0.00884181 0.00883981 0.00883965 0.00883847\n", " 0.00884231 0.00884144 0.00883986 0.00884171 0.00884103 0.00884161\n", " 0.00884216 0.00884032 0.00884239 0.00884205 0.00884004 0.00883854\n", " 0.00884168 0.00884233 0.00885465 0.00894007 0.00893709 0.00885661\n", " 0.0088398 0.00883834 0.00883813 0.00884224 0.00883822 0.00884209\n", " 0.00884187 0.00884094 0.01051571 0.00884007 0.0105171 0.00883999\n", " 0.00883874 0.01014498 0.00883984 0.03766147]]\n" ] } ], "source": [ "# Label maxima\n", "labeled_maxima = cle.label_spots(maxima)\n", "\n", "# read out intensities at the maxima\n", "max_intensities = cle.read_intensities_from_map(labeled_maxima, starting_point)\n", "print(max_intensities)\n", "\n", "# calculate thresholds\n", "thresholds = cle.multiply_image_and_scalar(max_intensities, scalar=0.5)\n", "print(thresholds)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Make a local threshold image" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(512, 512)
dtypeuint32
size1024.0 kB
min1.0
max123.0
\n", "\n", "
" ], "text/plain": [ "cl.OCLArray([[ 1, 1, 1, ..., 12, 12, 12],\n", " [ 1, 1, 1, ..., 12, 12, 12],\n", " [ 1, 1, 1, ..., 12, 12, 12],\n", " ...,\n", " [106, 106, 106, ..., 112, 112, 112],\n", " [106, 106, 106, ..., 112, 112, 112],\n", " [106, 106, 106, ..., 112, 112, 112]], dtype=uint32)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Extend labeled maxima until they touch\n", "voronoi_label_image = cle.extend_labeling_via_voronoi(labeled_maxima)\n", "voronoi_label_image" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(512, 512)
dtypefloat32
size1024.0 kB
min0.0
max0.037661467
\n", "\n", "
" ], "text/plain": [ "cl.OCLArray([[0. , 0. , 0. , ..., 0.00883835, 0.00883835,\n", " 0.00883835],\n", " [0. , 0. , 0. , ..., 0.00883835, 0.00883835,\n", " 0.00883835],\n", " [0. , 0. , 0. , ..., 0.00883835, 0.00883835,\n", " 0.00883835],\n", " ...,\n", " [0.00893709, 0.00893709, 0.00893709, ..., 0.00883822, 0.00883822,\n", " 0.00883822],\n", " [0.00893709, 0.00893709, 0.00893709, ..., 0.00883822, 0.00883822,\n", " 0.00883822],\n", " [0.00893709, 0.00893709, 0.00893709, ..., 0.00883822, 0.00883822,\n", " 0.00883822]], dtype=float32)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Replace labels with thresholds\n", "threshold_image = cle.replace_intensities(voronoi_label_image, thresholds)\n", "threshold_image" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(512, 512)
dtypeuint8
size256.0 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": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Apply threshold\n", "binary_segmented = cle.greater(starting_point, threshold_image)\n", "binary_segmented" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Measure bounding boxes" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "cle._ image
\n", "\n", "\n", "\n", "\n", "\n", "
shape(512, 512)
dtypeuint32
size1024.0 kB
min0.0
max117.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": [ "# Label objects\n", "labels = cle.connected_components_labeling_box(binary_segmented)\n", "labels" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Bounding box widths [ 7. 16. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7.\n", " 7. 11. 7. 7. 7. 7. 7. 7. 15. 7. 7. 7. 7. 7. 7. 7. 7. 7.\n", " 7. 13. 14. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7.\n", " 7. 8. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7.\n", " 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7.\n", " 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7.\n", " 7. 7. 7. 7. 7. 7. 7. 7. 7.]\n", "Bounding box heights [ 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7.\n", " 7. 12. 7. 7. 7. 7. 7. 7. 10. 7. 7. 7. 7. 7. 7. 7. 7. 7.\n", " 7. 9. 13. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7.\n", " 7. 13. 7. 7. 7. 7. 7. 3. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7.\n", " 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7.\n", " 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 3. 7.\n", " 7. 7. 7. 7. 7. 7. 7. 7. 7.]\n" ] } ], "source": [ "# Derive statistics\n", "stats = cle.statistics_of_labelled_pixels(label_image=labels)\n", "\n", "print('Bounding box widths', stats['bbox_width'])\n", "print('Bounding box heights', stats['bbox_height'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The bounding box width and height should be approximately twice as large as the sigma used for bluring the image at the very beginning." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sigma 3\n" ] } ], "source": [ "print(\"Sigma\", sigma)" ] }, { "cell_type": "code", "execution_count": null, "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": 4 }