/*========================================================================= This code provided as part of Brooks, R., Arbel, T. "Improving the OrientedImage class for use in the Registration Framework", Insight Journal, October, 2007 Author: Rupert Brooks Institution: Centre for Intelligent Machines, McGill University Sole differences from itkMeanSquaresImageToImageMetric are the derivative calculation. =========================================================================*/ #ifndef _itkMeanSquaresModImageToImageMetric_txx #define _itkMeanSquaresModImageToImageMetric_txx #include "itkMeanSquaresModImageToImageMetric.h" #include "itkImageRegionConstIteratorWithIndex.h" namespace itk { /* * Constructor */ template MeanSquaresModImageToImageMetric ::MeanSquaresModImageToImageMetric() { itkDebugMacro("Constructor"); } /* * Get the match Measure */ template typename MeanSquaresModImageToImageMetric::MeasureType MeanSquaresModImageToImageMetric ::GetValue( const TransformParametersType & parameters ) const { itkDebugMacro("GetValue( " << parameters << " ) "); FixedImageConstPointer fixedImage = this->m_FixedImage; if( !fixedImage ) { itkExceptionMacro( << "Fixed image has not been assigned" ); } typedef itk::ImageRegionConstIteratorWithIndex FixedIteratorType; FixedIteratorType ti( fixedImage, this->GetFixedImageRegion() ); typename FixedImageType::IndexType index; MeasureType measure = NumericTraits< MeasureType >::Zero; this->m_NumberOfPixelsCounted = 0; this->SetTransformParameters( parameters ); while(!ti.IsAtEnd()) { index = ti.GetIndex(); typename Superclass::InputPointType inputPoint; fixedImage->TransformIndexToPhysicalPoint( index, inputPoint ); if( this->m_FixedImageMask && !this->m_FixedImageMask->IsInside( inputPoint ) ) { ++ti; continue; } typename Superclass::OutputPointType transformedPoint = this->m_Transform->TransformPoint( inputPoint ); if( this->m_MovingImageMask && !this->m_MovingImageMask->IsInside( transformedPoint ) ) { ++ti; continue; } if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) { const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint ); const RealType fixedValue = ti.Get(); this->m_NumberOfPixelsCounted++; const RealType diff = movingValue - fixedValue; measure += diff * diff; } ++ti; } if( !this->m_NumberOfPixelsCounted ) { itkExceptionMacro(<<"All the points mapped to outside of the moving image"); } else { measure /= this->m_NumberOfPixelsCounted; } return measure; } /* * Get the Derivative Measure */ template < class TFixedImage, class TMovingImage> void MeanSquaresModImageToImageMetric ::GetDerivative( const TransformParametersType & parameters, DerivativeType & derivative ) const { itkDebugMacro("GetDerivative( " << parameters << " ) "); FixedImageConstPointer fixedImage = this->m_FixedImage; if( !fixedImage ) { itkExceptionMacro( << "Fixed image has not been assigned" ); } const unsigned int ImageDimension = FixedImageType::ImageDimension; typedef itk::ImageRegionConstIteratorWithIndex< FixedImageType> FixedIteratorType; typedef itk::ImageRegionConstIteratorWithIndex< ITK_TYPENAME Superclass::GradientImageType> GradientIteratorType; FixedIteratorType ti( fixedImage, this->GetFixedImageRegion() ); typename FixedImageType::IndexType index; this->m_NumberOfPixelsCounted = 0; this->SetTransformParameters( parameters ); const unsigned int ParametersDimension = this->GetNumberOfParameters(); derivative = DerivativeType( ParametersDimension ); derivative.Fill( NumericTraits::Zero ); ti.GoToBegin(); while(!ti.IsAtEnd()) { index = ti.GetIndex(); typename Superclass::InputPointType inputPoint; fixedImage->TransformIndexToPhysicalPoint( index, inputPoint ); if( this->m_FixedImageMask && !this->m_FixedImageMask->IsInside( inputPoint ) ) { ++ti; continue; } typename Superclass::OutputPointType transformedPoint = this->m_Transform->TransformPoint( inputPoint ); if( this->m_MovingImageMask && !this->m_MovingImageMask->IsInside( transformedPoint ) ) { ++ti; continue; } if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) { const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint ); const TransformJacobianType & jacobian = this->m_Transform->GetJacobian( inputPoint ); const RealType fixedValue = ti.Value(); this->m_NumberOfPixelsCounted++; const RealType diff = movingValue - fixedValue; GradientPixelType gradient; this->ComputeImageDerivatives(transformedPoint,gradient); for(unsigned int par=0; par::Zero; for(unsigned int dim=0; dimm_NumberOfPixelsCounted ) { itkExceptionMacro(<<"All the points mapped to outside of the moving image"); } else { for(unsigned int i=0; im_NumberOfPixelsCounted; } } } /* * Get both the match Measure and theDerivative Measure */ template void MeanSquaresModImageToImageMetric ::GetValueAndDerivative(const TransformParametersType & parameters, MeasureType & value, DerivativeType & derivative) const { itkDebugMacro("GetValueAndDerivative( " << parameters << " ) "); FixedImageConstPointer fixedImage = this->m_FixedImage; if( !fixedImage ) { itkExceptionMacro( << "Fixed image has not been assigned" ); } const unsigned int ImageDimension = FixedImageType::ImageDimension; typedef itk::ImageRegionConstIteratorWithIndex< FixedImageType> FixedIteratorType; typedef itk::ImageRegionConstIteratorWithIndex< ITK_TYPENAME Superclass::GradientImageType> GradientIteratorType; FixedIteratorType ti( fixedImage, this->GetFixedImageRegion() ); typename FixedImageType::IndexType index; MeasureType measure = NumericTraits< MeasureType >::Zero; this->m_NumberOfPixelsCounted = 0; this->SetTransformParameters( parameters ); const unsigned int ParametersDimension = this->GetNumberOfParameters(); derivative = DerivativeType( ParametersDimension ); derivative.Fill( NumericTraits::Zero ); ti.GoToBegin(); while(!ti.IsAtEnd()) { index = ti.GetIndex(); typename Superclass::InputPointType inputPoint; fixedImage->TransformIndexToPhysicalPoint( index, inputPoint ); if( this->m_FixedImageMask && !this->m_FixedImageMask->IsInside( inputPoint ) ) { ++ti; continue; } typename Superclass::OutputPointType transformedPoint = this->m_Transform->TransformPoint( inputPoint ); if( this->m_MovingImageMask && !this->m_MovingImageMask->IsInside( transformedPoint ) ) { ++ti; continue; } if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) { const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint ); const TransformJacobianType & jacobian = this->m_Transform->GetJacobian( inputPoint ); const RealType fixedValue = ti.Value(); this->m_NumberOfPixelsCounted++; const RealType diff = movingValue - fixedValue; measure += diff * diff; GradientPixelType gradient; this->ComputeImageDerivatives(transformedPoint,gradient); for(unsigned int par=0; par::Zero; for(unsigned int dim=0; dimm_NumberOfPixelsCounted ) { itkExceptionMacro(<<"All the points mapped to outside of the moving image"); } else { for(unsigned int i=0; im_NumberOfPixelsCounted; } measure /= this->m_NumberOfPixelsCounted; } value = measure; } } // end namespace itk #endif