{ "cells": [ { "cell_type": "markdown", "id": "5b65aa36-e8aa-43c7-9537-4702066d9813", "metadata": {}, "source": [ "# Image filtering using cupy\n", "Cupy also comes with drop-in replacements for [scipy's ndimage](https://docs.scipy.org/doc/scipy/reference/ndimage.html) submodule called [cupyx.scipy.ndimage](https://docs.cupy.dev/en/stable/reference/scipy_ndimage.html). It allows us to call common functions such as `gaussian_filter()` with identical parameters.\n", "\n", "For importing this submodule, we use again a failsafe pattern:" ] }, { "cell_type": "code", "execution_count": 1, "id": "543ec996-3138-4797-9d6f-c548985cdd41", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "try:\n", " import cupy as xp\n", "except:\n", " import numpy as xp\n", "\n", "import numpy as np\n", "\n", "try:\n", " import cupyx.scipy.ndimage as xdi\n", "except:\n", " import scipy.ndimage as xdi\n", "\n", "import scipy.ndimage as ndi\n", " \n", "xdi" ] }, { "cell_type": "code", "execution_count": 2, "id": "ea540aa3-bf76-4438-a6fd-d4d375eae0ea", "metadata": { "tags": [] }, "outputs": [], "source": [ "from skimage.io import imread, imshow\n", "from timeit import timeit\n", "import stackview" ] }, { "cell_type": "code", "execution_count": 3, "id": "767d691b-c490-4b97-b783-9e0b93486681", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "cupy.ndarray" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "image = imread(\"../../data/blobs.tif\")\n", "\n", "xp_image = xp.asarray(image)\n", "\n", "type(xp_image)" ] }, { "cell_type": "markdown", "id": "9e7743be-35fe-4658-8b1a-e23e1ba82d03", "metadata": {}, "source": [ "We can then use the `xdi` alias to call the `gaussian_filter()` function without worrying if cupy is installed or not." ] }, { "cell_type": "code", "execution_count": 4, "id": "9770f953-4557-4978-bdde-e578aa9caf4c", "metadata": { "tags": [] }, "outputs": [], "source": [ "xp_blurred = xdi.gaussian_filter(xp_image, sigma=5)" ] }, { "cell_type": "markdown", "id": "cfad2f20-d2d5-4491-95d6-ec2ec80ac362", "metadata": {}, "source": [ "Before we can show the image, we must transfer it back to CPU memory and convert it to a numpy array." ] }, { "cell_type": "code", "execution_count": 5, "id": "24b1cf53-dc2a-4e21-8eaf-2ee40a070fbd", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
shape(254, 256)
dtypeuint8
size63.5 kB
min35
max237
\n", "\n", "
" ], "text/plain": [ "StackViewNDArray([[ 35, 35, 35, ..., 232, 232, 232],\n", " [ 35, 35, 35, ..., 232, 232, 232],\n", " [ 36, 36, 36, ..., 232, 232, 232],\n", " ...,\n", " [ 66, 66, 65, ..., 48, 48, 48],\n", " [ 66, 66, 65, ..., 49, 48, 48],\n", " [ 67, 66, 66, ..., 49, 48, 48]], dtype=uint8)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stackview.insight(xp_blurred)" ] }, { "cell_type": "markdown", "id": "44c6512d-b9d0-4d60-a3d4-db8c40e09c80", "metadata": {}, "source": [ "## Quick-and-dirty benchmarking\n", "To get a rough idea about potential speedup using cupy, one can use the [timeit](https://docs.python.org/3/library/timeit.html) jupyter magic." ] }, { "cell_type": "code", "execution_count": 6, "id": "38bf22c8-995b-4062-961f-859444709147", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "228 µs ± 8.87 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n" ] } ], "source": [ "%%timeit\n", "xdi.gaussian_filter(xp_image, sigma=5)" ] }, { "cell_type": "code", "execution_count": 7, "id": "7d76bc0b-5ffa-437a-8152-a60e91424a6f", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "305 µs ± 9.88 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n" ] } ], "source": [ "%%timeit\n", "xp_image = xp.asarray(image)\n", "xdi.gaussian_filter(xp_image, sigma=5)" ] }, { "cell_type": "code", "execution_count": 8, "id": "ae6d245d-a61b-455f-80eb-6ce16b8ebb2f", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.39 ms ± 22.8 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n" ] } ], "source": [ "%%timeit\n", "ndi.gaussian_filter(image, sigma=5)" ] }, { "cell_type": "markdown", "id": "6ae71e79-bc01-43fb-8cc2-6eaacb72d1d1", "metadata": {}, "source": [ "## Exercises\n", "Explore which other filters are available in cupy, and which not. Use the documentation:\n", "https://docs.cupy.dev/en/stable/reference/scipy_ndimage.html" ] }, { "cell_type": "code", "execution_count": null, "id": "7ff23ed1-a623-4c4d-8048-2d0776929616", "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.17" } }, "nbformat": 4, "nbformat_minor": 5 }