22 #ifndef otbNCCRegistrationFunction_hxx
23 #define otbNCCRegistrationFunction_hxx
25 #include "vnl/vnl_math.h"
26 #include "itkNeighborhoodIterator.h"
30 #include "vcl_legacy_aliases.h"
38 template <
class TFixedImage,
class TMovingImage,
class TDisplacementField>
44 for (j = 0; j < ImageDimension; ++j)
52 m_DenominatorThreshold = 1e-9;
53 m_IntensityDifferenceThreshold = 0.001;
54 this->SetMovingImage(
nullptr);
55 this->SetFixedImage(
nullptr);
56 m_FixedImageSpacing.Fill(1.0);
57 m_FixedImageOrigin.Fill(0.0);
58 m_FixedImageGradientCalculator = GradientCalculatorType::New();
60 typename DefaultInterpolatorType::Pointer interp = DefaultInterpolatorType::New();
62 m_MovingImageInterpolator =
static_cast<InterpolatorType*
>(interp.GetPointer());
68 template <
class TFixedImage,
class TMovingImage,
class TDisplacementField>
72 Superclass::PrintSelf(os, indent);
88 template <
class TFixedImage,
class TMovingImage,
class TDisplacementField>
91 if (!this->m_MovingImage || !this->m_FixedImage || !m_MovingImageInterpolator)
93 itkExceptionMacro(<<
"MovingImage, FixedImage and/or Interpolator not set");
97 m_FixedImageSpacing = this->m_FixedImage->GetSignedSpacing();
98 m_FixedImageOrigin = this->m_FixedImage->GetOrigin();
101 m_FixedImageGradientCalculator->SetInputImage(this->m_FixedImage);
104 m_MovingImageInterpolator->SetInputImage(this->m_MovingImage);
106 otbMsgDevMacro(
" total metric " << m_MetricTotal <<
" field size " << this->GetDisplacementField()->GetLargestPossibleRegion().GetSize() <<
" image size "
107 << this->m_FixedImage->GetLargestPossibleRegion().GetSize());
114 template <
class TFixedImage,
class TMovingImage,
class TDisplacementField>
126 typename FixedImageType::SizeType hradius = it.GetRadius();
130 typename FixedImageType::SizeType imagesize = img->GetLargestPossibleRegion().GetSize();
132 itk::NeighborhoodIterator<FixedImageType> hoodIt(hradius, img, img->GetRequestedRegion());
133 hoodIt.SetLocation(oindex);
141 double derivativeF[ImageDimension];
142 double derivativeM[ImageDimension];
143 for (j = 0; j < ImageDimension; ++j)
150 unsigned int hoodlen = hoodIt.Size();
152 for (indct = 0; indct < hoodlen - 1; indct++)
155 IndexType index = hoodIt.GetIndex(indct);
158 for (
unsigned int dd = 0; dd < ImageDimension; dd++)
160 if (index[dd] < 0 || index[dd] >
static_cast<typename IndexType::IndexValueType
>(imagesize[dd] - 1))
170 double fixedGradientSquaredMagnitude = 0;
174 fixedValue = (double)this->m_FixedImage->GetPixel(index);
176 fixedGradient = m_FixedImageGradientCalculator->EvaluateAtIndex(index);
177 for (j = 0; j < ImageDimension; ++j)
179 fixedGradientSquaredMagnitude += vnl_math_sqr(fixedGradient[j]) * m_FixedImageSpacing[j];
186 typedef typename TDisplacementField::PixelType DisplacementPixelType;
189 DisplacementPixelType vec;
191 if (this->GetDisplacementField()->GetBufferedRegion().IsInside(index))
193 vec = this->GetDisplacementField()->GetPixel(index);
197 for (j = 0; j < ImageDimension; ++j)
199 mappedPoint[j] = double(index[j]) * m_FixedImageSpacing[j] + m_FixedImageOrigin[j];
200 mappedPoint[j] += vec[j];
202 if (m_MovingImageInterpolator->IsInsideBuffer(mappedPoint))
204 movingValue = m_MovingImageInterpolator->Evaluate(mappedPoint);
211 sff += fixedValue * fixedValue;
212 smm += movingValue * movingValue;
213 sfm += fixedValue * movingValue;
215 for (
unsigned int dim = 0; dim < ImageDimension; ++dim)
217 double differential = fixedGradient[dim];
218 derivativeF[dim] += fixedValue * differential;
219 derivativeM[dim] += movingValue * differential;
224 double updatenorm = 0.0;
225 if ((sff * smm) != 0.0)
227 double factor = 1.0 / std::sqrt(sff * smm);
228 for (
unsigned int i = 0; i < ImageDimension; ++i)
230 update[i] = factor * (derivativeF[i] - (sfm / smm) * derivativeM[i]);
231 updatenorm += (update[i] * update[i]);
233 updatenorm = std::sqrt(updatenorm);
234 m_MetricTotal += sfm * factor;
235 this->m_Energy += sfm * factor;
239 for (
unsigned int i = 0; i < ImageDimension; ++i)
248 if (this->GetNormalizeGradient() && updatenorm != 0.0)
250 update /= (updatenorm);
253 return update * this->m_GradientStep;
Superclass::FloatOffsetType FloatOffsetType
void InitializeIteration() override
Superclass::NeighborhoodType NeighborhoodType
NCCRegistrationFunction()
itk::CovariantVector< double, itkGetStaticConstMacro(ImageDimension)> CovariantVectorType
Superclass::RadiusType RadiusType
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Superclass::PixelType PixelType
FixedImageType::IndexType IndexType
InterpolatorType::PointType PointType
itk::InterpolateImageFunction< MovingImageType, CoordRepType > InterpolatorType
Superclass::FixedImageType FixedImageType
PixelType ComputeUpdate(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset=FloatOffsetType(0.0)) override
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
#define otbMsgDevMacro(x)