Orfeo Toolbox  3.16
itkNCCRegistrationFunction.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkNCCRegistrationFunction.txx,v $
5  Language: C++
6  Date: $Date: 2009-01-26 21:45:53 $
7  Version: $Revision: 1.15 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #ifndef __itkNCCRegistrationFunction_txx
18 #define __itkNCCRegistrationFunction_txx
19 
21 #include "itkExceptionObject.h"
22 #include "vnl/vnl_math.h"
23 
24 namespace itk {
25 
29 template <class TFixedImage, class TMovingImage, class TDeformationField>
32 {
33 
34  RadiusType r;
35  unsigned int j;
36  for( j = 0; j < ImageDimension; j++ )
37  {
38  r[j] = 1;
39  }
40  this->SetRadius(r);
41  m_MetricTotal=0.0;
42 
43  m_TimeStep = 1.0;
44  m_DenominatorThreshold = 1e-9;
45  m_IntensityDifferenceThreshold = 0.001;
46  this->SetMovingImage(NULL);
47  this->SetFixedImage(NULL);
48  m_FixedImageSpacing.Fill( 1.0 );
49  m_FixedImageGradientCalculator = GradientCalculatorType::New();
50 
51  typename DefaultInterpolatorType::Pointer interp =
52  DefaultInterpolatorType::New();
53 
54  m_MovingImageInterpolator = static_cast<InterpolatorType*>(
55  interp.GetPointer() );
56 
57 
58 }
59 
60 
61 /*
62  * Standard "PrintSelf" method.
63  */
64 template <class TFixedImage, class TMovingImage, class TDeformationField>
65 void
67 ::PrintSelf(std::ostream& os, Indent indent) const
68 {
69 
70  Superclass::PrintSelf(os, indent);
71 /*
72  os << indent << "MovingImageIterpolator: ";
73  os << m_MovingImageInterpolator.GetPointer() << std::endl;
74  os << indent << "FixedImageGradientCalculator: ";
75  os << m_FixedImageGradientCalculator.GetPointer() << std::endl;
76  os << indent << "DenominatorThreshold: ";
77  os << m_DenominatorThreshold << std::endl;
78  os << indent << "IntensityDifferenceThreshold: ";
79  os << m_IntensityDifferenceThreshold << std::endl;
80 */
81 }
82 
83 
84 /*
85  * Set the function state values before each iteration
86  */
87 template <class TFixedImage, class TMovingImage, class TDeformationField>
88 void
91 {
92  if( !this->m_MovingImage || !this->m_FixedImage || !m_MovingImageInterpolator )
93  {
94  itkExceptionMacro( << "MovingImage, FixedImage and/or Interpolator not set" );
95  }
96 
97  // cache fixed image information
98  m_FixedImageSpacing = this->m_FixedImage->GetSpacing();
99 
100  // setup gradient calculator
101  m_FixedImageGradientCalculator->SetInputImage( this->m_FixedImage );
102 
103  // setup moving image interpolator
104  m_MovingImageInterpolator->SetInputImage( this->m_MovingImage );
105 
106  std::cout << " total metric " << m_MetricTotal << " field size " <<
107  this->GetDeformationField()->GetLargestPossibleRegion().GetSize()<< " image size " <<
108  this->m_FixedImage->GetLargestPossibleRegion().GetSize() << std::endl;
109  m_MetricTotal=0.0;
110 }
111 
112 
113 /*
114  * Compute update at a non boundary neighbourhood
115  */
116 template <class TFixedImage, class TMovingImage, class TDeformationField>
118 ::PixelType
120 ::ComputeUpdate(const NeighborhoodType &it, void * itkNotUsed(globalData),
121  const FloatOffsetType& itkNotUsed(offset))
122 {
123  const IndexType oindex = it.GetIndex();
124  const typename FixedImageType::SizeType hradius=it.GetRadius();
125  FixedImageType* img =const_cast<FixedImageType *>(this->m_FixedImage.GetPointer());
126  const typename FixedImageType::SizeType imagesize=img->GetLargestPossibleRegion().GetSize();
127 
129  hoodIt( hradius , img, img->GetRequestedRegion());
130  hoodIt.SetLocation(oindex);
131 
132  double sff=0.0;
133  double smm=0.0;
134  double sfm=0.0;
135 
136  double derivativeF[ImageDimension];
137  double derivativeM[ImageDimension];
138  for (unsigned int j=0; j<ImageDimension;j++)
139  {
140  derivativeF[j]=0;
141  derivativeM[j]=0;
142  }
143 
144  unsigned int hoodlen=hoodIt.Size();
145  for(unsigned int indct=0; indct<hoodlen-1; indct++)
146  {
147  const IndexType index=hoodIt.GetIndex(indct);
148  bool inimage=true;
149  for (unsigned int dd=0; dd<ImageDimension; dd++)
150  {
151  if ( index[dd] < 0 || index[dd] > static_cast<typename IndexType::IndexValueType>(imagesize[dd]-1) ) inimage=false;
152  }
153  if (inimage)
154  {
155  // Get fixed image related information
156  // Note: no need to check the index is within
157  // fixed image buffer. This is done by the external filter.
158  const double fixedValue = (double) this->m_FixedImage->GetPixel( index );
159  const CovariantVectorType fixedGradient = m_FixedImageGradientCalculator->EvaluateAtIndex( index );
160  double fixedGradientSquaredMagnitude = 0;
161  for(unsigned int j = 0; j < ImageDimension; j++ )
162  {
163  fixedGradientSquaredMagnitude += vnl_math_sqr( fixedGradient[j] ) * m_FixedImageSpacing[j];
164  }
165 
166  // Get moving image related information
167  typedef typename TDeformationField::PixelType DeformationPixelType;
168  const DeformationPixelType vec = this->GetDeformationField()->GetPixel(index);
169  PointType mappedPoint;
170  this->GetFixedImage()->TransformIndexToPhysicalPoint(index, mappedPoint);
171  for(unsigned int j = 0; j < ImageDimension; j++ )
172  {
173  mappedPoint[j] += vec[j];
174  }
175  double movingValue=0.0;
176  if( m_MovingImageInterpolator->IsInsideBuffer( mappedPoint ) )
177  {
178  movingValue = m_MovingImageInterpolator->Evaluate( mappedPoint );
179  }
180 
181  sff += fixedValue*fixedValue;
182  smm += movingValue*movingValue;
183  sfm += fixedValue*movingValue;
184 
185  for(unsigned int dim=0; dim<ImageDimension; dim++)
186  {
187  const double differential = fixedGradient[dim];
188  derivativeF[dim] += fixedValue * differential;
189  derivativeM[dim] += movingValue * differential;
190  }
191  }
192  }
193 
194  PixelType update;
195  update.Fill(0.0);
196  double updatenorm=0.0;
197  if( (sff*smm) != 0.0)
198  {
199  const double factor = 1.0 / vcl_sqrt(sff * smm );
200  for(unsigned int i=0; i<ImageDimension; i++)
201  {
202  update[i] = factor * ( derivativeF[i] - (sfm/smm)*derivativeM[i]);
203  updatenorm += (update[i]*update[i]);
204  }
205  updatenorm=vcl_sqrt(updatenorm);
206  m_MetricTotal += sfm*factor;
207  this->m_Energy += sfm*factor;
208  }
209  else
210  {
211  update.Fill(0.0);
212  updatenorm=1.0;
213  }
214 
215  if (this->GetNormalizeGradient() && updatenorm != 0.0 )
216  {
217  update /= (updatenorm);
218  }
219  return update * this->m_GradientStep;
220 }
221 
222 } // end namespace itk
223 
224 #endif

Generated at Sat May 18 2013 23:56:32 for Orfeo Toolbox with doxygen 1.8.3.1