21 #ifndef __otbNCCRegistrationFunction_txx
22 #define __otbNCCRegistrationFunction_txx
27 #include "vnl/vnl_math.h"
35 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
42 for (j = 0; j < ImageDimension; ++j)
50 m_DenominatorThreshold = 1e-9;
51 m_IntensityDifferenceThreshold = 0.001;
52 this->SetMovingImage(
NULL);
53 this->SetFixedImage(
NULL);
54 m_FixedImageSpacing.Fill(1.0);
55 m_FixedImageOrigin.Fill(0.0);
56 m_FixedImageGradientCalculator = GradientCalculatorType::New();
59 DefaultInterpolatorType::New();
69 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
75 Superclass::PrintSelf(os, indent);
91 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
96 if (!this->m_MovingImage || !this->m_FixedImage || !m_MovingImageInterpolator)
98 itkExceptionMacro(<<
"MovingImage, FixedImage and/or Interpolator not set");
102 m_FixedImageSpacing = this->m_FixedImage->GetSpacing();
103 m_FixedImageOrigin = this->m_FixedImage->GetOrigin();
106 m_FixedImageGradientCalculator->SetInputImage(this->m_FixedImage);
109 m_MovingImageInterpolator->SetInputImage(this->m_MovingImage);
111 otbMsgDevMacro(
" total metric " << m_MetricTotal <<
" field size " <<
112 this->GetDeformationField()->GetLargestPossibleRegion().GetSize() <<
" image size " <<
113 this->m_FixedImage->GetLargestPossibleRegion().GetSize() );
121 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
135 typename FixedImageType::SizeType hradius = it.
GetRadius();
139 typename FixedImageType::SizeType imagesize = img->GetLargestPossibleRegion().
GetSize();
142 hoodIt(hradius, img, img->GetRequestedRegion());
151 double derivativeF[ImageDimension];
152 double derivativeM[ImageDimension];
153 for (j = 0; j < ImageDimension; ++j)
160 unsigned int hoodlen = hoodIt.Size();
162 for (indct = 0; indct < hoodlen - 1; indct++)
165 IndexType index = hoodIt.GetIndex(indct);
168 for (
unsigned int dd = 0; dd < ImageDimension; dd++)
170 if (index[dd] < 0 || index[dd] >
171 static_cast<typename IndexType::IndexValueType>(imagesize[dd] - 1)) inimage =
false;
180 double fixedGradientSquaredMagnitude = 0;
184 fixedValue = (double) this->m_FixedImage->GetPixel(index);
186 fixedGradient = m_FixedImageGradientCalculator->EvaluateAtIndex(index);
187 for (j = 0; j < ImageDimension; ++j)
189 fixedGradientSquaredMagnitude += vnl_math_sqr(fixedGradient[j]) * m_FixedImageSpacing[j];
196 typedef typename TDeformationField::PixelType DeformationPixelType;
199 DeformationPixelType vec;
201 if (this->GetDeformationField()->GetBufferedRegion().IsInside(index))
203 vec = this->GetDeformationField()->GetPixel(index);
207 for (j = 0; j < ImageDimension; ++j)
209 mappedPoint[j] = double(index[j]) * m_FixedImageSpacing[j] +
210 m_FixedImageOrigin[j];
211 mappedPoint[j] += vec[j];
213 if (m_MovingImageInterpolator->IsInsideBuffer(mappedPoint))
215 movingValue = m_MovingImageInterpolator->Evaluate(mappedPoint);
222 sff += fixedValue * fixedValue;
223 smm += movingValue * movingValue;
224 sfm += fixedValue * movingValue;
226 for (
unsigned int dim = 0; dim < ImageDimension; ++dim)
228 double differential = fixedGradient[dim];
229 derivativeF[dim] += fixedValue * differential;
230 derivativeM[dim] += movingValue * differential;
236 double updatenorm = 0.0;
237 if ((sff * smm) != 0.0)
239 double factor = 1.0 / vcl_sqrt(sff * smm);
240 for (
unsigned int i = 0; i < ImageDimension; ++i)
242 update[i] = factor * (derivativeF[i] - (sfm / smm) * derivativeM[i]);
243 updatenorm += (update[i] * update[i]);
245 updatenorm = vcl_sqrt(updatenorm);
246 m_MetricTotal += sfm * factor;
247 this->m_Energy += sfm * factor;
251 for (
unsigned int i = 0; i < ImageDimension; ++i)
260 if (this->GetNormalizeGradient() && updatenorm != 0.0)
262 update /= (updatenorm);
265 return update * this->m_GradientStep;