17 #ifndef __itkLevelSetMotionRegistrationFunction_txx
18 #define __itkLevelSetMotionRegistrationFunction_txx
22 #include "vnl/vnl_math.h"
29 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
36 for( j = 0; j < ImageDimension; j++ )
43 m_GradientMagnitudeThreshold = 1e-9;
44 m_IntensityDifferenceThreshold = 0.001;
45 m_GradientSmoothingStandardDeviations = 1.0;
46 this->SetMovingImage(
NULL);
47 this->SetFixedImage(
NULL);
50 DefaultInterpolatorType::New();
55 m_Metric = NumericTraits<double>::max();
56 m_SumOfSquaredDifference = 0.0;
57 m_NumberOfPixelsProcessed = 0L;
58 m_RMSChange = NumericTraits<double>::max();
59 m_SumOfSquaredChange = 0.0;
60 m_UseImageSpacing =
true;
62 m_MovingImageSmoothingFilter = MovingImageSmoothingFilterType::New();
63 m_MovingImageSmoothingFilter
64 ->SetSigma( m_GradientSmoothingStandardDeviations );
65 m_MovingImageSmoothingFilter->SetNormalizeAcrossScale(
false);
67 m_SmoothMovingImageInterpolator
69 DefaultInterpolatorType::New().GetPointer());
76 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
81 Superclass::PrintSelf(os, indent);
83 os << indent <<
"MovingImageIterpolator: ";
84 os << m_MovingImageInterpolator.GetPointer() << std::endl;
85 os << indent <<
"IntensityDifferenceThreshold: ";
86 os << m_IntensityDifferenceThreshold << std::endl;
87 os << indent <<
"GradientMagnitudeThreshold: ";
88 os << m_GradientMagnitudeThreshold << std::endl;
89 os << indent <<
"Alpha: ";
90 os << m_Alpha << std::endl;
92 os << indent <<
"Metric: ";
93 os << m_Metric << std::endl;
94 os << indent <<
"SumOfSquaredDifference: ";
95 os << m_SumOfSquaredDifference << std::endl;
96 os << indent <<
"NumberOfPixelsProcessed: ";
97 os << m_NumberOfPixelsProcessed << std::endl;
98 os << indent <<
"RMSChange: ";
99 os << m_RMSChange << std::endl;
100 os << indent <<
"SumOfSquaredChange: ";
101 os << m_SumOfSquaredChange << std::endl;
109 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
120 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
131 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
136 m_IntensityDifferenceThreshold = threshold;
142 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
147 return m_IntensityDifferenceThreshold;
154 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
159 m_GradientMagnitudeThreshold = threshold;
165 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
170 return m_GradientMagnitudeThreshold;
177 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
182 m_GradientSmoothingStandardDeviations = sigma;
188 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
193 return m_GradientSmoothingStandardDeviations;
200 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
205 return this->m_UseImageSpacing;
212 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
217 this->m_UseImageSpacing = useImageSpacing;
223 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
228 if( !this->GetMovingImage() || !this->GetFixedImage() || !m_MovingImageInterpolator )
230 itkExceptionMacro( <<
"MovingImage, FixedImage and/or Interpolator not set" );
237 m_MovingImageSmoothingFilter->SetInput( this->GetMovingImage() );
238 m_MovingImageSmoothingFilter
239 ->SetSigma( m_GradientSmoothingStandardDeviations );
240 m_MovingImageSmoothingFilter->Update();
242 m_SmoothMovingImageInterpolator
243 ->SetInputImage( m_MovingImageSmoothingFilter->GetOutput() );
246 m_MovingImageInterpolator->SetInputImage( this->GetMovingImage() );
249 m_SumOfSquaredDifference = 0.0;
250 m_NumberOfPixelsProcessed = 0L;
251 m_SumOfSquaredChange = 0.0;
258 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
270 const double fixedValue = (double) this->GetFixedImage()->GetPixel( index );
274 this->GetFixedImage()->TransformIndexToPhysicalPoint(index, mappedPoint);
275 for(
unsigned int j = 0; j < ImageDimension; j++ )
281 if( m_MovingImageInterpolator->IsInsideBuffer( mappedPoint ) )
283 movingValue = m_MovingImageInterpolator->Evaluate( mappedPoint );
303 if( !this->m_UseImageSpacing )
305 mSpacing.Fill( 1.0 );
309 const double centralValue = m_SmoothMovingImageInterpolator->Evaluate( mPoint );
310 double forwardDifferences[ImageDimension];
311 double backwardDifferences[ImageDimension];
312 for (
unsigned int j=0; j < ImageDimension; j++)
314 mPoint[j] += mSpacing[j];
315 if( m_SmoothMovingImageInterpolator->IsInsideBuffer( mPoint ) )
317 forwardDifferences[j] = m_SmoothMovingImageInterpolator->Evaluate(mPoint)
319 forwardDifferences[j] /= mSpacing[j];
323 forwardDifferences[j] = 0.0;
326 mPoint[j] -= (2.0 * mSpacing[j]);
327 if( m_SmoothMovingImageInterpolator->IsInsideBuffer( mPoint ) )
329 backwardDifferences[j] = centralValue
330 - m_SmoothMovingImageInterpolator->Evaluate( mPoint );
331 backwardDifferences[j] /= mSpacing[j];
335 backwardDifferences[j] = 0.0;
339 mPoint[j] += mSpacing[j];
350 double gradientMagnitude = 0.0;
351 for(
unsigned int j = 0; j < ImageDimension; j++ )
353 if (forwardDifferences[j] * backwardDifferences[j] > 0.0)
355 const double bvalue = vnl_math_abs(backwardDifferences[j]);
356 double gvalue = vnl_math_abs(forwardDifferences[j]);
361 gradient[j] = gvalue * vnl_math_sgn(forwardDifferences[j]);
367 gradientMagnitude += vnl_math_sqr( gradient[j] );
369 gradientMagnitude = vcl_sqrt( gradientMagnitude );
374 const double speedValue = fixedValue - movingValue;
383 if ( vnl_math_abs(speedValue) < m_IntensityDifferenceThreshold
384 || gradientMagnitude < m_GradientMagnitudeThreshold )
391 for(
unsigned int j = 0; j < ImageDimension; j++ )
393 update[j] = speedValue * gradient[j] / (gradientMagnitude + m_Alpha);
402 L1norm += (vnl_math_abs(update[j]) / mSpacing[j]);
408 if (globalData && (L1norm > globalData->
m_MaxL1Norm))
418 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
444 template <
class TFixedImage,
class TMovingImage,
class TDeformationField>
451 m_MetricCalculationLock.Lock();
455 if ( m_NumberOfPixelsProcessed )
457 m_Metric = m_SumOfSquaredDifference /
458 static_cast<double>( m_NumberOfPixelsProcessed );
459 m_RMSChange = vcl_sqrt( m_SumOfSquaredChange /
460 static_cast<double>( m_NumberOfPixelsProcessed ) );
462 m_MetricCalculationLock.Unlock();