OTB  9.0.0
Orfeo Toolbox
otbNCCRegistrationFunction.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1999-2011 Insight Software Consortium
3  * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
4  *
5  * This file is part of Orfeo Toolbox
6  *
7  * https://www.orfeo-toolbox.org/
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 #ifndef otbNCCRegistrationFunction_hxx
23 #define otbNCCRegistrationFunction_hxx
24 
25 #include "vnl/vnl_math.h"
26 #include "itkNeighborhoodIterator.h"
27 
28 #include "otbMacro.h"
30 
31 namespace otb
32 {
33 
34 /*
35  * Default constructor
36  */
37 template <class TFixedImage, class TMovingImage, class TDisplacementField>
39 {
40 
41  RadiusType r;
42  unsigned int j;
43  for (j = 0; j < ImageDimension; ++j)
44  {
45  r[j] = 1;
46  }
47  this->SetRadius(r);
48  m_MetricTotal = 0.0;
49 
50  m_TimeStep = 1.0;
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();
58 
59  typename DefaultInterpolatorType::Pointer interp = DefaultInterpolatorType::New();
60 
61  m_MovingImageInterpolator = static_cast<InterpolatorType*>(interp.GetPointer());
62 }
63 
64 /*
65  * Standard "PrintSelf" method.
66  */
67 template <class TFixedImage, class TMovingImage, class TDisplacementField>
69 {
70 
71  Superclass::PrintSelf(os, indent);
72  /*
73  os << indent << "MovingImageIterpolator: ";
74  os << m_MovingImageInterpolator.GetPointer() << std::endl;
75  os << indent << "FixedImageGradientCalculator: ";
76  os << m_FixedImageGradientCalculator.GetPointer() << std::endl;
77  os << indent << "DenominatorThreshold: ";
78  os << m_DenominatorThreshold << std::endl;
79  os << indent << "IntensityDifferenceThreshold: ";
80  os << m_IntensityDifferenceThreshold << std::endl;
81  */
82 }
83 
84 /*
85  * Set the function state values before each iteration
86  */
87 template <class TFixedImage, class TMovingImage, class TDisplacementField>
89 {
90  if (!this->m_MovingImage || !this->m_FixedImage || !m_MovingImageInterpolator)
91  {
92  itkExceptionMacro(<< "MovingImage, FixedImage and/or Interpolator not set");
93  }
94 
95  // cache fixed image information
96  m_FixedImageSpacing = this->m_FixedImage->GetSignedSpacing();
97  m_FixedImageOrigin = this->m_FixedImage->GetOrigin();
98 
99  // setup gradient calculator
100  m_FixedImageGradientCalculator->SetInputImage(this->m_FixedImage);
101 
102  // setup moving image interpolator
103  m_MovingImageInterpolator->SetInputImage(this->m_MovingImage);
104 
105  otbMsgDevMacro(" total metric " << m_MetricTotal << " field size " << this->GetDisplacementField()->GetLargestPossibleRegion().GetSize() << " image size "
106  << this->m_FixedImage->GetLargestPossibleRegion().GetSize());
107  m_MetricTotal = 0.0;
108 }
109 
110 /*
111  * Compute update at a non boundary neighbourhood
112  */
113 template <class TFixedImage, class TMovingImage, class TDisplacementField>
116  const FloatOffsetType& itkNotUsed(offset))
117 {
118 
119  PixelType update;
120  update.Fill(0.0);
121  unsigned int j;
122 
123  IndexType oindex = it.GetIndex();
124 
125  typename FixedImageType::SizeType hradius = it.GetRadius();
126 
127  FixedImageType* img = const_cast<FixedImageType*>(this->m_FixedImage.GetPointer());
128 
129  typename FixedImageType::SizeType imagesize = img->GetLargestPossibleRegion().GetSize();
130 
131  itk::NeighborhoodIterator<FixedImageType> hoodIt(hradius, img, img->GetRequestedRegion());
132  hoodIt.SetLocation(oindex);
133 
134  double sff = 0.0;
135  double smm = 0.0;
136  double sfm = 0.0;
137  double fixedValue;
138  double movingValue;
139 
140  double derivativeF[ImageDimension];
141  double derivativeM[ImageDimension];
142  for (j = 0; j < ImageDimension; ++j)
143  {
144  derivativeF[j] = 0;
145  derivativeM[j] = 0;
146  }
147 
148  unsigned int indct;
149  unsigned int hoodlen = hoodIt.Size();
150 
151  for (indct = 0; indct < hoodlen - 1; indct++)
152  {
153 
154  IndexType index = hoodIt.GetIndex(indct);
155 
156  bool inimage = true;
157  for (unsigned int dd = 0; dd < ImageDimension; dd++)
158  {
159  if (index[dd] < 0 || index[dd] > static_cast<typename IndexType::IndexValueType>(imagesize[dd] - 1))
160  inimage = false;
161  }
162 
163  if (inimage)
164  {
165 
166  // Get fixed image related information
167 
168  CovariantVectorType fixedGradient;
169  double fixedGradientSquaredMagnitude = 0;
170 
171  // Note: no need to check the index is within
172  // fixed image buffer. This is done by the external filter.
173  fixedValue = (double)this->m_FixedImage->GetPixel(index);
174 
175  fixedGradient = m_FixedImageGradientCalculator->EvaluateAtIndex(index);
176  for (j = 0; j < ImageDimension; ++j)
177  {
178  fixedGradientSquaredMagnitude += vnl_math_sqr(fixedGradient[j]) * m_FixedImageSpacing[j];
179  }
180 
181  // Get moving image related information
182 
183  PointType mappedPoint;
184 
185  typedef typename TDisplacementField::PixelType DisplacementPixelType;
186 
187  // Edited by OTB developers
188  DisplacementPixelType vec;
189  vec.Fill(0);
190  if (this->GetDisplacementField()->GetBufferedRegion().IsInside(index))
191  {
192  vec = this->GetDisplacementField()->GetPixel(index);
193  }
194  // End Edited by OTB developers
195 
196  for (j = 0; j < ImageDimension; ++j)
197  {
198  mappedPoint[j] = double(index[j]) * m_FixedImageSpacing[j] + m_FixedImageOrigin[j];
199  mappedPoint[j] += vec[j];
200  }
201  if (m_MovingImageInterpolator->IsInsideBuffer(mappedPoint))
202  {
203  movingValue = m_MovingImageInterpolator->Evaluate(mappedPoint);
204  }
205  else
206  {
207  movingValue = 0.0;
208  }
209 
210  sff += fixedValue * fixedValue;
211  smm += movingValue * movingValue;
212  sfm += fixedValue * movingValue;
213 
214  for (unsigned int dim = 0; dim < ImageDimension; ++dim)
215  {
216  double differential = fixedGradient[dim];
217  derivativeF[dim] += fixedValue * differential;
218  derivativeM[dim] += movingValue * differential;
219  }
220  }
221  }
222 
223  double updatenorm = 0.0;
224  if ((sff * smm) != 0.0)
225  {
226  double factor = 1.0 / std::sqrt(sff * smm);
227  for (unsigned int i = 0; i < ImageDimension; ++i)
228  {
229  update[i] = factor * (derivativeF[i] - (sfm / smm) * derivativeM[i]);
230  updatenorm += (update[i] * update[i]);
231  }
232  updatenorm = std::sqrt(updatenorm);
233  m_MetricTotal += sfm * factor;
234  this->m_Energy += sfm * factor;
235  }
236  else
237  {
238  for (unsigned int i = 0; i < ImageDimension; ++i)
239  {
240  update[i] = 0.0;
241  }
242  updatenorm = 1.0;
243  }
244 
245  // if ( fixedValue > 0.40 && movingValue > 0.40) std::cout << " update norm " << updatenorm;
246 
247  if (this->GetNormalizeGradient() && updatenorm != 0.0)
248  {
249  update /= (updatenorm);
250  }
251 
252  return update * this->m_GradientStep;
253 }
254 
255 } // end namespace otbs
256 
257 #endif
otb::NCCRegistrationFunction::NCCRegistrationFunction
NCCRegistrationFunction()
Definition: otbNCCRegistrationFunction.hxx:38
otb::NCCRegistrationFunction::ComputeUpdate
PixelType ComputeUpdate(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset=FloatOffsetType(0.0)) override
Definition: otbNCCRegistrationFunction.hxx:115
otb::NCCRegistrationFunction::NeighborhoodType
Superclass::NeighborhoodType NeighborhoodType
Definition: otbNCCRegistrationFunction.h:86
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::NCCRegistrationFunction::FixedImageType
Superclass::FixedImageType FixedImageType
Definition: otbNCCRegistrationFunction.h:70
otbMacro.h
otb::NCCRegistrationFunction::InitializeIteration
void InitializeIteration() override
Definition: otbNCCRegistrationFunction.hxx:88
otb::NCCRegistrationFunction::IndexType
FixedImageType::IndexType IndexType
Definition: otbNCCRegistrationFunction.h:72
otb::NCCRegistrationFunction::RadiusType
Superclass::RadiusType RadiusType
Definition: otbNCCRegistrationFunction.h:85
otb::NCCRegistrationFunction::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Definition: otbNCCRegistrationFunction.hxx:68
otb::NCCRegistrationFunction::CovariantVectorType
itk::CovariantVector< double, itkGetStaticConstMacro(ImageDimension)> CovariantVectorType
Definition: otbNCCRegistrationFunction.h:99
otb::NCCRegistrationFunction::PointType
InterpolatorType::PointType PointType
Definition: otbNCCRegistrationFunction.h:95
otbMsgDevMacro
#define otbMsgDevMacro(x)
Definition: otbMacro.h:64
otb::NCCRegistrationFunction::FloatOffsetType
Superclass::FloatOffsetType FloatOffsetType
Definition: otbNCCRegistrationFunction.h:88
otb::NCCRegistrationFunction::PixelType
Superclass::PixelType PixelType
Definition: otbNCCRegistrationFunction.h:84
otb::NCCRegistrationFunction::InterpolatorType
itk::InterpolateImageFunction< MovingImageType, CoordRepType > InterpolatorType
Definition: otbNCCRegistrationFunction.h:93
otbNCCRegistrationFunction.h