1 /*===================================================================
3 The Medical Imaging Interaction Toolkit (MITK)
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 See LICENSE.txt or http://www.mitk.org for details.
15 ===================================================================*/
17 #include "mitkImageRegistrationMethod.h"
18 #include "mitkImageRegistrationMethodAccessFunctor.h"
20 #include <mitkImageCast.h>
22 #include <itkLinearInterpolateImageFunction.h>
23 #include <itkMultiResolutionImageRegistrationMethod.h>
27 template <typename TPixel, unsigned int VImageDimension>
28 void ImageRegistrationMethodAccessFunctor::AccessItkImage(const itk::Image<TPixel, VImageDimension> *itkImage1,
29 ImageRegistrationMethod *method)
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())
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());
49 typename ImageMaskType::Pointer fixedImageMask;
50 if (method->m_FixedMask.IsNotNull())
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());
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);
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);
88 TransformPointer transform = dynamic_cast<TransformType *>(method->m_Transform.GetPointer());
89 if (transform.IsNull())
90 mitkThrow() << "Failed to retrieve registration transform, dynamic cast failed";
93 typename OptimizerType::Pointer optimizer = dynamic_cast<OptimizerType *>(method->m_Optimizer.GetPointer());
96 if (method->m_OptimizerScales.Size() != 0)
98 typename OptimizerType::ScalesType scales(transform->GetNumberOfParameters());
99 for (unsigned int i = 0; i < scales.Size(); i++)
101 scales[i] = method->m_OptimizerScales[i];
103 optimizer->SetScales(scales);
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());
115 // set initial position to identity by first setting the transformation to identity
116 // and then using its parameters
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)
123 matrix_transform->SetIdentity();
124 identityParameters = matrix_transform->GetParameters();
127 registration->SetInitialTransformParameters(identityParameters);
128 optimizer->SetInitialPosition(identityParameters);
130 if (method->m_Interpolator == ImageRegistrationMethod::LINEARINTERPOLATOR)
132 typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
133 registration->SetInterpolator(interpolator);
135 else if (method->m_Interpolator == ImageRegistrationMethod::NEARESTNEIGHBORINTERPOLATOR)
137 typename InterpolatorType2::Pointer interpolator = InterpolatorType2::New();
138 registration->SetInterpolator(interpolator);
141 // registering command observer with the optimizer
142 unsigned int pyramid_observer_tag = 0;
143 if (method->m_Observer.IsNotNull())
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);
150 typename mitk::RigidRegistrationPyramidObserver<RegistrationType>::Pointer pyramid_observer =
151 mitk::RigidRegistrationPyramidObserver<RegistrationType>::New();
153 pyramid_observer_tag = registration->AddObserver(itk::IterationEvent(), pyramid_observer);
156 registration->Update();
158 if (pyramid_observer_tag)
160 registration->RemoveObserver(pyramid_observer_tag);
163 if (method->m_Observer.IsNotNull())
165 optimizer->RemoveAllObservers();
166 registration->RemoveAllObservers();
167 transform->RemoveAllObservers();
168 method->m_Observer->SetRemainingProgress(15);
171 if (method->m_Observer.IsNotNull())
173 method->m_Observer->SetRemainingProgress(5);