From 712b3797f3d7e1e866b84c663fe94a0fdc61282e Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Fri, 17 Jan 2020 18:40:00 -0500 Subject: [PATCH 1/6] DOC: Add registration parameters notebook --- examples/2_RegistrationParameters.ipynb | 696 ++++++++++++++++++++++++ 1 file changed, 696 insertions(+) create mode 100644 examples/2_RegistrationParameters.ipynb diff --git a/examples/2_RegistrationParameters.ipynb b/examples/2_RegistrationParameters.ipynb new file mode 100644 index 00000000..aec6e4e1 --- /dev/null +++ b/examples/2_RegistrationParameters.ipynb @@ -0,0 +1,696 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Examine and Modify Registration Parameters" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import itk\n", + "from itkwidgets import view, checkerboard" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[Elastix registration parameters](http://elastix.isi.uu.nl/doxygen/parameter.html) are stored in a *ParameterObject*.\n", + "\n", + "Let's find out how to examine default registration parameters and modify their values." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "parameters = itk.ParameterObject.New()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Self (0x1d64050)\n", + " RTTI typeinfo: elastix::ParameterObject\n", + " Reference Count: 1\n", + " Modified Time: 67\n", + " Debug: Off\n", + " Object Name: \n", + " Observers: \n", + " none\n", + "ParameterMap 0: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (AutomaticTransformInitialization \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\")\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 3)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (ResultImageFormat \"nii\")\n", + " (Transform \"TranslationTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "\n" + ] + } + ], + "source": [ + "# Get the default parameter map for a 3 resolution translation registration\n", + "\n", + "# When multiple resolutions are used, a multi-scale image pyramid is generated with downscaled versions of the image.\n", + "# Registration results at a lower resolution is used to initialize registration at a higher resolution.\n", + "# This improves speed and robustness.\n", + "resolutions = 3\n", + "\n", + "default_translation = parameters.GetDefaultParameterMap(\"translation\", resolutions)\n", + "\n", + "# Add these parameters to the registration parameters\n", + "parameters.AddParameterMap(default_translation)\n", + "\n", + "print(parameters)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's use these parameters for registration." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "fixed = itk.imread('data/CT_3D_lung_fixed.mha', itk.F)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "19343049a8924fe58728b36450e4d93c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Viewer(geometries=[], gradient_opacity=0.22, point_sets=[], rendered_image= affine -> bspline* transformation, with 4 resolutions for each transformation type." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Self (0x1d64050)\n", + " RTTI typeinfo: elastix::ParameterObject\n", + " Reference Count: 1\n", + " Modified Time: 24855\n", + " Debug: Off\n", + " Object Name: \n", + " Observers: \n", + " none\n", + "ParameterMap 0: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (AutomaticTransformInitialization \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\")\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 3)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (ResultImageFormat \"nii\")\n", + " (Transform \"TranslationTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "ParameterMap 1: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (AutomaticScalesEstimation \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\")\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 2)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (ResultImageFormat \"nii\")\n", + " (Transform \"AffineTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "\n" + ] + } + ], + "source": [ + "# Get the default parameter map for a 3 resolution translation registration\n", + "resolutions = 2\n", + "default_affine = parameters.GetDefaultParameterMap(\"affine\", resolutions)\n", + "\n", + "# Add these parameters to the registration parameters\n", + "parameters.AddParameterMap(default_affine)\n", + "\n", + "print(parameters)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Self (0x1d64050)\n", + " RTTI typeinfo: elastix::ParameterObject\n", + " Reference Count: 1\n", + " Modified Time: 24856\n", + " Debug: Off\n", + " Object Name: \n", + " Observers: \n", + " none\n", + "ParameterMap 0: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (AutomaticTransformInitialization \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\")\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 3)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (ResultImageFormat \"nii\")\n", + " (Transform \"TranslationTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "ParameterMap 1: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (AutomaticScalesEstimation \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\")\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 2)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (ResultImageFormat \"nii\")\n", + " (Transform \"AffineTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "ParameterMap 2: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FinalGridSpacingInPhysicalUnits 20)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (GridSpacingSchedule 1)\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\" \"TransformBendingEnergyPenalty\")\n", + " (Metric0Weight 1)\n", + " (Metric1Weight 1)\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 1)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiMetricMultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (ResultImageFormat \"nii\")\n", + " (Transform \"BSplineTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "\n" + ] + } + ], + "source": [ + "# For the bspline default parameter map, an extra argument can be specified that define the final bspline grid spacing in physical space. \n", + "resolutions = 1\n", + "default_bspline = parameters.GetDefaultParameterMap(\"bspline\", resolutions, 20.0)\n", + "\n", + "# Add these parameters to the registration parameters\n", + "parameters.AddParameterMap(default_bspline)\n", + "\n", + "print(parameters)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "parameters.GetNumberOfParameterMaps()" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Self (0x1d64050)\n", + " RTTI typeinfo: elastix::ParameterObject\n", + " Reference Count: 1\n", + " Modified Time: 24856\n", + " Debug: Off\n", + " Object Name: \n", + " Observers: \n", + " none\n", + "ParameterMap 0: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (AutomaticTransformInitialization \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\")\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 3)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (ResultImageFormat \"nii\")\n", + " (Transform \"TranslationTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "ParameterMap 1: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (AutomaticScalesEstimation \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\")\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 2)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (ResultImageFormat \"nii\")\n", + " (Transform \"AffineTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "ParameterMap 2: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FinalGridSpacingInPhysicalUnits 20)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (GridSpacingSchedule 1)\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\" \"TransformBendingEnergyPenalty\")\n", + " (Metric0Weight 1)\n", + " (Metric1Weight 1)\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 1)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiMetricMultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (ResultImageFormat \"nii\")\n", + " (Transform \"BSplineTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "\n" + ] + } + ], + "source": [ + "# Change a parameter\n", + "\n", + "# Note that keys and values are currently both strings\n", + "parameters.SetParameter(2, \"NumberOfResolutions\", \"1\")\n", + "\n", + "print(parameters)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Self (0x1d64050)\n", + " RTTI typeinfo: elastix::ParameterObject\n", + " Reference Count: 1\n", + " Modified Time: 24856\n", + " Debug: Off\n", + " Object Name: \n", + " Observers: \n", + " none\n", + "ParameterMap 0: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (AutomaticTransformInitialization \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\")\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 5)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (ResultImageFormat \"nii\")\n", + " (Transform \"TranslationTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "ParameterMap 1: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (AutomaticScalesEstimation \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\")\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 5)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (ResultImageFormat \"nii\")\n", + " (Transform \"AffineTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "ParameterMap 2: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FinalGridSpacingInPhysicalUnits 20)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (GridSpacingSchedule 1)\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\" \"TransformBendingEnergyPenalty\")\n", + " (Metric0Weight 1)\n", + " (Metric1Weight 1)\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 5)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiMetricMultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (ResultImageFormat \"nii\")\n", + " (Transform \"BSplineTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "\n" + ] + } + ], + "source": [ + "# Change a parameter on all parameter maps\n", + "parameters.SetParameter(\"NumberOfResolutions\", \"5\")\n", + "\n", + "print(parameters)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For more information on the available parameters and their meaning, see the [Elastix Parameters](http://elastix.isi.uu.nl/doxygen/parameter.html) documentation." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.6.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 0e5a95435a7d0021098f1b923d30e283300d290b Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Sun, 19 Jan 2020 19:21:33 -0500 Subject: [PATCH 2/6] DOC: Require itk-elastix>=0.5.1 on Binder --- binder/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/binder/requirements.txt b/binder/requirements.txt index d0b17b3e..fd2f2068 100644 --- a/binder/requirements.txt +++ b/binder/requirements.txt @@ -1,4 +1,4 @@ -itk-elastix>=0.5.0 +itk-elastix>=0.5.1 itk>=5.1rc1.post1 itk-core>=5.1rc1.post1 itk-numerics>=5.1rc1.post1 From af693a2f35f8490e90c816156e01282ea192fefd Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Sun, 19 Jan 2020 19:22:56 -0500 Subject: [PATCH 3/6] DOC: Require itkwidgets>=0.25.1 --- binder/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/binder/requirements.txt b/binder/requirements.txt index fd2f2068..f217d639 100644 --- a/binder/requirements.txt +++ b/binder/requirements.txt @@ -5,7 +5,7 @@ itk-numerics>=5.1rc1.post1 itk-filtering>=5.1rc1.post1 itk-registration>=5.1rc1.post1 itk-segmentation>=5.1rc1.post1 -itkwidgets>=0.24.2 +itkwidgets>=0.25.1 jupyterlab==1.2.5 imageio ipywidgets>=7.5.1 From b44ffc054d4a8ec6c75f63c0c660d02f82ceba45 Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Sun, 19 Jan 2020 19:40:10 -0500 Subject: [PATCH 4/6] DOC: Notebook content for serializing ParameterObject's --- .gitignore | 1 + examples/2_RegistrationParameters.ipynb | 333 ++++++++++++++++++++---- 2 files changed, 283 insertions(+), 51 deletions(-) diff --git a/.gitignore b/.gitignore index 9420924f..e1e5d52a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ tools/ zstd-1.2.0-linux.tar zstd-1.2.0-linux/ .ipynb_checkpoints/ +examples/Parameters.*.txt diff --git a/examples/2_RegistrationParameters.ipynb b/examples/2_RegistrationParameters.ipynb index aec6e4e1..cb19a2ca 100644 --- a/examples/2_RegistrationParameters.ipynb +++ b/examples/2_RegistrationParameters.ipynb @@ -4,12 +4,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Examine and Modify Registration Parameters" + "# Examine, Modify, and Save Registration Parameters" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -23,12 +23,12 @@ "source": [ "[Elastix registration parameters](http://elastix.isi.uu.nl/doxygen/parameter.html) are stored in a *ParameterObject*.\n", "\n", - "Let's find out how to examine default registration parameters and modify their values." + "Let's find out how to examine default registration parameters, modify their values, and serialize them." ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -37,17 +37,17 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Self (0x1d64050)\n", + "Self (0x55e28544c5e0)\n", " RTTI typeinfo: elastix::ParameterObject\n", " Reference Count: 1\n", - " Modified Time: 67\n", + " Modified Time: 56\n", " Debug: Off\n", " Object Name: \n", " Observers: \n", @@ -106,7 +106,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -115,13 +115,13 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "19343049a8924fe58728b36450e4d93c", + "model_id": "85298f1bfb5d40bcb220771e8f155595", "version_major": 2, "version_minor": 0 }, @@ -139,7 +139,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -148,13 +148,13 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "9d154703982645b3b90061a0a21e371a", + "model_id": "9511aa67abc14a0d97c3fe7e29607618", "version_major": 2, "version_minor": 0 }, @@ -172,13 +172,13 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "b7c66cb3e4b344dab22a4c22f98b68d1", + "model_id": "a67097d976ae47adb5365419b32d2b9e", "version_major": 2, "version_minor": 0 }, @@ -196,7 +196,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 35, "metadata": {}, "outputs": [], "source": [ @@ -205,13 +205,13 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "437243537e33433094d574fd2da5b1cb", + "model_id": "29002952ddea4cf9b6e9337c58430da6", "version_major": 2, "version_minor": 0 }, @@ -240,17 +240,17 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Self (0x1d64050)\n", + "Self (0x55e2865a1e60)\n", " RTTI typeinfo: elastix::ParameterObject\n", " Reference Count: 1\n", - " Modified Time: 24855\n", + " Modified Time: 49515\n", " Debug: Off\n", " Object Name: \n", " Observers: \n", @@ -322,17 +322,17 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Self (0x1d64050)\n", + "Self (0x55e2865a1e60)\n", " RTTI typeinfo: elastix::ParameterObject\n", " Reference Count: 1\n", - " Modified Time: 24856\n", + " Modified Time: 49516\n", " Debug: Off\n", " Object Name: \n", " Observers: \n", @@ -432,37 +432,17 @@ }, { "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "parameters.GetNumberOfParameterMaps()" - ] - }, - { - "cell_type": "code", - "execution_count": 33, + "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Self (0x1d64050)\n", + "Self (0x55e2865a1e60)\n", " RTTI typeinfo: elastix::ParameterObject\n", " Reference Count: 1\n", - " Modified Time: 24856\n", + " Modified Time: 49516\n", " Debug: Off\n", " Object Name: \n", " Observers: \n", @@ -560,17 +540,17 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Self (0x1d64050)\n", + "Self (0x55e2865a1e60)\n", " RTTI typeinfo: elastix::ParameterObject\n", " Reference Count: 1\n", - " Modified Time: 24856\n", + " Modified Time: 49516\n", " Debug: Off\n", " Object Name: \n", " Observers: \n", @@ -664,6 +644,257 @@ "print(parameters)" ] }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Self (0x55e2865a1e60)\n", + " RTTI typeinfo: elastix::ParameterObject\n", + " Reference Count: 1\n", + " Modified Time: 49516\n", + " Debug: Off\n", + " Object Name: \n", + " Observers: \n", + " none\n", + "ParameterMap 0: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (AutomaticTransformInitialization \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\")\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 5)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (Transform \"TranslationTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "ParameterMap 1: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (AutomaticScalesEstimation \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\")\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 5)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (Transform \"AffineTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "ParameterMap 2: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FinalGridSpacingInPhysicalUnits 20)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (GridSpacingSchedule 1)\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\" \"TransformBendingEnergyPenalty\")\n", + " (Metric0Weight 1)\n", + " (Metric1Weight 1)\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 5)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiMetricMultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (Transform \"BSplineTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "\n" + ] + } + ], + "source": [ + "# Remove a parameter\n", + "parameters.RemoveParameter(\"ResultImageFormat\")\n", + "\n", + "print(parameters)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(AutomaticParameterEstimation \"true\")\n", + "(AutomaticScalesEstimation \"true\")\n", + "(CheckNumberOfSamples \"true\")\n", + "(DefaultPixelValue 0.000000)\n", + "(FinalBSplineInterpolationOrder 3.000000)\n", + "(FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + "(ImageSampler \"RandomCoordinate\")\n", + "(Interpolator \"LinearInterpolator\")\n", + "(MaximumNumberOfIterations 256.000000)\n", + "(MaximumNumberOfSamplingAttempts 8.000000)\n", + "(Metric \"AdvancedMattesMutualInformation\")\n", + "(MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + "(NewSamplesEveryIteration \"true\")\n", + "(NumberOfResolutions 5.000000)\n", + "(NumberOfSamplesForExactGradient 4096.000000)\n", + "(NumberOfSpatialSamples 2048.000000)\n", + "(Optimizer \"AdaptiveStochasticGradientDescent\")\n", + "(Registration \"MultiResolutionRegistration\")\n", + "(ResampleInterpolator \"FinalBSplineInterpolator\")\n", + "(Resampler \"DefaultResampler\")\n", + "(Transform \"AffineTransform\")\n", + "(WriteIterationInfo \"false\")\n", + "(WriteResultImage \"true\")\n" + ] + } + ], + "source": [ + "# Each parameter map can be serialized to a file.\n", + "for index in range(parameters.GetNumberOfParameterMaps()):\n", + " parameter_map = parameters.GetParameterMap(index)\n", + " parameters.WriteParameterFile(parameter_map, \"Parameters.{0}.txt\".format(index))\n", + " \n", + "%cat Parameters.1.txt" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Self (0x55e287b14970)\n", + " RTTI typeinfo: elastix::ParameterObject\n", + " Reference Count: 1\n", + " Modified Time: 49521\n", + " Debug: Off\n", + " Object Name: \n", + " Observers: \n", + " none\n", + "ParameterMap 0: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (AutomaticTransformInitialization \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\")\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 5)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (Transform \"TranslationTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "ParameterMap 1: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (AutomaticScalesEstimation \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\")\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 5)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (Transform \"AffineTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "ParameterMap 2: \n", + " (AutomaticParameterEstimation \"true\")\n", + " (CheckNumberOfSamples \"true\")\n", + " (DefaultPixelValue 0)\n", + " (FinalBSplineInterpolationOrder 3)\n", + " (FinalGridSpacingInPhysicalUnits 20)\n", + " (FixedImagePyramid \"FixedSmoothingImagePyramid\")\n", + " (GridSpacingSchedule 1)\n", + " (ImageSampler \"RandomCoordinate\")\n", + " (Interpolator \"LinearInterpolator\")\n", + " (MaximumNumberOfIterations 256)\n", + " (MaximumNumberOfSamplingAttempts 8)\n", + " (Metric \"AdvancedMattesMutualInformation\" \"TransformBendingEnergyPenalty\")\n", + " (Metric0Weight 1)\n", + " (Metric1Weight 1)\n", + " (MovingImagePyramid \"MovingSmoothingImagePyramid\")\n", + " (NewSamplesEveryIteration \"true\")\n", + " (NumberOfResolutions 5)\n", + " (NumberOfSamplesForExactGradient 4096)\n", + " (NumberOfSpatialSamples 2048)\n", + " (Optimizer \"AdaptiveStochasticGradientDescent\")\n", + " (Registration \"MultiMetricMultiResolutionRegistration\")\n", + " (ResampleInterpolator \"FinalBSplineInterpolator\")\n", + " (Resampler \"DefaultResampler\")\n", + " (Transform \"BSplineTransform\")\n", + " (WriteIterationInfo \"false\")\n", + " (WriteResultImage \"true\")\n", + "\n" + ] + } + ], + "source": [ + "# To deserialize the parameters\n", + "parameter_files = [\"Parameters.{0}.txt\".format(i) for i in range(3)]\n", + "restored_parameters = itk.ParameterObject.New()\n", + "restored_parameters.ReadParameterFile(parameter_files)\n", + "print(restored_parameters)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -688,7 +919,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.9" + "version": "3.7.6" } }, "nbformat": 4, From c3520b7381de19f16449abe624f14b47654cdabc Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Sun, 19 Jan 2020 19:50:57 -0500 Subject: [PATCH 5/6] DOC: Use compare widget in notebooks --- examples/0_HelloRegistrationWorld.ipynb | 125 ++++++------------------ examples/1_NumPyArray.ipynb | 69 +++++-------- examples/2_RegistrationParameters.ipynb | 60 +++--------- 3 files changed, 68 insertions(+), 186 deletions(-) diff --git a/examples/0_HelloRegistrationWorld.ipynb b/examples/0_HelloRegistrationWorld.ipynb index 67f0ac47..f8ed5d3b 100644 --- a/examples/0_HelloRegistrationWorld.ipynb +++ b/examples/0_HelloRegistrationWorld.ipynb @@ -9,12 +9,12 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import itk\n", - "from itkwidgets import view, checkerboard" + "from itkwidgets import view, compare, checkerboard" ] }, { @@ -30,72 +30,33 @@ "source": [ "In image registration, we typically identify the two images as the fixed and moving image. Our goal is to find the spatial transformation that makes the moving image align with the fixed image.\n", "\n", - "First, let's load our **fixed image**." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "fixed = itk.imread('data/CT_2D_head_fixed.mha', itk.F)" + "First, let's load our **fixed image** and the image we will align to our fixed image, the **moving image**." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "e4158972d1a04e098425a4f40d0e7c4b", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Viewer(geometries=[], gradient_opacity=0.22, point_sets=[], rendered_image= Date: Mon, 20 Jan 2020 10:44:38 -0500 Subject: [PATCH 6/6] DOC: Link to elastix manual and elastix parameter file database --- examples/2_RegistrationParameters.ipynb | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/examples/2_RegistrationParameters.ipynb b/examples/2_RegistrationParameters.ipynb index c9e8067a..3d874bd9 100644 --- a/examples/2_RegistrationParameters.ipynb +++ b/examples/2_RegistrationParameters.ipynb @@ -203,7 +203,18 @@ "\n", "Typically, we start with a simple spatial transformation and advance to a more complex spatial transformation.\n", "\n", - "The default, conservative, registration parameters progress from a *translation -> affine -> bspline* transformation, with 4 resolutions for each transformation type." + "The default, conservative, registration parameters progress from a *translation -> affine -> bspline* transformation, with 4 resolutions for each transformation type.\n", + "\n", + "A default set of registration parameters are available for\n", + "\n", + "- *translation*\n", + "- *rigid*\n", + "- *affine*\n", + "- *bspline*\n", + "- *spline*\n", + "- *groupwise*\n", + "\n", + "transformations. More information on these transformation can be found in the [elastix manual](http://elastix.isi.uu.nl/download/elastix-5.0.0-manual.pdf)." ] }, { @@ -867,7 +878,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "For more information on the available parameters and their meaning, see the [Elastix Parameters](http://elastix.isi.uu.nl/doxygen/parameter.html) documentation." + "For more information on the available parameters and their meaning, see the [Elastix Parameters](http://elastix.isi.uu.nl/doxygen/parameter.html) documentation.\n", + "\n", + "A database of parameter sets that work well for specific types of data can be found in the [elastix parameter file database](http://elastix.bigr.nl/wiki/index.php/Parameter_file_database)." ] } ],