22 #ifndef otbNCCRegistrationFunction_hxx
23 #define otbNCCRegistrationFunction_hxx
25 #include "vnl/vnl_math.h"
26 #include "itkNeighborhoodIterator.h"
37 template <
class TFixedImage,
class TMovingImage,
class TDisplacementField>
43 for (j = 0; j < ImageDimension; ++j)
51 m_DenominatorThreshold = 1e-9;
52 m_IntensityDifferenceThreshold = 0.001;
53 this->SetMovingImage(
nullptr);
54 this->SetFixedImage(
nullptr);
55 m_FixedImageSpacing.Fill(1.0);
56 m_FixedImageOrigin.Fill(0.0);
57 m_FixedImageGradientCalculator = GradientCalculatorType::New();
59 typename DefaultInterpolatorType::Pointer interp = DefaultInterpolatorType::New();
61 m_MovingImageInterpolator =
static_cast<InterpolatorType*
>(interp.GetPointer());
67 template <
class TFixedImage,
class TMovingImage,
class TDisplacementField>
71 Superclass::PrintSelf(os, indent);
87 template <
class TFixedImage,
class TMovingImage,
class TDisplacementField>
90 if (!this->m_MovingImage || !this->m_FixedImage || !m_MovingImageInterpolator)
92 itkExceptionMacro(<<
"MovingImage, FixedImage and/or Interpolator not set");
96 m_FixedImageSpacing = this->m_FixedImage->GetSignedSpacing();
97 m_FixedImageOrigin = this->m_FixedImage->GetOrigin();
100 m_FixedImageGradientCalculator->SetInputImage(this->m_FixedImage);
103 m_MovingImageInterpolator->SetInputImage(this->m_MovingImage);
105 otbMsgDevMacro(
" total metric " << m_MetricTotal <<
" field size " << this->GetDisplacementField()->GetLargestPossibleRegion().GetSize() <<
" image size "
106 << this->m_FixedImage->GetLargestPossibleRegion().GetSize());
113 template <
class TFixedImage,
class TMovingImage,
class TDisplacementField>
125 typename FixedImageType::SizeType hradius = it.GetRadius();
129 typename FixedImageType::SizeType imagesize = img->GetLargestPossibleRegion().GetSize();
131 itk::NeighborhoodIterator<FixedImageType> hoodIt(hradius, img, img->GetRequestedRegion());
132 hoodIt.SetLocation(oindex);
140 double derivativeF[ImageDimension];
141 double derivativeM[ImageDimension];
142 for (j = 0; j < ImageDimension; ++j)
149 unsigned int hoodlen = hoodIt.Size();
151 for (indct = 0; indct < hoodlen - 1; indct++)
154 IndexType index = hoodIt.GetIndex(indct);
157 for (
unsigned int dd = 0; dd < ImageDimension; dd++)
159 if (index[dd] < 0 || index[dd] >
static_cast<typename IndexType::IndexValueType
>(imagesize[dd] - 1))
169 double fixedGradientSquaredMagnitude = 0;
173 fixedValue = (double)this->m_FixedImage->GetPixel(index);
175 fixedGradient = m_FixedImageGradientCalculator->EvaluateAtIndex(index);
176 for (j = 0; j < ImageDimension; ++j)
178 fixedGradientSquaredMagnitude += vnl_math_sqr(fixedGradient[j]) * m_FixedImageSpacing[j];
185 typedef typename TDisplacementField::PixelType DisplacementPixelType;
188 DisplacementPixelType vec;
190 if (this->GetDisplacementField()->GetBufferedRegion().IsInside(index))
192 vec = this->GetDisplacementField()->GetPixel(index);
196 for (j = 0; j < ImageDimension; ++j)
198 mappedPoint[j] = double(index[j]) * m_FixedImageSpacing[j] + m_FixedImageOrigin[j];
199 mappedPoint[j] += vec[j];
201 if (m_MovingImageInterpolator->IsInsideBuffer(mappedPoint))
203 movingValue = m_MovingImageInterpolator->Evaluate(mappedPoint);
210 sff += fixedValue * fixedValue;
211 smm += movingValue * movingValue;
212 sfm += fixedValue * movingValue;
214 for (
unsigned int dim = 0; dim < ImageDimension; ++dim)
216 double differential = fixedGradient[dim];
217 derivativeF[dim] += fixedValue * differential;
218 derivativeM[dim] += movingValue * differential;
223 double updatenorm = 0.0;
224 if ((sff * smm) != 0.0)
226 double factor = 1.0 / std::sqrt(sff * smm);
227 for (
unsigned int i = 0; i < ImageDimension; ++i)
229 update[i] = factor * (derivativeF[i] - (sfm / smm) * derivativeM[i]);
230 updatenorm += (update[i] * update[i]);
232 updatenorm = std::sqrt(updatenorm);
233 m_MetricTotal += sfm * factor;
234 this->m_Energy += sfm * factor;
238 for (
unsigned int i = 0; i < ImageDimension; ++i)
247 if (this->GetNormalizeGradient() && updatenorm != 0.0)
249 update /= (updatenorm);
252 return update * this->m_GradientStep;