{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# ITK in Python" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Learning Objectives\n", "\n", "* Learn how to write simple Python code with ITK\n", "* Become familiar with the functional and object-oriented interfaces to ITK in Python\n", "* Understand how to bridge ITK with machine learning libraries with [NumPy](https://numpy.org/)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Working with NumPy and friends\n", "\n", "* ITK is great at reading and processing images\n", "* Some algorithms are not available in ITK\n", "* NumPy is great at processing arrays in simple ways\n", "* NumPy arrays can be read by many other Python packages\n", " * [matplotlib](https://matplotlib.org)\n", " * [scikit-learn](https://scikit-learn.org)\n", " * [PyTorch](https://pytorch.org)\n", " * [TensorFlow](https://www.tensorflow.org)\n", " * [scikit-image](https://scikit-image.org)\n", " * [OpenCV](https://opencv.org)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "slideshow": { "slide_type": "subslide" }, "tags": [] }, "outputs": [], "source": [ "import itk\n", "\n", "from packaging.version import parse\n", "from importlib.metadata import version\n", "\n", "if parse(version('itk')) < parse('5.3'):\n", " raise ValueError(\"ITK greater than version 5.3.0 is required for this notebook\")\n", "\n", "from itkwidgets import view\n", "\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/html": [ "\n", " \n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "window.connectPlugin && window.connectPlugin(\"a1a409e0-26f1-4324-9230-fcb6a2cd79aa\")" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "image = itk.imread(\"data/KitwareITK.jpg\")\n", "view(image)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[51 56 60]\n" ] } ], "source": [ "array = itk.array_from_image(image)\n", "print(array[1, 1])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Let go the other way around: NumPy array to an ITK image. First, we create an array with some values." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "def make_gaussian(size, fwhm=3, center=None):\n", " \"\"\"Make a square gaussian kernel.\n", "\n", " size is the length of a side of the square\n", " fwhm is full-width-half-maximum, which\n", " can be considered an effective radius.\n", " \"\"\"\n", "\n", " x = np.arange(0, size, 1, np.float32)\n", " y = x[:, np.newaxis]\n", "\n", " if center is None:\n", " x0 = y0 = size // 2\n", " else:\n", " x0 = center[0]\n", " y0 = center[1]\n", "\n", " return np.exp(-4 * np.log(2) * ((x - x0) ** 2 + (y - y0) ** 2) / fwhm**2)\n", "\n", "\n", "array = make_gaussian(11)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Let's look at the array. We use `matplotlib` or `itkwidgets.view` to do this." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "(-0.5, 10.5, 10.5, -0.5)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.gray()\n", "plt.imshow(array)\n", "plt.axis(\"off\")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/html": [ "\n", " \n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "window.connectPlugin && window.connectPlugin(\"a1a409e0-26f1-4324-9230-fcb6a2cd79aa\")" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "image = itk.image_from_array(array)\n", "view(image, cmap=\"Grayscale\", interpolation=False)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Exercises" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Exercise 1: Visualize an image\n", "* Read an image with ITK\n", "* Apply a filter\n", "* Show both original image and filtered images with matplotlib" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "image = itk.imread(\"data/CBCT-TextureInput.png\", itk.F)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# %load solutions/2_ITK_in_Python_answers_Exercise1.py" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Views vs Copies" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "So far we have used\n", "\n", "- `itk.array_from_image()`\n", "- `itk.image_from_array()`.\n", "\n", "Also available:\n", "\n", "- `itk.array_view_from_image()`\n", "- `itk.image_view_from_array()`\n", "\n", "You can see the keyword **view** in both the names of these functions.\n", "\n", "How to they differ in their behavior?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Let's compare the result of `itk.array_view_from_image()` and `itk.array_from_image()`." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ "Text(0.5, 1.0, 'Copy')" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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TtyWe++916xdu9a8//77Ztu2baaystIEg0HzzjvvuNiEmO985zvmxRdfNHv37jV/+ctfTEVFhenXr5+pr683xiTPPvlnkUjEFBUVme9973vt7kvk/RIOh82OHTvMjh07jCTz0EMPmR07dph9+/YZY4z58Y9/bHJycsyaNWvMW2+9ZSZOnGhKS0tNa2trrMa1115rHnnkkdjfp3rPJQP6RmK8Pk+Uar2DvmG/byR0IDHGmEceecQUFRWZvn37miuuuMK88sorsfuuvvpqM23atLjxTz31lBk0aJDp27evGTp0qHnuued6eMbtSerwtnjx4tiYE7dl5syZse3Oy8sz//qv/2q2b9/e85M/wZQpU0xBQYHp27ev+cIXvmCmTJlidu/eHbs/WfbJP1u7dq2RZN5999129yXyftmwYUOHr6vj841Go2bOnDkmLy/PBAIBc91117XbxuLiYjNv3ry4ZSd7zyUL+ob71+eJUq130DfmxS2z0Td8xhjTtWMqAAAAdiXsOSQAAKD3IJAAAADnCCQAAMA5AgkAAHCOQAIAAJwjkAAAAOcIJAAAwDkCCQAAcI5AAgAAnCOQAAAA5wgkAADAuf8HVeDgUKquEnkAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "gaussian = itk.gaussian_image_source(size=11, sigma=3, scale=100, mean=[5, 5])\n", "\n", "arr_view_gaussian = itk.array_view_from_image(gaussian)\n", "arr_gaussian = itk.array_from_image(gaussian)\n", "\n", "gaussian.SetPixel([5, 5], 0)\n", "\n", "plt.subplot(1, 2, 1)\n", "plt.imshow(arr_view_gaussian)\n", "plt.title(\"View\")\n", "\n", "plt.subplot(1, 2, 2)\n", "plt.imshow(arr_gaussian)\n", "plt.title(\"Copy\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Exercise 2: ITK image to NumPy array\n", "\n", "* Read an image with ITK\n", "\n", "--\n", "\n", "* Convert image to NumPy array as a view\n", "* Modify a pixel in the image\n", "* Has the array been modified?\n", "\n", "--\n", "\n", "* Convert image to NumPy array as a copy\n", "* Modify a pixel in the image\n", "* Has the array been modified?" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# %load solutions/2_ITK_and_NumPy_answers_Exercise2.py" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Templated Types\n", "\n", "* Is my ITK type templated? (hint: usually, yes)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on itkTemplate in module itk.support.template_class object:\n", "\n", "itk::Image = class itkTemplate(collections.abc.Mapping)\n", " | itk::Image(new_object_name: str) -> 'itkTemplate'\n", " | \n", " | This class manages access to available template arguments of a C++ class.\n", " | \n", " | This class is generic and does not give help on the methods available in\n", " | the instantiated class. To get help on a specific ITK class, instantiate an\n", " | object of that class.\n", " | \n", " | e.g.: median = itk.MedianImageFilter[ImageType, ImageType].New()\n", " | help(median)\n", " | \n", " | There are two ways to access types:\n", " | \n", " | 1. With a dict interface. The user can manipulate template parameters\n", " | similarly to C++, with the exception that the available parameters sets are\n", " | chosen at compile time. It is also possible, with the dict interface, to\n", " | explore the available parameters sets.\n", " | 2. With object attributes. The user can easily find the available parameters\n", " | sets by pressing tab in interpreter like ipython\n", " | \n", " | Method resolution order:\n", " | itkTemplate\n", " | collections.abc.Mapping\n", " | collections.abc.Collection\n", " | collections.abc.Sized\n", " | collections.abc.Iterable\n", " | collections.abc.Container\n", " | builtins.object\n", " | \n", " | Methods defined here:\n", " | \n", " | GetTypes(self)\n", " | Helper method which prints out the available template parameters.\n", " | \n", " | GetTypesAsList(self)\n", " | Helper method which returns the available template parameters.\n", " | \n", " | New(self, *args, **kwargs)\n", " | Instantiate the template with a type implied from its input.\n", " | \n", " | Template type specification can be avoided by assuming that the type's\n", " | first template argument should have the same type as its primary input.\n", " | This is generally true. If it is not true, then specify the types\n", " | explicitly.\n", " | \n", " | For example, instead of the explicit type specification::\n", " | \n", " | median = itk.MedianImageFilter[ImageType, ImageType].New()\n", " | median.SetInput(reader.GetOutput())\n", " | \n", " | call::\n", " | \n", " | median = itk.MedianImageFilter.New(Input=reader.GetOutput())\n", " | \n", " | or, the shortened::\n", " | \n", " | median = itk.MedianImageFilter.New(reader.GetOutput())\n", " | \n", " | or:\n", " | \n", " | median = itk.MedianImageFilter.New(reader)\n", " | \n", " | __add__(self, paramSetString: str, cl: Callable[..., Any]) -> None\n", " | Add a new argument set and the resulting class to the template.\n", " | \n", " | paramSetString is the C++ string which defines the parameters set.\n", " | cl is the class which corresponds to the couple template-argument set.\n", " | \n", " | __call__(self, *args, **kwargs)\n", " | Deprecated procedural interface function.\n", " | \n", " | Use snake case function instead. This function is now\n", " | merely a wrapper around the snake case function (more\n", " | specifically around `__internal_call__()` to avoid\n", " | creating a new instance twice).\n", " | \n", " | Create a process object, update with the inputs and\n", " | attributes, and return the result.\n", " | \n", " | The syntax is the same as the one used in New().\n", " | \n", " | UpdateLargestPossibleRegion() is execute and the current output,\n", " | or tuple of outputs if there is more than one, is returned.\n", " | \n", " | For example,\n", " | \n", " | outputImage = itk.MedianImageFilter(inputImage, Radius=(1,2))\n", " | \n", " | __contains__(self, key)\n", " | \n", " | __dir__(self)\n", " | Returns the list of the attributes available in the current template.\n", " | \n", " | This loads all the modules that might be required by this template first,\n", " | and then returns the list of attributes. It is used when dir() is called\n", " | or when it tries to autocomplete attribute names.\n", " | \n", " | __find_param__(self, paramSetString) -> List[Any]\n", " | Find the parameters of the template.\n", " | \n", " | paramSetString is the C++ string which defines the parameters set.\n", " | \n", " | __find_param__ returns a list of itk classes, itkCType, and/or numbers\n", " | which correspond to the parameters described in paramSetString.\n", " | The parameters MUST have been registered before calling this method,\n", " | or __find_param__ will return a string and not the wanted object, and\n", " | will display a warning. Registration order is important.\n", " | \n", " | This method is not static only to be able to display the template name\n", " | in the warning.\n", " | \n", " | __getattr__(self, attr)\n", " | Support for lazy loading.\n", " | \n", " | __getitem__(self, parameters) -> Callable[..., Any]\n", " | Return the class which corresponds to the given template parameters.\n", " | \n", " | parameters can be:\n", " | - a single parameter (Ex: itk.Index[2])\n", " | - a list of elements (Ex: itk.Image[itk.UC, 2])\n", " | \n", " | __getnewargs_ex__(self)\n", " | Return arguments for __new__.\n", " | Required by the Pickle protocol.\n", " | \n", " | __hash__(self)\n", " | Overloads `hash()` when called on an `itkTemplate` object.\n", " | \n", " | Identify with the __name__, e.g. `itk.Image.__name__` is `itk::Image`.\n", " | Used by frozenset construction in typing._GenericAlias\n", " | \n", " | __instancecheck__(self, instance) -> bool\n", " | Overloads `isinstance()` when called on an `itkTemplate` object.\n", " | \n", " | This function allows to compare an object to a filter without\n", " | specifying the actual template arguments of the class. It will\n", " | test all available template parameters that have been wrapped\n", " | and return `True` if one that corresponds to the object is found.\n", " | \n", " | __iter__(self)\n", " | # everything after this comment is for dict interface\n", " | # and is a copy/paste from DictMixin\n", " | # only methods to edit dictionary are not there\n", " | \n", " | __len__(self)\n", " | \n", " | __local__init__(self, new_object_name: str) -> None\n", " | Can not have a __init__ because we must use __new__\n", " | so that the singleton takes preference.\n", " | Use this to define the class member elements\n", " | \n", " | __repr__(self) -> str\n", " | Return repr(self).\n", " | \n", " | get(self, key, default=None)\n", " | D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.\n", " | \n", " | items(self)\n", " | D.items() -> a set-like object providing a view on D's items\n", " | \n", " | keys(self)\n", " | D.keys() -> a set-like object providing a view on D's keys\n", " | \n", " | values(self)\n", " | D.values() -> an object providing a view on D's values\n", " | \n", " | ----------------------------------------------------------------------\n", " | Static methods defined here:\n", " | \n", " | __new__(cls, new_object_name: str) -> 'itkTemplate'\n", " | Create and return a new object. See help(type) for accurate signature.\n", " | \n", " | normalizeName(name: str) -> str\n", " | Normalize the class name to remove ambiguity\n", " | \n", " | This function removes the white spaces in the name, and also\n", " | remove the pointer declaration \"*\" (it have no sense in python)\n", " | \n", " | registerNoTpl(name: str, cl: 'itkTemplate') -> None\n", " | Register a class without template\n", " | \n", " | It can seem not useful to register classes without template (and it wasn't\n", " | useful until the SmartPointer template was generated), but those classes\n", " | can be used as template argument of classes with template.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Data descriptors defined here:\n", " | \n", " | __dict__\n", " | dictionary for instance variables\n", " | \n", " | __weakref__\n", " | list of weak references to the object\n", " | \n", " | ----------------------------------------------------------------------\n", " | Data and other attributes defined here:\n", " | \n", " | __abstractmethods__ = frozenset()\n", " | \n", " | ----------------------------------------------------------------------\n", " | Methods inherited from collections.abc.Mapping:\n", " | \n", " | __eq__(self, other)\n", " | Return self==value.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Data and other attributes inherited from collections.abc.Mapping:\n", " | \n", " | __reversed__ = None\n", " | \n", " | ----------------------------------------------------------------------\n", " | Class methods inherited from collections.abc.Collection:\n", " | \n", " | __subclasshook__(C) from abc.ABCMeta\n", " | Abstract classes can override this to customize issubclass().\n", " | \n", " | This is invoked early on by abc.ABCMeta.__subclasscheck__().\n", " | It should return True, False or NotImplemented. If it returns\n", " | NotImplemented, the normal algorithm is used. Otherwise, it\n", " | overrides the normal algorithm (and the outcome is cached).\n", " | \n", " | ----------------------------------------------------------------------\n", " | Class methods inherited from collections.abc.Iterable:\n", " | \n", " | __class_getitem__ = GenericAlias(...) from abc.ABCMeta\n", " | Represent a PEP 585 generic type\n", " | \n", " | E.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).\n", "\n" ] } ], "source": [ "help(itk.Image)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "* If so, you need to specify the data type\n", "* This is similar to `dtype` in NumPy" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "array([0., 0.])" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy\n", "\n", "numpy.array([0, 0], dtype=float)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "* Define and create a simple object" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "itkIndex3 ([0, 0, 0])\n" ] } ], "source": [ "# A pixel Index is templated over the image dimension\n", "IndexType = itk.Index[3]\n", "index = IndexType()\n", "print(index)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "* Define and use smart pointer object" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Image (0x561be6e990f0)\n", " RTTI typeinfo: itk::Image\n", " Reference Count: 1\n", " Modified Time: 868\n", " Debug: Off\n", " Object Name: \n", " Observers: \n", " none\n", " Source: (none)\n", " Source output name: (none)\n", " Release Data: Off\n", " Data Released: False\n", " Global Release Data: Off\n", " PipelineMTime: 0\n", " UpdateMTime: 0\n", " RealTimeStamp: 0 seconds \n", " LargestPossibleRegion: \n", " Dimension: 2\n", " Index: [0, 0]\n", " Size: [0, 0]\n", " BufferedRegion: \n", " Dimension: 2\n", " Index: [0, 0]\n", " Size: [0, 0]\n", " RequestedRegion: \n", " Dimension: 2\n", " Index: [0, 0]\n", " Size: [0, 0]\n", " Spacing: [1, 1]\n", " Origin: [0, 0]\n", " Direction: \n", "1 0\n", "0 1\n", "\n", " IndexToPointMatrix: \n", "1 0\n", "0 1\n", "\n", " PointToIndexMatrix: \n", "1 0\n", "0 1\n", "\n", " Inverse Direction: \n", "1 0\n", "0 1\n", "\n", " PixelContainer: \n", " ImportImageContainer (0x561bea401390)\n", " RTTI typeinfo: itk::ImportImageContainer\n", " Reference Count: 1\n", " Modified Time: 869\n", " Debug: Off\n", " Object Name: \n", " Observers: \n", " none\n", " Pointer: 0\n", " Container manages memory: true\n", " Size: 0\n", " Capacity: 0\n", "\n" ] } ], "source": [ "ImageType = itk.Image[itk.ctype(\"float\"), 2]\n", "my_image = ImageType.New()\n", "print(my_image)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "* Print list of available types" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Options:\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 5]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 5]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 5]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n", " [, 2]\n", " [, 3]\n", " [, 4]\n" ] } ], "source": [ "itk.Image.GetTypes()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Non-templated Types\n", "\n", "* `MetaDataDictionary`" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "'new_key' value: 5\n" ] } ], "source": [ "d = itk.MetaDataDictionary()\n", "d[\"new_key\"] = 5\n", "print(f\"'new_key' value: {d['new_key']}\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Python Sequences for of ITK Objects\n", "\n", "* Some ITK objects expect inputs of a certain ITK type. However, it is often more convenient to directly provide Python sequences, i.e. a `list` or `tuple`." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on method itkImageBase2_SetOrigin:\n", "\n", "itkImageBase2_SetOrigin(...) method of itk.itkImagePython.itkImageF2 instance\n", " SetOrigin(self, _arg)\n", " \n", " Parameters\n", " ----------\n", " _arg: itkPointD2 const\n", " \n", " SetOrigin(self, origin)\n", " \n", " Parameters\n", " ----------\n", " origin: double const *\n", " \n", " SetOrigin(self, origin)\n", " \n", " Parameters\n", " ----------\n", " origin: float const *\n", "\n" ] } ], "source": [ "image = ImageType.New()\n", "help(image.SetOrigin)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "* Use a Python `list` where an `itk.Index`, `itk.Point`, or `itk.Vector` is requested." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Image origin: itkPointD2 ([2, 10])\n", "Image origin: [2.0, 10.0]\n", "Image origin: (2.0, 10.0)\n" ] } ], "source": [ "image.SetOrigin([2, 10])\n", "print(f\"Image origin: {str(image.GetOrigin())}\")\n", "print(f\"Image origin: {str(list(image.GetOrigin()))}\")\n", "print(f\"Image origin: {str(tuple(image.GetOrigin()))}\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# scikit-learn" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "* *scikit-learn* is a machine learning package in Python.\n", "* scikit-learn is used to illustrate solving a problem using ITK and *NumPy* arrays." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "import sklearn" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "First, we load 10 2D-images of circles with different radii and center position to which noise has been added and their corresponding ground truth segmentations." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "itkSize2 ([50, 50])\n" ] }, { "data": { "text/plain": [ "Text(0.5, 1.0, 'Segmentation')" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAEjCAYAAACSDWOaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABKfUlEQVR4nO3deVTV57U38C+oIDKpqDiCszhrEA3OAwatGo0mZrpXo2lsU7RRm9XUvs3Um9SstPcmMTHDbVNNUq2JSTRz1DigUXHACSeixoGI4AyKAgq/94+8nJdnP1sFhR8H+X7WYq3sH/uc85zBXx7O2WdvH8dxHBARERG5xLeiF0BERERVCzcfRERE5CpuPoiIiMhV3HwQERGRq7j5ICIiIldx80FERESu4uaDiIiIXMXNBxEREbmKmw8iIiJyFTcfRERExfj4+OC5556r6GXc1rj5qKLmz58PHx8fbN26taKXQkQllJKSgnvvvReRkZGoWbMmmjRpgqFDh+L111+v6KW5Kj09Hc899xx27Nhx09fx9ddfc4NRgbj5ICKqBDZs2IAePXpg586deOyxx/DGG2/gl7/8JXx9ffHaa69V9PJclZ6ejueff/6WNx/PP/+8+rvLly/jT3/6001fN91Y9YpeABER3diLL76I0NBQbNmyBbVr1zZ+d/LkyYpZ1G2qZs2aFb2E2x7f+SAAwCOPPIKgoCAcO3YMI0eORFBQEJo0aYK5c+cC+Pnt3sGDByMwMBCRkZFYuHChcfmzZ8/iySefROfOnREUFISQkBAMHz4cO3futG7r6NGjuPvuuxEYGIgGDRpgxowZWLZsGXx8fLBmzRojd9OmTRg2bBhCQ0NRq1YtDBgwAOvXry+3x4HIWx06dAgdO3a0Nh4A0KBBAyP+17/+hejoaAQEBKBu3bp44IEHkJaWZl1u7ty5aNmyJQICAtCzZ0+sW7cOAwcOxMCBAz05a9asgY+PDz766CM8//zzaNKkCYKDg3HvvfciKysLeXl5mD59Oho0aICgoCBMmjQJeXl51m2VZE0DBw5Ep06dsHfvXgwaNAi1atVCkyZN8PLLLxvriYmJAQBMmjQJPj4+8PHxwfz58wEA69atw3333YeIiAj4+/ujWbNmmDFjBi5fvuy5jkceecRzbiu6vI+Pj+f3Ws3H9u3bMXz4cISEhCAoKAhDhgxBUlKSkVP0cfb69esxc+ZM1K9fH4GBgbjnnntw6tQp6zGpyvjOB3kUFBRg+PDh6N+/P15++WUsWLAAU6dORWBgIP7P//k/ePjhhzF27Fi8/fbbmDBhAmJjY9GiRQsAwI8//oilS5fivvvuQ4sWLZCZmYl33nkHAwYMwN69e9G4cWMAQE5ODgYPHowTJ07giSeeQMOGDbFw4UKsXr3aWs+qVaswfPhwREdH49lnn4Wvry/mzZuHwYMHY926dejZs6erjw9RRYqMjMTGjRuxe/dudOrU6Zp5L774Ip5++mmMHz8ev/zlL3Hq1Cm8/vrr6N+/P7Zv3+7ZvLz11luYOnUq+vXrhxkzZuDIkSMYM2YM6tSpg6ZNm1rXO3v2bAQEBOAPf/gDDh48iNdffx01atSAr68vzp07h+eeew5JSUmYP38+WrRogWeeeabUawKAc+fOYdiwYRg7dizGjx+Pjz/+GE899RQ6d+6M4cOHo3379vjzn/+MZ555BlOmTEG/fv0AAL179wYALF68GJcuXcLjjz+OsLAwbN68Ga+//jp++uknLF68GADwq1/9Cunp6VixYgU++OCDGz72e/bsQb9+/RASEoLf//73qFGjBt555x0MHDgQiYmJ6NWrl5E/bdo01KlTB88++yyOHDmCV199FVOnTsWHH354w9uqMhyqkubNm+cAcLZs2eI4juNMnDjRAeD85S9/8eScO3fOCQgIcHx8fJxFixZ5ju/fv98B4Dz77LOeY7m5uU5BQYFxG4cPH3b8/f2dP//5z55j//3f/+0AcJYuXeo5dvnyZScqKsoB4KxevdpxHMcpLCx02rRp48THxzuFhYWe3EuXLjktWrRwhg4dWiaPA1FlsXz5cqdatWpOtWrVnNjYWOf3v/+9s2zZMic/P9+Tc+TIEadatWrOiy++aFw2JSXFqV69uud4Xl6eExYW5sTExDhXrlzx5M2fP98B4AwYMMBzbPXq1Q4Ap1OnTsZtPfjgg46Pj48zfPhw47ZiY2OdyMjIUq/JcRxnwIABDgDn/fff9xzLy8tzGjZs6IwbN85zbMuWLQ4AZ968edbjdOnSJevY7NmzHR8fH+fo0aOeYwkJCc61/hcoz29jxoxx/Pz8nEOHDnmOpaenO8HBwU7//v09x4rOq3FxccZ5a8aMGU61atWc8+fPq7dXFfFjFzL88pe/9Px37dq10a5dOwQGBmL8+PGe4+3atUPt2rXx448/eo75+/vD1/fnl1NBQQHOnDmDoKAgtGvXDtu2bfPkffvtt2jSpAnuvvtuz7GaNWviscceM9axY8cOHDhwAA899BDOnDmD06dP4/Tp08jJycGQIUOwdu1aFBYWlvn9J/JWQ4cOxcaNG3H33Xdj586dePnllxEfH48mTZrg888/BwB8+umnKCwsxPjx4z3/Zk6fPo2GDRuiTZs2nncYt27dijNnzuCxxx5D9er//w3whx9+GHXq1FFvf8KECahRo4Yn7tWrFxzHweTJk428Xr16IS0tDVevXi3VmooEBQXhP/7jPzyxn58fevbsaZxvricgIMDz3zk5OTh9+jR69+4Nx3Gwffv2El1HcQUFBVi+fDnGjBmDli1beo43atQIDz30EL7//ntkZ2cbl5kyZYrxMU6/fv1QUFCAo0ePlvr2b1f82IU8atasifr16xvHQkND0bRpU+MfUtHxc+fOeeLCwkK89tprePPNN3H48GEUFBR4fhcWFub576NHj6JVq1bW9bVu3dqIDxw4AACYOHHiNdeblZV1zRMl0e0oJiYGn376KfLz87Fz504sWbIEr7zyCu69917Pht1xHLRp00a9fNHmoeh/gvLfXfXq1dG8eXP1shEREUYcGhoKAGjWrJl1vLCwEFlZWQgLCyvxmopo55s6depg165d6uWlY8eO4ZlnnsHnn39unKOAn88ZpXXq1ClcunQJ7dq1s37Xvn17FBYWIi0tDR07dvQcl49V0XlKrqcq4+aDPKpVq1aq447jeP77L3/5C55++mlMnjwZ//Vf/4W6devC19cX06dPv6l3KIou89e//hXdunVTc4KCgkp9vUS3Az8/P8TExCAmJgZt27bFpEmTsHjxYhQWFsLHxwfffPON+u/2Vv7N3Oz5obRrKsn55loKCgowdOhQnD17Fk899RSioqIQGBiI48eP45FHHnHt3dJbuQ9VBTcfVCY+/vhjDBo0CO+++65x/Pz586hXr54njoyMxN69e+E4jvHXzcGDB43LtWrVCgAQEhKCuLi4clw5UeXWo0cPAMCJEyfQqlUrOI6DFi1aoG3btte8TGRkJICf/90NGjTIc/zq1as4cuQIunTpUmbrK+maSkO+M1IkJSUFP/zwA9577z1MmDDBc3zFihUlvg6pfv36qFWrFlJTU63f7d+/H76+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IyIqC3zng4iIiFzFzQcRERG5ipsPIiIichU3H0REROQqry04zc7ONhodyWZgiYmJ1mVGjx5txNq008OHDxuxbEYFAI8//rgR9+3b18o5fvy4EWuNpeSa09PTrZyePXsasdasTDax0gpXL168aMRaQWOXLl2MWDaaAuz7FRgYaOXI+6oV227dutU61rFjRyPWpnvK4lFZIAwA33//vRF37tz5hjlawWnjxo2NWJtGKyfCatcji6G1QmfZmE2bsiunMmsTfV977TUjls8pAMTExBjx4sWLrZz169cbsSz+lRN/6eZwgi2Rju98EBERkau4+SAiIiJXcfNBRERErvLamo9Dhw4Zn5OHhIQYv//Tn/5kXUY20dKaT8laAG0omhzwJYeCAXaNhVZfIpue3XHHHVZORESEEWuDwmTdRe/eva0cOXjP19feV8pje/bssXJk3cGaNWusHFkrodV3aAP7HnzwQSNevny5lSNrIfLy8qycgoICI9buhxwapz0e+/fvN2KtoZqsEWrfvr2VIx8jbTigbBSn1Y7Uq1fPiE+cOGHlyLom2cgOAN5++20jljUpgD047ty5c0asDW4kIiorfOeDiIiIXMXNBxEREbmKmw8iIiJyFTcfRERE5CqvLTiVZNMsrZhUK3KU7rzzTiOWRYcAsHv3biPWpov+6le/MmJtsqucbqqtWRbStm3b1sq5evWqEctCVo3W+EsWamrNyurUqWPE2n2XTay0gtyNGzdaxz7++GMjloW9gF2UK4swAWDhwoVG3L17dytHPq5agzf5etEaQp08edKItcJVOY1We55lYzY5vRewi21lATVgPx7aFOSJEycasWwcB9gN5uRzIQtSiYjKEt/5ICIiIldx80FERESu4uaDiIiIXFVpaj7atGljxLJ+AbA/59fI+oRGjRpZObL5VdeuXa0c+Xn8hQsXrJzNmzcbcXx8vJXzySefGHG3bt2sHLlm7b4PGjTIiLXmYHXr1jXi+vXrWzkDBw40Yq1+4fTp0ze8La2JlqzN6NGjh5UjHzOtgZlszCbrVAAgODjYiOXgNABISkoyYm04YGRkpBHLZlyAXQcia30A+/WhDRAsLCw04gYNGlg5spmc1ogsLCzsujFgN5OTtT25ubnWZYiIygrf+SAiIiJXcfNBREREruLmg4iIiFzFzQcRERG5ymsLTuvUqQN/f39P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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "l_label = []\n", "l_image = []\n", "\n", "for i in range(0, 10):\n", " image_name = \"data/sklearn/im%d.nrrd\" % i\n", " image = itk.imread(image_name, itk.F)\n", " array = itk.array_from_image(image)\n", " l_image.append(array)\n", "\n", " label_name = \"data/sklearn/im%d_label.nrrd\" % i\n", " image = itk.imread(label_name, itk.UC)\n", " array = itk.array_from_image(image)\n", " l_label.append(array)\n", "\n", "size = itk.size(image)\n", "print(size)\n", "\n", "plt.subplot(1, 2, 1)\n", "plt.imshow(l_image[0])\n", "plt.title(\"Image\")\n", "\n", "plt.subplot(1, 2, 2)\n", "plt.imshow(l_label[0])\n", "plt.title(\"Segmentation\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "The goal is to find the segmentation based on the input image." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "We create arrays of data:\n", "* X - the input samples\n", "* Y - the target values" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "X0 = l_image[0].flatten()\n", "X = X0\n", "\n", "Y = l_label[0].flatten()\n", "\n", "for i in range(1, 10):\n", " X = np.concatenate((X, l_image[i].flatten()))\n", " Y = np.concatenate((Y, l_label[i].flatten()))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "* We use a supervised learning methods based on Bayes’ theorem.\n", "* The only information provided to the algorithm is the image intensity value." ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAaAAAAGfCAYAAAAZGgYhAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAdiUlEQVR4nO3df2jc9R3H8dfFNFdne5em6sXSZCsoVpF2GG09HBuzmUVE6hrBgbDOyUSXFtsONgNTGQxSFPxRV3+wH8pgNaODKhXUlagpY2nXRotVZ3BQ1ox6V/0jdzUzaWk++6P03NnkLnff++b9+V6eD/hC+7277/fz/dz37sUn9/58vzHnnBMAALOswboBAIC5iQACAJgggAAAJgggAIAJAggAYIIAAgCYIIAAACYIIACACQIIAGCCAAIAmGgMa8M7duzQY489pkwmo5UrV+rpp5/WqlWryr5ucnJSx48f18KFCxWLxcJqHgAgJM45nTx5UkuWLFFDQ4lxjgtBX1+fa2pqcn/4wx/cBx984H7yk5+45uZml81my752ZGTESWJhYWFhifgyMjJS8vs+5lztL0a6evVqXX/99frNb34j6eyopq2tTZs2bdKDDz5Y8rW5XE7Nzc0lHy8lmUxW3N6ZbDvIdoPwsU3VKvfelRLW+xpFpfoirD6utz6sN2F9F1T7vufzebW1tWl0dLRk22r+J7hTp05paGhIPT09hXUNDQ3q7OzU4ODgec+fmJjQxMRE4f8nT54suf1EIlG7xs7itqvlY5uqZXUs9dSH5YR1rHOpD/GloO97uZ9Ral6E8Nlnn+nMmTNKpVJF61OplDKZzHnP7+3tVTKZLCxtbW21bhIAwEPmVXA9PT3K5XKFZWRkxLpJAIBZUPM/wV188cW64IILlM1mi9Zns1m1trae9/x4PK54PF7rZgAAPFfzEVBTU5M6OjrU399fWDc5Oan+/n6l0+kZbyeXy8k5d95SzlSvmelrq91uuSWIWCw27RKWIMdT6nWljqXcgi9ZnONR5OP5FOQzUGqxeu+ma89MiyJCmQe0detWbdiwQdddd51WrVqlJ598UmNjY7r77rvD2B0AIIJCCaA777xTn376qR5++GFlMhl985vf1Ouvv35eYQIAYO4KZR5QEPl8XslkUrlcrualn+WG3mF1RdT+hFSuH0odT6nXWvWDZ6c4Zkm152mYwvoMhPW5C/JdIKns97h5FRwAYG4igAAAJgggAIAJAggAYCK02zGEJcwfsi1+JA/6I18Y+w2yT4v21hurYpkggvzgH1axgI/9FORz5+PxBMUICABgggACAJgggAAAJgggAIAJAggAYIIAAgCYiFwZdpBSRB+vyeZj6aVV2SzOimIf1lu5tMU57uN3W9jfmYyAAAAmCCAAgAkCCABgggACAJgggAAAJgggAIAJAggAYMLbeUDJZHLK9Va3LwhLWMdTb/1kNV+KOU9nBel/H+e6leNjm0oJ6/YqYX+PMAICAJgggAAAJgggAIAJAggAYIIAAgCYIIAAACa8LcPO5XJKJBLnrfexHLcci8u3h1lm7eMtIuptv76pt9stlBNW+T23eSjGCAgAYIIAAgCYIIAAACYIIACACQIIAGCCAAIAmPC2DLtaQcocwyo5DKuEO6z2WpXNWpSoRvFKzQhfte/7XLtqeFCMgAAAJgggAIAJAggAYIIAAgCYIIAAACYIIACACQIIAGCi7uYBlRL2pcXDUG2bw7wEu4+XjQ9rnxZzkxBd9XY+VdumfD6vZDJZ9nmMgAAAJgggAIAJAggAYIIAAgCYIIAAACYIIACACW/LsGdSwjeVsC53blXCXW2bwiylDqs03McSVR9LYxFd9XY+Bf1eZAQEADBBAAEATBBAAAATBBAAwAQBBAAwQQABAEwQQAAAE97OA5pOmHNJqn1tmPOLfJxzE9Z8nXqbIwHUUpTmyXE7BgCA1wggAIAJAggAYIIAAgCYIIAAACYIIACAiYoDaN++fbrtttu0ZMkSxWIxvfzyy0WPO+f08MMP67LLLtOFF16ozs5OffzxxxU3LJfLyTl33lLOVK+pxWtjsdi0SzlBXmtxrEGEdayIrlLnBOfFzIX1mbVUcQCNjY1p5cqV2rFjx5SPP/roo9q+fbuee+45HThwQBdddJHWrl2r8fHxwI0FANSPiiei3nLLLbrlllumfMw5pyeffFK//OUvtW7dOknSH//4R6VSKb388sv6wQ9+EKy1AIC6UdPfgI4ePapMJqPOzs7CumQyqdWrV2twcHDK10xMTCifzxctAID6V9MAymQykqRUKlW0PpVKFR77qt7eXiWTycLS1tZWyyYBADxlXgXX09OjXC5XWEZGRqybBACYBTUNoNbWVklSNpstWp/NZguPfVU8HlcikShaAAD1r6YBtGzZMrW2tqq/v7+wLp/P68CBA0qn0zXZR7mSziALZqZUOWg9lopWi3PtLM6L2qjH86niKrjPP/9c//rXvwr/P3r0qA4fPqyWlha1t7dr8+bN+vWvf60rrrhCy5Yt00MPPaQlS5bo9ttvr2W7AQARV3EAHTp0SN/97ncL/9+6daskacOGDXrxxRf185//XGNjY7r33ns1Ojqqb33rW3r99dc1f/782rUaABB5MefZGPjcjYxyudyUvweFOdwMcuM4C569dfgKH28ghuiK0vlU7nv8HPMqOADA3EQAAQBMEEAAABMEEADARMVVcLMlmUzO+j6r/ZGvXIGCbz8QYnZYvO9BzsUo/cg9F9Xje8AICABgggACAJgggAAAJgggAIAJAggAYIIAAgCY8LYMO4xrwQUpYwyyX6s2Y+4Jcr5wrqFSQa+RyQgIAGCCAAIAmCCAAAAmCCAAgAkCCABgggACAJgggAAAJrydBxSGsObjBK2F9w23l7BF/yMqpjsX8/n8jG6pwwgIAGCCAAIAmCCAAAAmCCAAgAkCCABgggACAJiYU2XY5YRVah21stmotbfe0P+YSqnvoKieM4yAAAAmCCAAgAkCCABgggACAJgggAAAJgggAIAJb8uwZ3Il1akEKaWut6taA6gf1ZZa+3x1dUZAAAATBBAAwAQBBAAwQQABAEwQQAAAEwQQAMAEAQQAMOHtPKBq+TiXZy7dysFH9XgZ+zDQT/XJ5/eOERAAwAQBBAAwQQABAEwQQAAAEwQQAMAEAQQAMFF3ZdilhFWO6GOZdZBLsPt8+fZqWLU3amXNPrYJX4ra+TQTjIAAACYIIACACQIIAGCCAAIAmCCAAAAmCCAAgAkCCABgou7mAQWZ31JPgswLiOqcAt/Qj/7yca6bVZss5xcxAgIAmCCAAAAmCCAAgAkCCABgggACAJgggAAAJioKoN7eXl1//fVauHChLr30Ut1+++0aHh4ues74+Li6u7u1ePFiLViwQF1dXcpmsxU3LJfLyTl33hLEVNub6RLWfn0Ui8VKLkAlfDyfgnzewzqWML+Dqt1v2CoKoIGBAXV3d2v//v3au3evTp8+rZtvvlljY2OF52zZskV79uzRrl27NDAwoOPHj2v9+vU1bzgAINpiLkDMffrpp7r00ks1MDCgb3/728rlcrrkkku0c+dO3XHHHZKkjz76SFdddZUGBwd1ww03lN1mPp9XMplULpdTIpE4v8EeTtYqx9eRznR8nKSH6Kq386kebwxXa+W+x88J9BtQLpeTJLW0tEiShoaGdPr0aXV2dhaes3z5crW3t2twcHDKbUxMTCifzxctAID6V3UATU5OavPmzbrxxht1zTXXSJIymYyamprU3Nxc9NxUKqVMJjPldnp7e5VMJgtLW1tbtU0CAERI1QHU3d2t999/X319fYEa0NPTo1wuV1hGRkYCbQ8AEA1VXYx048aNevXVV7Vv3z4tXbq0sL61tVWnTp3S6Oho0Sgom82qtbV1ym3F43HF4/FqmgEAiLCKRkDOOW3cuFG7d+/Wm2++qWXLlhU93tHRoXnz5qm/v7+wbnh4WMeOHVM6na6oYclksuZljuXKQUstUSulDsLHElVEV72dT1bfBT72RVAVjYC6u7u1c+dOvfLKK1q4cGHhd51kMqkLL7xQyWRS99xzj7Zu3aqWlhYlEglt2rRJ6XR6RhVwAIC5o6Iy7OmS9oUXXtCPfvQjSWcnov7sZz/TSy+9pImJCa1du1bPPPPMtH+C+6pz5XvVCut+QEG2W4+jpOlQoopa4nz6UpT6YqZl2IHmAYWBAIq2KH1I4D/Opy9FqS9mZR4QAADVIoAAACYIIACACQIIAGCiqomoPgvyQ12U6+l9YXUxWN9+hA0iisca1g/kPh6rlXrsC0ZAAAATBBAAwAQBBAAwQQABAEwQQAAAEwQQAMBE3ZVhlxKkzDqs8m4fSyvDKgMOst251E8+Hms5Pl4rMWqfu7mIERAAwAQBBAAwQQABAEwQQAAAEwQQAMAEAQQAMEEAAQBMeDsPaLp7iQeZyxPW7Rjq7TYOYc2RqLe5F1bHE7X5LVZt8rEvUIwREADABAEEADBBAAEATBBAAAATBBAAwAQBBAAw4W0ZdjKZnPV9BrmkfLXbhd98LHm22G+Yt1TwsY+rZXXriahiBAQAMEEAAQBMEEAAABMEEADABAEEADBBAAEATHhbhl0tH0up66nMNIp87H/aVJ/op8owAgIAmCCAAAAmCCAAgAkCCABgggACAJgggAAAJgggAICJupsHFGSuT5T26Ssf55IE2W9YbfZxvkgU35+o8fHzYYkREADABAEEADBBAAEATBBAAAATBBAAwAQBBAAwEbky7HKlimHdciGsUuty241aaWbU2uujejsnfGTVx1F778LuJ0ZAAAATBBAAwAQBBAAwQQABAEwQQAAAEwQQAMAEAQQAMBG5eUBh4rYKc4+Pc26iNlckiujjmQm7nxgBAQBMEEAAABMEEADABAEEADBBAAEATBBAAAATFQXQs88+qxUrViiRSCiRSCidTuu1114rPD4+Pq7u7m4tXrxYCxYsUFdXl7LZbE0bHIvFSi7OuWmXelOqH/Al+glzWbnvTEsVBdDSpUu1bds2DQ0N6dChQ7rpppu0bt06ffDBB5KkLVu2aM+ePdq1a5cGBgZ0/PhxrV+/PpSGAwCiLeYCDg1aWlr02GOP6Y477tAll1yinTt36o477pAkffTRR7rqqqs0ODioG264YUbby+fzSiaTVbfH4qZyYar2eOpxxFetsG5SCESBxWTrc9/juVxOiURi2udV/RvQmTNn1NfXp7GxMaXTaQ0NDen06dPq7OwsPGf58uVqb2/X4ODgtNuZmJhQPp8vWgAA9a/iADpy5IgWLFigeDyu++67T7t379bVV1+tTCajpqYmNTc3Fz0/lUopk8lMu73e3l4lk8nC0tbWVvFBAACip+IAuvLKK3X48GEdOHBA999/vzZs2KAPP/yw6gb09PQol8sVlpGRkaq3BQCIjoovRtrU1KTLL79cktTR0aGDBw/qqaee0p133qlTp05pdHS0aBSUzWbV2to67fbi8bji8XjlLQcARFrgeUCTk5OamJhQR0eH5s2bp/7+/sJjw8PDOnbsmNLpdNDdzJiv5YZhmEsl50GU6qdyy1wylz47c4nP53hFI6Cenh7dcsstam9v18mTJ7Vz5069/fbbeuONN5RMJnXPPfdo69atamlpUSKR0KZNm5ROp2dcAQcAmDsqCqATJ07ohz/8oT755BMlk0mtWLFCb7zxhr73ve9Jkp544gk1NDSoq6tLExMTWrt2rZ555plQGg4AiLbA84BqLeg8oHrj2duDOsa8MtRK6POAAAAIggACAJgggAAAJgggAICJiieiorbK/bjLD8OYLZxPwVlc+DPKGAEBAEwQQAAAEwQQAMAEAQQAMEEAAQBMEEAAABPelmFPdw2hMC8NX6pEMqz9BtluWCXaYZWSUqJaG5Tmo14wAgIAmCCAAAAmCCAAgAkCCABgggACAJgggAAAJgggAIAJb+cBTSfI7QvKqfa1Ybap2v0GmXMT1lwSH/spCKt5Tcz1gS+CfmYZAQEATBBAAAATBBAAwAQBBAAwQQABAEwQQAAAE96WYSeTSesmzFiQUsQgpclh3prCQtTKi6PW3nKidnsPH9XTscwGRkAAABMEEADABAEEADBBAAEATBBAAAATBBAAwIS3Zdi5XE6JROK89fVW0mlVSh1WyW0QFm0Kcj7V27kYVql11PoBs4cREADABAEEADBBAAEATBBAAAATBBAAwAQBBAAwQQABAEx4Ow9oOkFuXxDmfkuJ2m0TrOa3WMwXYY5Kbcyl+VL1xvL7iREQAMAEAQQAMEEAAQBMEEAAABMEEADABAEEADDhbRl2Mpm0bkIRH0upwyp9LfdaLr1/FrcvmJl6O565JOxpL4yAAAAmCCAAgAkCCABgggACAJgggAAAJgggAIAJAggAYMLbeUDVCjK/JSxhtcnqtQguanNjuKVCdPn8PcEICABgggACAJgggAAAJgggAIAJAggAYIIAAgCYCBRA27ZtUywW0+bNmwvrxsfH1d3drcWLF2vBggXq6upSNputeNu5XE7OufOWKIrFYtMuYZmq72rVj6W2W+pYgyywFeb5xPserjDfu6CqDqCDBw/q+eef14oVK4rWb9myRXv27NGuXbs0MDCg48ePa/369YEbCgCoL1UF0Oeff6677rpLv/3tb7Vo0aLC+lwup9///vd6/PHHddNNN6mjo0MvvPCC/v73v2v//v01azQAIPqqCqDu7m7deuut6uzsLFo/NDSk06dPF61fvny52tvbNTg4OOW2JiYmlM/nixYAQP2r+FI8fX19euedd3Tw4MHzHstkMmpqalJzc3PR+lQqpUwmM+X2ent79atf/arSZgAAIq6iEdDIyIgeeOAB/elPf9L8+fNr0oCenh7lcrnCMjIyUpPtAgD8VlEADQ0N6cSJE7r22mvV2NioxsZGDQwMaPv27WpsbFQqldKpU6c0Ojpa9LpsNqvW1tYptxmPx5VIJIoWAED9q+hPcGvWrNGRI0eK1t19991avny5fvGLX6itrU3z5s1Tf3+/urq6JEnDw8M6duyY0ul07VoNSX5e+Tssc+lqzFbHWmq/QfY5l967IIL0U1if93LvTdD9VhRACxcu1DXXXFO07qKLLtLixYsL6++55x5t3bpVLS0tSiQS2rRpk9LptG644YZADQUA1Jea3w/oiSeeUENDg7q6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WrZsmVpbW4v6LJ/P68CBA3Oqz5xz2rhxo3bv3q0333xTy5YtK3q8o6ND8+bNK+qn4eFhHTt2bE7101QmJyc1MTFBH/2fNWvW6MiRIzp8+HBhue6663TXXXcV/k1fVcm6CqKUvr4+F4/H3Ysvvug+/PBDd++997rm5maXyWSsm2bm5MmT7t1333Xvvvuuk+Qef/xx9+6777p///vfzjnntm3b5pqbm90rr7zi3nvvPbdu3Tq3bNky98UXXxi3fPbcf//9LplMurffftt98sknheW///1v4Tn33Xefa29vd2+++aY7dOiQS6fTLp1OG7Z69j344INuYGDAHT161L333nvuwQcfdLFYzP31r391ztFHpfx/FZxz9FW1vA4g55x7+umnXXt7u2tqanKrVq1y+/fvt26SqbfeestJOm/ZsGGDc+5sKfZDDz3kUqmUi8fjbs2aNW54eNi20bNsqv6R5F544YXCc7744gv305/+1C1atMh97Wtfc9///vfdJ598YtdoAz/+8Y/d17/+ddfU1OQuueQSt2bNmkL4OEcflfLVAKKvqsPtGAAAJrz9DQgAUN8IIACACQIIAGCCAAIAmCCAAAAmCCAAgAkCCABgggACAJgggAAAJgggAIAJAggAYIIAAgCY+B+viKmcY2NXfQAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from sklearn.naive_bayes import GaussianNB\n", "\n", "clf = GaussianNB()\n", "clf.fit(X.reshape(-1, 1), Y)\n", "\n", "result = clf.predict(X0.reshape(-1, 1)).reshape(size[0], size[1])\n", "plt.imshow(result)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "To improve our segmentation, we filter the input image with a median image filter and add this information as a second sample vector.\n", "\n", "ITK is often used to read, reformat, denoise, and augment medical imaging data to improve the effectiveness of medical imaging models." ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "Text(0.5, 1.0, 'Median Filtered Image')" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAaAAAAGzCAYAAABpdMNsAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA7Z0lEQVR4nO3de3hdVZ3/8U/aNEmbW5PSJIamFwGpiEWNQ4nlWgqZgghS7zoW5FHEFinV0dZRbjIGULkUauvDMK36WMuEGdTiCJZagmiLEIpW0AoKNqVNb5CTNGmTkuzfH/xypqc5+7uSvXu6Tsv79Tx5tGedvc/aa+99vuzk+10rJwiCQAAAHGbDfHcAAPDmRAACAHhBAAIAeEEAAgB4QQACAHhBAAIAeEEAAgB4QQACAHhBAAIAeEEAQlaYOHGiLrvssuS/H3vsMeXk5Oixxx7z1qcwN9xwg3JyclJeO7j/2e5I6y+OTgQgJC1fvlw5OTnKycnRE088MaA9CALV1NQoJydH73//+z308PA4++yzk+Nw8M9f/vKXQe3j+eef1w033KCXX345s53NsJycHM2dO9d3N3CUyvXdAWSfgoICrVixQqeffnrK601NTdqyZYvy8/Mz3oczzzxTe/fuVV5eXsY/K51x48apoaFhwOvV1dX6+te/rgULFpjbP//887rxxht19tlna+LEiRnqJXBkIwBhgAsuuECNjY1atGiRcnP/7xJZsWKFamtrtWvXroz3YdiwYSooKMj454QpLS3Vpz71qdD2A8flcOrs7FRhYaGXzwYONX4FhwE+/vGPa/fu3Vq9enXytZ6eHj3wwAP6xCc+kXabvr4+3XnnnXrHO96hgoICVVZW6sorr9Rrr72W8r4gCHTzzTdr3LhxGjVqlM455xw999xzA/aX7m9Av/nNb/ThD39Y48ePV35+vmpqanTttddq7969KdtedtllKioq0iuvvKJLLrlERUVFGjt2rL785S+rt7c3xsi8Id3fgA60fPlyffjDH5YknXPOOclf3x14LL/85S91xhlnqLCwUMXFxbrwwgsHjEP/cfztb3/TBRdcoOLiYn3yk5+UdOjHe7D6z8t//dd/6cYbb9Sxxx6r4uJifehDH1IikVB3d7fmzZuniooKFRUV6fLLL1d3d3fKPpYtW6bp06eroqJC+fn5Oumkk7RkyZIBn9XX16cbbrhB1dXVyb4///zzaf9+1dbWpnnz5qmmpkb5+fk6/vjjdeutt6qvry/ysSLzeALCABMnTlRdXZ1+8pOfaObMmZLe+MJMJBL62Mc+pkWLFg3Y5sorr9Ty5ct1+eWX64tf/KJeeukl3XPPPdqwYYN++9vfasSIEZKk6667TjfffLMuuOACXXDBBXrmmWd0/vnnq6enx9mvxsZGdXV16aqrrtKYMWP0+9//Xnfffbe2bNmixsbGlPf29vaqvr5eU6dO1Xe+8x09+uij+u53v6vjjjtOV111lfOzent7BzzpFRQUqKioyLntmWeeqS9+8YtatGiRvva1r+ntb3+7JCX/90c/+pFmz56t+vp63Xrrrerq6tKSJUt0+umna8OGDSm/snv99ddVX1+v008/Xd/5znc0atQoSYdnvC0NDQ0aOXKkFixYoBdffFF33323RowYoWHDhum1117TDTfcoPXr12v58uWaNGmSrrvuuuS2S5Ys0Tve8Q594AMfUG5urlatWqUvfOEL6uvr05w5c5LvW7hwoW677TZddNFFqq+v1x/+8AfV19dr3759KX3p6urSWWedpVdeeUVXXnmlxo8fr9/97ndauHChtm3bpjvvvDPWsSKDAuD/W7ZsWSApeOqpp4J77rknKC4uDrq6uoIgCIIPf/jDwTnnnBMEQRBMmDAhuPDCC5Pb/eY3vwkkBT/+8Y9T9vfwww+nvL5jx44gLy8vuPDCC4O+vr7k+772ta8FkoLZs2cnX1u7dm0gKVi7dm3ytf6+HKihoSHIyckJ/vGPfyRfmz17diApuOmmm1Le++53vzuora11jsNZZ50VSBrw09+/66+/Pjj41pkwYUJK/xsbGwf0PwiCoKOjIxg9enTw2c9+NuX11tbWoLS0NOX1/uNYsGBBynszMd5hJAVz5sxJ/rv/vJx88slBT09P8vWPf/zjQU5OTjBz5syU7evq6oIJEyakvJbuPNbX1wdvfetbk/9ubW0NcnNzg0suuSTlfTfccMOAvn/zm98MCgsLg7/+9a8p712wYEEwfPjwYPPmzc7jhB/8Cg5pfeQjH9HevXv10EMPqaOjQw899FDor98aGxtVWlqq8847T7t27Ur+1NbWqqioSGvXrpUkPfroo+rp6dHVV1+d8iusefPmDapPI0eOTP7/zs5O7dq1S+973/sUBIE2bNgw4P2f//znU/59xhln6O9///ugPmvixIlavXp1ys9XvvKVQW1rWb16tdra2vTxj388ZayGDx+uqVOnJsfqQAc/sR2u8bZ8+tOfTj5lSdLUqVMVBIE+85nPpLxv6tSpamlp0euvv5587cDzmEgktGvXLp111ln6+9//rkQiIUlas2aNXn/9dX3hC19I2d/VV189oC+NjY0644wzVFZWljIeM2bMUG9vrx5//PHYx4vM4FdwSGvs2LGaMWOGVqxYoa6uLvX29upDH/pQ2ve+8MILSiQSqqioSNu+Y8cOSdI//vEPSdIJJ5ww4LPKysqcfdq8ebOuu+46/fznPx/wt47+L65+BQUFGjt2bMprZWVlA7YLU1hYqBkzZgzqvUPxwgsvSJKmT5+etr2kpCTl37m5uRo3btyAfRyO8baMHz8+5d+lpaWSpJqamgGv9/X1KZFIaMyYMZKk3/72t7r++uu1bt06dXV1pbw/kUiotLQ02ffjjz8+pb28vHxA31944QX98Y9/HHC++/WPB7IPAQihPvGJT+izn/2sWltbNXPmTI0ePTrt+/r6+lRRUaEf//jHadvDvhiGore3V+edd55effVVffWrX9XkyZNVWFioV155RZdddtmAPzYPHz489mdmQn8/f/SjH6mqqmpA+8HZdfn5+Ro2LPUXFYdjvF3Cxjfs9SAIJEl/+9vfdO6552ry5Mm6/fbbVVNTo7y8PP3v//6v7rjjjkhJA319fTrvvPNCn1Df9ra3DXmfODwIQAj1wQ9+UFdeeaXWr1+v+++/P/R9xx13nB599FFNmzYt5dcrB5swYYKkN/6L9a1vfWvy9Z07dzqfTDZu3Ki//vWv+sEPfqBPf/rTydcPzNTLJmFZcscdd5wkqaKiIvIT1uEY70xZtWqVuru79fOf/zzlKergXz329/3FF1/UpEmTkq/v3r17QN+PO+447dmzJyNPrMgs/gaEUEVFRVqyZIluuOEGXXTRRaHv+8hHPqLe3l5985vfHND2+uuvq62tTZI0Y8YMjRgxQnfffXfyv4glDSpLqf+/rA/cLggC3XXXXYM8msOrv1an/9j71dfXq6SkRN/61re0f//+Advt3LnTue/DMd6Zku48JhIJLVu2LOV95557rnJzcwekZ99zzz0D9vmRj3xE69at0yOPPDKgra2tLeXvT8guPAHBNHv2bOd7zjrrLF155ZVqaGjQs88+q/PPP18jRozQCy+8oMbGRt1111360Ic+lKzFaWho0Pvf/35dcMEF2rBhg375y1/qmGOOMT9j8uTJOu644/TlL39Zr7zyikpKSvTf//3f3v5L3uVd73qXhg8frltvvVWJREL5+fnJ2pclS5boX/7lX/Se97xHH/vYxzR27Fht3rxZv/jFLzRt2rS0X7IHOhzjnSnnn3++8vLydNFFF+nKK6/Unj17dO+996qiokLbtm1Lvq+yslLXXHONvvvd7+oDH/iA/vmf/1l/+MMfkn0/8AnzX//1X/Xzn/9c73//+3XZZZeptrZWnZ2d2rhxox544AG9/PLL3o4XNgIQDomlS5eqtrZW3//+9/W1r31Nubm5mjhxoj71qU9p2rRpyffdfPPNKigo0NKlS7V27VpNnTpVv/rVr3ThhRea+x8xYoRWrVqlL37xi2poaFBBQYE++MEPau7cuTrllFMyfXhDVlVVpaVLl6qhoUFXXHGFent7tXbtWlVUVOgTn/iEqqurdcstt+jb3/62uru7deyxx+qMM87Q5ZdfPqj9Z3q8M+XEE0/UAw88oK9//ev68pe/rKqqKl111VUaO3bsgAy6W2+9VaNGjdK9996rRx99VHV1dfrVr36l008/PWWWjFGjRqmpqUnf+ta31NjYqB/+8IcqKSnR2972Nt14443JBAlkn5zgwGdhAMhibW1tKisr080336x/+7d/890dxMTfgABkpYOnWJL+7+9XZ5999uHtDDKCX8EByEr333+/li9frgsuuEBFRUV64okn9JOf/ETnn39+yq8ZceQiAAHISlOmTFFubq5uu+02tbe3JxMTbr75Zt9dwyHC34AAAF7wNyAAgBcEIACAF1n3N6C+vj5t3bpVxcXF5qJfAIDsFASBOjo6VF1dPWAuw4PfmBH33HNPMGHChCA/Pz849dRTgyeffHJQ27W0tKRdi4Uffvjhh58j66elpcX8vs/IE9D999+v+fPna+nSpZo6daruvPNO1dfXa9OmTaFTyPcrLi6WJJ100kmHfUbjv/71r6FtQYxcDetJzrVf13iFcU23n5+fH2m/kswJMK1z5loOu3/+tHQOnEwznbCZuqX/m9gynYOXPxhKnw6eufpg6epY+h24ls6hlG5+ucGyrsVM/jYiLy8vI/vt/y5Jp6Ojw9z24OU9Bquzs9Ns719mIp09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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "l_median = []\n", "for i in range(0, 10):\n", " image_name = \"data/sklearn/im%d.nrrd\" % i\n", " image = itk.imread(image_name, itk.F)\n", "\n", " median = itk.median_image_filter(image, radius=3)\n", "\n", " array = itk.array_from_image(median)\n", " l_median.append(array)\n", "\n", "plt.gray()\n", "plt.imshow(l_median[0])\n", "plt.title(\"Median Filtered Image\")" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "M0 = l_median[0].flatten()\n", "M = M0\n", "X0 = np.concatenate((X0.reshape(-1, 1), M0.reshape(-1, 1)), axis=1)\n", "for i in range(1, 10):\n", " M = np.concatenate((M, l_median[i].flatten()))\n", "\n", "X = np.concatenate((X.reshape(-1, 1), M.reshape(-1, 1)), axis=1)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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AgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgIucC5JyzHgIAIAum+nqecwEaHBy0HgIAIAum+nrucTm25BgfH1d/f79KSkrk8XiUTCZVUVGhvr4++f1+6+HlLOZpepin6WGepod5mphzToODgyovL1dBwe3XOYULOKZpKSgo0Nq1a2857/f7+QOeBuZpepin6WGepod5ulUgEJjympz7FhwAID8QIACAiZwPkM/n03PPPSefz2c9lJzGPE0P8zQ9zNP0ME9zk3ObEAAA+SHnV0AAgKWJAAEATBAgAIAJAgQAMJHzATpy5Ii+9a1vadmyZdq0aZP+9a9/WQ/J1NmzZ/Xoo4+qvLxcHo9Hb7zxRsbjzjkdPHhQd911l5YvX666ujp9/PHHNoM10tLSog0bNqikpERr1qzR9u3b1dvbm3HN8PCwIpGIVq1apeLiYjU0NCgejxuN2MYrr7yi6urq9E2U4XBYb7/9dvpx5mhira2t8ng82rdvX/occzU7OR2gv/71r2pqatJzzz2nixcvqqamRvX19bp586b10MwMDQ2ppqZGR44cmfDx559/XocPH9arr76q8+fPa8WKFaqvr9fw8PACj9RONBpVJBLRuXPndPr0aY2Ojurhhx/W0NBQ+pr9+/fr1KlTOnnypKLRqPr7+7Vjxw7DUS+8tWvXqrW1Vd3d3bpw4YK2bNmibdu26cqVK5KYo4l0dXXptddeU3V1dcZ55mqWXA7buHGji0Qi6V+PjY258vJy19LSYjiq3CHJtbe3p389Pj7uQqGQO3ToUPrcwMCA8/l87vXXXzcYYW64efOmk+Si0ahz7os5KSoqcidPnkxf8+9//9tJcp2dnVbDzAkrV650f/zjH5mjCQwODrp77rnHnT592n3ve99ze/fudc7x+TQXObsCGhkZUXd3t+rq6tLnCgoKVFdXp87OTsOR5a5r164pFotlzFkgENCmTZvyes4SiYQkqaysTJLU3d2t0dHRjHlat26dKisr83aexsbG1NbWpqGhIYXDYeZoApFIRI888kjGnEh8Ps1Fzr0Y6Zc+/fRTjY2NKRgMZpwPBoO6evWq0ahyWywWk6QJ5+zLx/LN+Pi49u3bp4ceekjr16+X9MU8eb1elZaWZlybj/N0+fJlhcNhDQ8Pq7i4WO3t7br//vvV09PDHH1FW1ubLl68qK6urlse4/Np9nI2QEA2RCIRffjhh/rHP/5hPZScdO+996qnp0eJREJ/+9vf1NjYqGg0aj2snNLX16e9e/fq9OnTWrZsmfVwlpSc/RbcnXfeqTvuuOOWnSTxeFyhUMhoVLnty3lhzr6we/duvfXWW3rvvfcy3uIjFAppZGREAwMDGdfn4zx5vV7dfffdqq2tVUtLi2pqavTSSy8xR1/R3d2tmzdv6oEHHlBhYaEKCwsVjUZ1+PBhFRYWKhgMMlezlLMB8nq9qq2tVUdHR/rc+Pi4Ojo6FA6HDUeWu6qqqhQKhTLmLJlM6vz583k1Z8457d69W+3t7Tpz5oyqqqoyHq+trVVRUVHGPPX29ur69et5NU8TGR8fVyqVYo6+YuvWrbp8+bJ6enrSx4MPPqjHH388/d/M1SxZ74KYTFtbm/P5fO748ePuo48+ck8++aQrLS11sVjMemhmBgcH3aVLl9ylS5ecJPfCCy+4S5cuuf/+97/OOedaW1tdaWmpe/PNN90HH3zgtm3b5qqqqtznn39uPPKF8/TTT7tAIODef/99d+PGjfTxv//9L33NU0895SorK92ZM2fchQsXXDgcduFw2HDUC+/AgQMuGo26a9euuQ8++MAdOHDAeTwe9/e//905xxxN5qu74JxjrmYrpwPknHMvv/yyq6ysdF6v123cuNGdO3fOekim3nvvPSfplqOxsdE598VW7GeffdYFg0Hn8/nc1q1bXW9vr+2gF9hE8yPJHTt2LH3N559/7n7xi1+4lStXum984xvuRz/6kbtx44bdoA387Gc/c9/85jed1+t1q1evdlu3bk3HxznmaDJfDxBzNTu8HQMAwETO/gwIALC0ESAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAm/g+kmt2bWVTz5AAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "clf.fit(X, Y)\n", "result = clf.predict(X0).reshape(50, 50)\n", "plt.imshow(result)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Typical processing\n", "\n", "* Resampling for consistent pixel grid size and spacing\n", "* Image preprocessing\n", " * Bias field correction, e.g. `n4_bias_field_correction_image_filter`\n", " * Noise reduction, e.g. `smoothing_recursive_gaussian_image_filter`\n", " * Feature computation, e.g. texture, wavelet, or edge detector\n", "* Converting ITK data to NumPy and organize the data as needed\n", "* Train classifier\n", "* Use classifier on new data\n", "* Convert classifier result to ITK data\n", "* Apply post processing filters\n", " * Fill holes, e.g. `binary_fillhole_image_filter`\n", " * Smoothing, e.g. `median_image_filter`" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Two ways of using ITK in Python\n", "\n", "* Functional programming API\n", " * *Pythonic*\n", " * Eager execution\n", " * More concise\n", " * A few functions and filters are not available\n", "* Object-oriented way\n", " * Set up processing pipelines\n", " * Delayed execution\n", " * Full access to ITK\n", " * Conserve memory\n", " * Optimally re-use and release pixel buffer memory\n", " * Stream process pipelines in chunks" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Let's start with the Pythonic way" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "image = itk.imread(\"data/CBCT-TextureInput.png\", itk.ctype(\"float\"))" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "filtered_image = itk.median_image_filter(image, radius=3)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/html": [ "\n", " \n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "window.connectPlugin && window.connectPlugin(\"a1a409e0-26f1-4324-9230-fcb6a2cd79aa\")" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "view(filtered_image, ui_collapsed=True)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Pythonic exercises\n", "\n", "* In the example above, change the radius of the filter and observe the result.\n", "* Replace filter with `mean_image_filter`\n", "* Replace filter with `otsu_threshold_image_filter`\n", "* Visualize results" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Uncomment and change the radius of the filter and observe the result." ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "# median_filtered_image = itk.median_image_filter(image, radius = XX)\n", "# view(median_filtered_image)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "# %load solutions/2_Using_ITK_in_Python_real_world_filters_median.py" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Uncomment and replace filter with `mean_image_filter`" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "# mean_filtered_image = itk.filter(image, radius = 5)\n", "# view(mean_filtered_image)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "# %load solutions/2_Using_ITK_in_Python_real_world_filters_mean.py" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Uncomment and replace filter with `otsu_threshold_image_filter`" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "# otsu_filtered_image = itk.filter(image)\n", "# view(otsu_filtered_image)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "# %load solutions/2_Using_ITK_in_Python_real_world_filters_otsu.py" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Object-oriented\n", "\n", "* Two types of C++ ITK objects\n", " * Smart pointers (hint: most ITK objects are smart pointers)\n", " * \"Simple\" objects\n", "* Translates in two ways of creating objects in Python\n", " * `obj = itk.SmartPointerObjectType.New()` (use auto-completion to see if `New()` method exists)\n", " * `obj = itk.SimpleObjectType()`" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "## Examples of objects\n", "\n", "* With `New()` method:\n", " * `itk.Image`\n", " * `itk.MedianImageFilter`\n", "* Without `New()` method:\n", " * `itk.Index`\n", " * `itk.RGBPixel`\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Filters with object-oriented syntax" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/html": [ "\n", " \n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "window.connectPlugin && window.connectPlugin(\"a1a409e0-26f1-4324-9230-fcb6a2cd79aa\")" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "PixelType = itk.ctype(\"float\")\n", "image = itk.imread(\"data/CBCT-TextureInput.png\", PixelType)\n", "\n", "ImageType = itk.Image[PixelType, 2]\n", "median_filter = itk.MedianImageFilter[ImageType, ImageType].New()\n", "median_filter.SetInput(image)\n", "median_filter.SetRadius(4)\n", "median_filter.Update()\n", "view(median_filter.GetOutput(), ui_collapsed=True)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Object-oriented exercises\n", "\n", "* In the example above, change the radius of the filter and observe the result.\n", "* Replace filter with `MeanImageFilter`\n", "* Replace filter with `OtsuThresholdImageFilter`\n", "* Visualize results" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Uncomment and change the radius of the filter and observe the result." ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "# median_filter = itk.MedianImageFilter[ImageType, ImageType].New()\n", "# median_filter.SetInput(image)\n", "# median_filter.SetRadius(XX)\n", "# median_filter.Update()\n", "# median_filtered_image = median_filter.GetOutput()\n", "# view(median_filtered_image)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "# %load solutions/2_Using_ITK_in_Python_real_world_filters_MedianFilter.py" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Uncomment and edit to use `MeanImageFilter`" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "# mean_filter = itk.XX[ImageType, ImageType].New()\n", "# mean_filter.SetInput(XX)\n", "# mean_filter.SetRadius(XX)\n", "# mean_filter.Update()\n", "# mean_filtered_image = mean_filter.GetOutput()\n", "# view(mean_filtered_image)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "# %load solutions/2_Using_ITK_in_Python_real_world_filters_MeanFilter.py" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Uncomment and replace filter with `OtsuThresholdImageFilter`" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "# InputImageType = itk.Image[itk.ctype('float'), 2]\n", "# OutputImageType = itk.Image[itk.ctype('short'), 2]\n", "\n", "# otsu_filter = itk.OtsuThresholdImageFilter[XX]\n", "# XX" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "# %load solutions/2_Using_ITK_in_Python_real_world_filters_OtsuFilter.py" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## ITK Object-oriented Summary\n", "* Has `New()` method?\n", " * Call `Update()` with filters!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Supported Image Types" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Unsupported (image) types\n", "\n", "ITK filters have compile-time performance optimized for a specific image types and dimensions.\n", "\n", "When an attempt is made to use a filter with an image type that is not supported, a error will occur like:" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "`KeyError: \"itkTemplate : No template [] for the itk::ImageFileReader class\"`" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# image = itk.imread(\"data/BrainProtonDensitySlice.png\", itk.D)\n", "# print(image)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To find the supported types for a filter, call `.GetTypes()` on the filter. `itk.imread` wraps, the `itk.ImageFileReader` filter." ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Options:\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n", " [,]\n" ] } ], "source": [ "itk.ImageFileReader.GetTypes()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "One approach to handle this type of error is is to read the image into a supported pixel type:" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "image = itk.imread(\"data/KitwareITK.jpg\", itk.F)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Another approach is to cast the image to a supported image type:" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "InputImageType = itk.Image[itk.F, 2]\n", "OutputImageType = itk.Image[itk.UC, 2]\n", "cast_filter = itk.CastImageFilter[InputImageType, OutputImageType].New(image)\n", "cast_filter.Update()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Appendix" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### Functions to know\n", "* `itk.imread(file_name [, pixel_type])`\n", "* `itk.imwrite(image, file_name [, compression])`\n", "* `itk.array_from_image(image)` and `itk.array_view_from_image(image)`\n", "* `itk.image_from_array(arr)` and `itk.image_view_from_array(arr)`" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### Pixel types - Two options\n", "* itk.ctype('float'), itk.ctype('unsigned char')\n", "* itk.F, itk.UC" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "skip" } }, "source": [ "### Convenience functions\n", "* `itk.size(image)`\n", "* `itk.spacing(image)`\n", "* `itk.origin(image)`\n", "* `itk.index(image)`\n", "* `itk.physical_size(image)`" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Type names in C++, ITK Python and Numpy\n", "| C++ | ITK Python | Numpy |\n", "| :------------- | :----------: | -----------: |\n", "| float | itk.F | numpy.float32|\n", "| double | itk.D | numpy.float64|\n", "| unsigned char | itk.UC | numpy.uint8 |\n", "| bool | itk.B | bool |\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "notes" } }, "source": [ "The complete list of types can be found in the [ITK Software Guide](https://itk.org/ITKSoftwareGuide/html/Book1/ITKSoftwareGuide-Book1ch9.html#x48-1530009.5).\n", "Alternatively, such correspondence can be obtained by the following methods." ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "True\n" ] } ], "source": [ "# names in C++ and ITK python\n", "print(itk.F == itk.ctype(\"float\")) # True\n", "print(itk.B == itk.ctype(\"bool\")) # True" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\n" ] } ], "source": [ "# print the numpy names of ITK python data types\n", "print(itk.D.dtype) # \n", "print(itk.UC.dtype) # \n", "print(itk.B.dtype) # " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Specify pixel types\n", "* `Some ITK functions (e.g., imread()) will automatically detect the pixel type and dimensions of the image.`\n", "* `However, in certain cases, you want to choose the pixel type of the image that is read. `" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n" ] } ], "source": [ "# Automatically detect\n", "image = itk.imread(\"data/KitwareITK.jpg\")\n", "print(type(image)) # \n", "\n", "# specify pixel type\n", "image = itk.imread(\"data/KitwareITK.jpg\", itk.ctype(\"unsigned char\"))\n", "print(type(image)) # " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See also: the **[ITK Python Quick Start Guide](https://docs.itk.org/en/latest/learn/python_quick_start.html)**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Enjoy ITK!" ] } ], "metadata": { "celltoolbar": "Slideshow", "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.11.7" } }, "nbformat": 4, "nbformat_minor": 4 }