Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkImageRegistrationMethodAccessFunctor.txx
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkImageRegistrationMethod.h"
18 #include "mitkImageRegistrationMethodAccessFunctor.h"
19 
20 #include <mitkImageCast.h>
21 
22 #include <itkLinearInterpolateImageFunction.h>
23 #include <itkMultiResolutionImageRegistrationMethod.h>
24 
25 namespace mitk
26 {
27  template <typename TPixel, unsigned int VImageDimension>
28  void ImageRegistrationMethodAccessFunctor::AccessItkImage(const itk::Image<TPixel, VImageDimension> *itkImage1,
29  ImageRegistrationMethod *method)
30  {
31  // convert mitk masks to itk masks
32  typedef typename itk::Image<TPixel, VImageDimension> FixedImageType;
33  typedef typename itk::Image<TPixel, VImageDimension> MovingImageType;
34  typedef typename itk::Image<unsigned char, VImageDimension> MaskImageType;
35  typedef typename itk::ImageMaskSpatialObject<VImageDimension> ImageMaskType;
36  typename ImageMaskType::Pointer movingImageMask;
37  if (method->m_MovingMask.IsNotNull())
38  {
39  typename MovingImageType::Pointer movingMask = MovingImageType::New();
40  mitk::CastToItkImage(method->m_MovingMask, movingMask);
41  typename itk::CastImageFilter<MovingImageType, MaskImageType>::Pointer maskImageCaster =
42  itk::CastImageFilter<MovingImageType, MaskImageType>::New();
43  maskImageCaster->SetInput(movingMask);
44  maskImageCaster->UpdateLargestPossibleRegion();
45  movingImageMask = ImageMaskType::New();
46  movingImageMask->SetImage(maskImageCaster->GetOutput());
47  }
48 
49  typename ImageMaskType::Pointer fixedImageMask;
50  if (method->m_FixedMask.IsNotNull())
51  {
52  typename FixedImageType::Pointer fixedMask = FixedImageType::New();
53  mitk::CastToItkImage(method->m_FixedMask, fixedMask);
54  typename itk::CastImageFilter<FixedImageType, MaskImageType>::Pointer maskImageCaster =
55  itk::CastImageFilter<FixedImageType, MaskImageType>::New();
56  maskImageCaster->SetInput(fixedMask);
57  maskImageCaster->UpdateLargestPossibleRegion();
58  fixedImageMask = ImageMaskType::New();
59  fixedImageMask->SetImage(maskImageCaster->GetOutput());
60  }
61 
62  // typedefs
63  typedef typename itk::Image<TPixel, VImageDimension> FixedImageType;
64  typedef typename itk::Image<TPixel, VImageDimension> MovingImageType;
65  typedef typename itk::LinearInterpolateImageFunction<MovingImageType, double> InterpolatorType;
66  typedef itk::NearestNeighborInterpolateImageFunction<MovingImageType, double> InterpolatorType2;
67  // typedef typename itk::ImageRegistrationMethod<FixedImageType, MovingImageType> RegistrationType;
68  typedef typename itk::MultiResolutionImageRegistrationMethod<FixedImageType, MovingImageType> RegistrationType;
69  typedef typename itk::Transform<double, VImageDimension, VImageDimension> TransformType;
70  typedef typename itk::MatrixOffsetTransformBase<double, VImageDimension, VImageDimension> MatrixTransformType;
71  typedef typename TransformType::Pointer TransformPointer;
72  typedef typename itk::ImageToImageMetric<FixedImageType, MovingImageType> MetricType;
73  typedef typename MetricType::Pointer MetricPointer;
74  typedef typename itk::SingleValuedNonLinearOptimizer OptimizerType;
75  // the fixed and the moving image
76  typename FixedImageType::Pointer fixedImage = FixedImageType::New();
77  typename MovingImageType::ConstPointer movingImage = itkImage1;
78  mitk::CastToItkImage(method->m_ReferenceImage, fixedImage);
79 
80  // the metric
81  MetricPointer metric = dynamic_cast<MetricType *>(method->m_Metric.GetPointer());
82  if (movingImageMask.IsNotNull())
83  metric->SetMovingImageMask(movingImageMask);
84  if (fixedImageMask.IsNotNull())
85  metric->SetFixedImageMask(fixedImageMask);
86 
87  // the transform
88  TransformPointer transform = dynamic_cast<TransformType *>(method->m_Transform.GetPointer());
89  if (transform.IsNull())
90  mitkThrow() << "Failed to retrieve registration transform, dynamic cast failed";
91 
92  // the optimizer
93  typename OptimizerType::Pointer optimizer = dynamic_cast<OptimizerType *>(method->m_Optimizer.GetPointer());
94 
95  // optimizer scales
96  if (method->m_OptimizerScales.Size() != 0)
97  {
98  typename OptimizerType::ScalesType scales(transform->GetNumberOfParameters());
99  for (unsigned int i = 0; i < scales.Size(); i++)
100  {
101  scales[i] = method->m_OptimizerScales[i];
102  }
103  optimizer->SetScales(scales);
104  }
105  // the registration method
106  typename RegistrationType::Pointer registration = RegistrationType::New();
107  registration->SetNumberOfLevels(method->m_MultiResolutionScales);
108  registration->SetMetric(metric);
109  registration->SetOptimizer(optimizer);
110  registration->SetTransform(transform);
111  registration->SetFixedImage(fixedImage);
112  registration->SetMovingImage(movingImage);
113  registration->SetFixedImageRegion(fixedImage->GetBufferedRegion());
114 
115  // set initial position to identity by first setting the transformation to identity
116  // and then using its parameters
117 
118  typename TransformType::ParametersType identityParameters = transform->GetParameters();
119  // the SetIdentity avialable only for a transform subset (of type matrix offset)
120  MatrixTransformType *matrix_transform = dynamic_cast<MatrixTransformType *>(method->m_Transform.GetPointer());
121  if (matrix_transform != nullptr)
122  {
123  matrix_transform->SetIdentity();
124  identityParameters = matrix_transform->GetParameters();
125  }
126 
127  registration->SetInitialTransformParameters(identityParameters);
128  optimizer->SetInitialPosition(identityParameters);
129 
130  if (method->m_Interpolator == ImageRegistrationMethod::LINEARINTERPOLATOR)
131  {
132  typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
133  registration->SetInterpolator(interpolator);
134  }
135  else if (method->m_Interpolator == ImageRegistrationMethod::NEARESTNEIGHBORINTERPOLATOR)
136  {
137  typename InterpolatorType2::Pointer interpolator = InterpolatorType2::New();
138  registration->SetInterpolator(interpolator);
139  }
140 
141  // registering command observer with the optimizer
142  unsigned int pyramid_observer_tag = 0;
143  if (method->m_Observer.IsNotNull())
144  {
145  method->m_Observer->AddStepsToDo(20);
146  optimizer->AddObserver(itk::IterationEvent(), method->m_Observer);
147  // registration->AddObserver(itk::IterationEvent(), method->m_Observer);
148  transform->AddObserver(itk::IterationEvent(), method->m_Observer);
149 
150  typename mitk::RigidRegistrationPyramidObserver<RegistrationType>::Pointer pyramid_observer =
151  mitk::RigidRegistrationPyramidObserver<RegistrationType>::New();
152 
153  pyramid_observer_tag = registration->AddObserver(itk::IterationEvent(), pyramid_observer);
154  }
155 
156  registration->Update();
157 
158  if (pyramid_observer_tag)
159  {
160  registration->RemoveObserver(pyramid_observer_tag);
161  }
162 
163  if (method->m_Observer.IsNotNull())
164  {
165  optimizer->RemoveAllObservers();
166  registration->RemoveAllObservers();
167  transform->RemoveAllObservers();
168  method->m_Observer->SetRemainingProgress(15);
169  }
170 
171  if (method->m_Observer.IsNotNull())
172  {
173  method->m_Observer->SetRemainingProgress(5);
174  }
175  }
176 
177 } // end namespace