{ "metadata": { "name": "", "signature": "sha256:82602b59a323989bb38205ceb7752bf2516820ac9015b2601b4cdac814fb5cec" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Welcome to the SimpleITK Image Filtering Tutorial\n", "\n", "This tutorial illustrates how to use some of the basic image filtering capabilities of SimpleITK." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Importing SimpleITK\n", "We start by importing the SimpleITK python module" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import SimpleITK as sitk" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Downloading an Image\n", "\n", "We download a specific image from the Figshare data sharing and hosting site\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import urllib\n", "import os.path\n", "\n", "destination = '/tmp/TralitusSaltrator.jpg'\n", "source = 'http://files.figshare.com/1546044/IMG_0974.jpg'" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and we download the image file, only if it doesn't already exist in our local disk" ] }, { "cell_type": "code", "collapsed": false, "input": [ "if not os.path.isfile(destination):\n", " urllib.urlretrieve(source,destination)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reading an Image\n", "\n", "Then we read in an image" ] }, { "cell_type": "code", "collapsed": false, "input": [ "colorimage = sitk.ReadImage(destination)\n" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Converting to Grayscale\n", "\n", "Typical image fileformats such as PNG and JPG will be read as color images (three channels matching RGB components)." ] }, { "cell_type": "code", "collapsed": false, "input": [ "image = sitk.VectorMagnitude(colorimage)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Displaying the Image\n", "\n", "We extract the pixel data in the form of a numpy array, that then we visualize using the Matplotlib python module" ] }, { "cell_type": "code", "collapsed": false, "input": [ "imshow(sitk.GetArrayFromImage(image));" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Changing the Colormap\n", "\n", "By default, imshow would use a rainbow colormap. We can change that by selecting from \n", "http://wiki.scipy.org/Cookbook/Matplotlib/Show_colormaps" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import matplotlib.pyplot as plt\n", "import matplotlib.cm as cm\n", "\n", "imshow(sitk.GetArrayFromImage(image),cmap=cm.gray);" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Your Work\n", "\n", "Add cells here for experimenting with two other color maps from the SciPy wiki list above.\n", "\n", "Note that you don't need to repeat the import of matplotlib modules.\n", "\n", "Just call imshow() with different arguments in \"cmap\" color map." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Smoothing Filters\n", "\n", "Smooting is often used to reduce noise." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Recursive Gaussian Smoothing\n", "\n", "This is a relatively fast filter for smoothing an image along all directions.\n", "\n", "Here we are showing off, how cool of equations we can add to the notebook\n", "\n", " $$ SI(x') = \\int^\\infty_\\infty{I(x'-x) e^{-x^2}}$$\n", "\n", "We need to specify the Sigma value of the Gaussian function to use.\n", "\n", "#### Your work\n", "\n", "Experiment with the values of Sigma and see its effect on the image." ] }, { "cell_type": "code", "collapsed": false, "input": [ "rgsmootherfilter = sitk.SmoothingRecursiveGaussianImageFilter()\n", "rgsmootherfilter.SetSigma(2.5)\n", "rgsmootherfilter.SetNormalizeAcrossScale(1)\n", "rgsmoothedimage = rgsmootherfilter.Execute(image)\n", "\n", "imshow(sitk.GetArrayFromImage(rgsmoothedimage),cmap=cm.gray);" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The parameters of the filter can also be passed directly to the Execute() function as:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "rgsmoothedimage = rgsmootherfilter.Execute(image,3.5,1)\n", "\n", "imshow(sitk.GetArrayFromImage(rgsmoothedimage),cmap=cm.gray);" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Median Image Filter\n", "\n", "The Median filter is commonly used to provide robust smoothing of an image.\n", "\n", "Its main parameter is the size of the neirborhood over which the median of pixels intensities is computed.\n", "\n", "The neighborhood size is specified in terms of an integer number representing the radius of a Manhattan distance.\n", "\n", "Therefore, a radius of 3 means that we will use a neighborhood of 7x7 pixels: 7 = 3 + 1 + 3\n", "\n", "#### Your work\n", "\n", "Experiment with the values of the Radius and see the effect on the smoothed image" ] }, { "cell_type": "code", "collapsed": false, "input": [ "medianfilter = sitk.MedianImageFilter()\n", "medianfilter.SetRadius(3)\n", "medianimage = medianfilter.Execute(image)\n", "\n", "imshow(sitk.GetArrayFromImage(medianimage),cmap=cm.gray);" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The parameters of the filter can also be passed directly to the Execute() function. Note that the Radius could be different in the X and Y directions, therefore we must pass an array with two values." ] }, { "cell_type": "code", "collapsed": false, "input": [ "medianimage = medianfilter.Execute(image,[3,3])\n", "\n", "imshow(sitk.GetArrayFromImage(medianimage),cmap=cm.gray);" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Curvature Flow Filter\n", "\n", "The Curvature flow filter applies a level set paradigm to the smoothin of a scalar image.\n", "\n", "Its main parameters are the TimeStep and NumberOfIterations to use for performing the approximation of a solution to a differential equation.\n", "\n", "* Increasing the number of iterations will increase the smoothing\n", "* Reducing the time stop will improve the precision of the differential equation solution, but would require more iterations to produce the same amount of smoothing.\n", "\n", "#### Your work\n", "\n", "Experiment with the values of number of iterations and time step size." ] }, { "cell_type": "code", "collapsed": false, "input": [ "curvatureflowfilter = sitk.CurvatureFlowImageFilter()\n", "curvatureflowfilter.SetTimeStep(0.01)\n", "curvatureflowfilter.SetNumberOfIterations(30)\n", "curvatureflowimage = curvatureflowfilter.Execute(image)\n", "\n", "imshow(sitk.GetArrayFromImage(curvatureflowimage),cmap=cm.gray);" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The parameters of the filter can also be passed directly to the Execute() function as:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "rgsmootherfilter.SetSigma(2.5)\n", "\n", "imshow(sitk.GetArrayFromImage(curvatureflowimage),cmap=cm.gray);" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Grayscale Morphology\n", "\n", "Mathematical Morphology filters can be applied in Grayscale" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Grayscale Erosion\n", "\n", "Based on a size of neighborhood type defined in the SetKernelType() method, and a neighborhood size defined in the SetKernelRadius() method." ] }, { "cell_type": "code", "collapsed": false, "input": [ "grayscale_erode_filter = sitk.GrayscaleErodeImageFilter()\n", "grayscale_eroded_image = grayscale_erode_filter.Execute(image)\n", "grayscale_erode_filter.SetKernelRadius(3)\n", "grayscale_erode_filter.SetKernelType(sitk.sitkBall)\n", "imshow(sitk.GetArrayFromImage(grayscale_eroded_image),cmap=cm.gray);" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Grayscale Dilation\n", "\n", "Based on a size of neighborhood type defined in the SetKernelType() method, and a neighborhood size defined in the SetKernelRadius() method." ] }, { "cell_type": "code", "collapsed": false, "input": [ "grayscale_dilate_filter = sitk.GrayscaleDilateImageFilter()\n", "grayscale_dilate_image = grayscale_dilate_filter.Execute(image)\n", "grayscale_dilate_filter.SetKernelRadius(3)\n", "grayscale_dilate_filter.SetKernelType(sitk.sitkBall)\n", "imshow(sitk.GetArrayFromImage(grayscale_dilate_image),cmap=cm.gray);" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Edge Detection\n", "\n", "Filters commonly used in Edge Detection" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Canny Edge Detection\n", "\n", "The classic Canny filter. We define the lower threshold for edge connections and the Variance of the smoothing component." ] }, { "cell_type": "code", "collapsed": false, "input": [ "canny_filter = sitk.CannyEdgeDetectionImageFilter()\n", "float_image = sitk.Cast(image, sitk.sitkFloat32)\n", "canny_filter.SetLowerThreshold(50);\n", "canny_filter.SetVariance(15);\n", "canny_edges = canny_filter.Execute(float_image)\n", "imshow(sitk.GetArrayFromImage(canny_edges),cmap=cm.gray);" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Your Work\n", "\n", "In the Canny filter above, experiment with other values of\n", "\n", "* The Variance\n", "* The Lower Threshold\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Laplacian Recursive\n", "\n", "The Laplacian Recursive Image filter is based on the RecursiveGaussianImageFilter, and its second derivatives. We define the Sigma value for the Gaussian." ] }, { "cell_type": "code", "collapsed": false, "input": [ "rglaplacianfilter = sitk.LaplacianRecursiveGaussianImageFilter()\n", "rglaplacianfilter.SetSigma(2.5)\n", "rglaplacianfilter.SetNormalizeAcrossScale(1)\n", "rglaplacianimage = rglaplacianfilter.Execute(image)\n", "\n", "imshow(sitk.GetArrayFromImage(rglaplacianimage),cmap=cm.gray);" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Your Work\n", "\n", "In the Laplacian filter above, experiment with other values of\n", "\n", "* Sigma\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Thresholding Filters\n", "\n", "Filters commonly used to threshold images." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Otsu Threshold Image Filter\n", "\n", "Computes a threshold value that maximizes the separation between classes in the histogram. Then applies this threshold the image." ] }, { "cell_type": "code", "collapsed": false, "input": [ "otsu_filter = sitk.OtsuThresholdImageFilter()\n", "otsu_image = otsu_filter.Execute(image)\n", "imshow(sitk.GetArrayFromImage(otsu_image),cmap=cm.gray);" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Voting Filters\n", "\n", "These filters perform operations on binary images based on the counts (votes) of neighboring pixels.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Hole Filling Filter\n", "\n", "This filter is based on a Voting operation. It is useful to remove isolated pixels from the image" ] }, { "cell_type": "code", "collapsed": false, "input": [ "hole_filling_filter = sitk.VotingBinaryHoleFillingImageFilter()\n", "hole_filling_filter.SetRadius(2)\n", "hole_filling_filter.SetMajorityThreshold(1)\n", "hole_filling_filter.SetBackgroundValue(0)\n", "hole_filling_filter.SetForegroundValue(1)\n", "hole_filled_image = hole_filling_filter.Execute(otsu_image)\n", "imshow(sitk.GetArrayFromImage(hole_filled_image),cmap=cm.gray);" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Iterative Voting Hole Filling Filter\n", "\n", "Performs the filling operation multiple times until no pixels change, or maximum number of iterations is reached. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "hole_filling_filter = sitk.VotingBinaryIterativeHoleFillingImageFilter()\n", "hole_filling_filter.SetRadius(2)\n", "hole_filling_filter.SetMajorityThreshold(1)\n", "hole_filling_filter.SetBackgroundValue(0)\n", "hole_filling_filter.SetForegroundValue(1)\n", "hole_filled_image = hole_filling_filter.Execute(otsu_image)\n", "imshow(sitk.GetArrayFromImage(hole_filled_image),cmap=cm.gray);" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Your Work\n", "\n", "In the Hole Filling filters above, experiment with the values of:\n", "\n", "* Radius\n", "* Majority Threshold" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# More Filters\n", "\n", "Find more filters available in SimpleITK in the following documentation page\n", "\n", "http://www.itk.org/SimpleITKDoxygen08/html/namespaceitk_1_1simple.html" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another way to see the full list of classes available in SimpleITK is to use the dir() function, as in:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "dir(sitk)" ], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }