Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
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