17 #ifndef __itkFastSymmetricForcesDemonsRegistrationFunction_txx
18 #define __itkFastSymmetricForcesDemonsRegistrationFunction_txx
22 #include "vnl/vnl_math.h"
29 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
36 for( j = 0; j < ImageDimension; j++ )
43 m_DenominatorThreshold = 1e-9;
44 m_IntensityDifferenceThreshold = 0.001;
45 this->SetMovingImage(
NULL);
46 this->SetFixedImage(
NULL);
48 m_FixedImageGradientCalculator = GradientCalculatorType::New();
51 DefaultInterpolatorType::New();
56 m_WarpedMovingImageGradientCalculator = MovingGradientCalculatorType::New();
57 m_MovingImageWarper = WarperType::New();
58 m_MovingImageWarper->SetInterpolator( m_MovingImageInterpolator );
60 m_Metric = NumericTraits<double>::max();
61 m_SumOfSquaredDifference = 0.0;
62 m_NumberOfPixelsProcessed = 0L;
63 m_RMSChange = NumericTraits<double>::max();
64 m_SumOfSquaredChange = 0.0;
72 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
77 Superclass::PrintSelf(os, indent);
79 os << indent <<
"MovingImageIterpolator: ";
80 os << m_MovingImageInterpolator.GetPointer() << std::endl;
81 os << indent <<
"FixedImageGradientCalculator: ";
82 os << m_FixedImageGradientCalculator.GetPointer() << std::endl;
83 os << indent <<
"DenominatorThreshold: ";
84 os << m_DenominatorThreshold << std::endl;
85 os << indent <<
"IntensityDifferenceThreshold: ";
86 os << m_IntensityDifferenceThreshold << std::endl;
88 os << indent <<
"Metric: ";
89 os << m_Metric << std::endl;
90 os << indent <<
"SumOfSquaredDifference: ";
91 os << m_SumOfSquaredDifference << std::endl;
92 os << indent <<
"NumberOfPixelsProcessed: ";
93 os << m_NumberOfPixelsProcessed << std::endl;
94 os << indent <<
"RMSChange: ";
95 os << m_RMSChange << std::endl;
96 os << indent <<
"SumOfSquaredChange: ";
97 os << m_SumOfSquaredChange << std::endl;
104 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
109 m_IntensityDifferenceThreshold = threshold;
115 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
120 return m_IntensityDifferenceThreshold;
126 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
131 if( !this->GetMovingImage() || !this->GetFixedImage() || !m_MovingImageInterpolator )
133 itkExceptionMacro( <<
"MovingImage, FixedImage and/or Interpolator not set" );
137 const PixelType fixedImageSpacing = this->GetFixedImage()->GetSpacing();
141 for(
unsigned int k = 0; k < ImageDimension; k++ )
143 m_Normalizer += fixedImageSpacing[k] * fixedImageSpacing[k];
145 m_Normalizer /=
static_cast<double>( ImageDimension );
149 m_FixedImageGradientCalculator->SetInputImage( this->GetFixedImage() );
151 m_MovingImageWarper->SetOutputOrigin( this->GetFixedImage()->GetOrigin() );
152 m_MovingImageWarper->SetOutputSpacing( this->GetFixedImage()->GetSpacing() );
153 m_MovingImageWarper->SetOutputDirection( this->GetFixedImage()->GetDirection() );
154 m_MovingImageWarper->SetInput( this->GetMovingImage() );
155 m_MovingImageWarper->SetDeformationField( this->GetDeformationField() );
156 m_MovingImageWarper->Update();
157 m_WarpedMovingImageGradientCalculator->SetInputImage( this->m_MovingImageWarper->GetOutput() );
160 m_MovingImageInterpolator->SetInputImage( this->GetMovingImage() );
163 m_SumOfSquaredDifference = 0.0;
164 m_NumberOfPixelsProcessed = 0L;
165 m_SumOfSquaredChange = 0.0;
173 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
181 const IndexType FirstIndex = this->GetFixedImage()->GetLargestPossibleRegion().GetIndex();
182 const IndexType LastIndex = this->GetFixedImage()->GetLargestPossibleRegion().GetIndex() +
183 this->GetFixedImage()->GetLargestPossibleRegion().GetSize();
190 const double fixedValue = (double) this->GetFixedImage()->GetPixel( index );
191 const CovariantVectorType fixedGradient = m_FixedImageGradientCalculator->EvaluateAtIndex( index );
195 const double movingValue = (double) m_MovingImageWarper->GetOutput()->GetPixel( index );
196 const CovariantVectorType movingGradient = m_WarpedMovingImageGradientCalculator->EvaluateAtIndex( index );
200 this->GetFixedImage()->TransformIndexToPhysicalPoint(index, mappedCenterPoint);
201 for(
unsigned int dim = 0; dim < ImageDimension; dim++ )
220 double fixedPlusMovingGradientSquaredMagnitude = 0;
221 for(
unsigned int dim = 0; dim < ImageDimension; dim++ )
223 fixedPlusMovingGradientSquaredMagnitude += vnl_math_sqr( fixedGradient[dim] + movingGradient[dim] );
226 const double speedValue = fixedValue - movingValue;
227 const double denominator = vnl_math_sqr( speedValue ) / m_Normalizer + fixedPlusMovingGradientSquaredMagnitude;
230 if ( vnl_math_abs(speedValue) < m_IntensityDifferenceThreshold || denominator < m_DenominatorThreshold )
236 for(
unsigned int j = 0; j < ImageDimension; j++ )
238 update[j] = 2 * speedValue * (movingGradient[j] + fixedGradient[j]) / denominator;
244 bool IsOutsideRegion = 0;
245 for(
unsigned int j = 0; j < ImageDimension; j++ )
250 newMappedCenterPoint[j] = mappedCenterPoint[j] + update[j];
251 if ( index[j] < (FirstIndex[j] + 2) || index[j] > (LastIndex[j] - 3) )
259 double newMovingValue=0;
264 if( !IsOutsideRegion )
266 if( m_MovingImageInterpolator->IsInsideBuffer( newMappedCenterPoint ) )
268 newMovingValue = m_MovingImageInterpolator->Evaluate( newMappedCenterPoint );
285 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
292 m_MetricCalculationLock.Lock();
296 if ( m_NumberOfPixelsProcessed )
298 m_Metric = m_SumOfSquaredDifference /
299 static_cast<double>( m_NumberOfPixelsProcessed );
300 m_RMSChange = vcl_sqrt( m_SumOfSquaredChange /
301 static_cast<double>( m_NumberOfPixelsProcessed ) );
303 m_MetricCalculationLock.Unlock();