ANIMA  4.0
animaFastCorrelationImageToImageMetric.hxx
Go to the documentation of this file.
1 #pragma once
3 
4 #include <itkImageRegionConstIteratorWithIndex.h>
5 
6 namespace anima
7 {
8 
9 template <class TFixedImage, class TMovingImage>
12 {
13  m_SumFixed = 0;
14  m_VarFixed = 0;
15  m_DefaultBackgroundValue = 0.0;
16  m_SquaredCorrelation = true;
17  m_ScaleIntensities = false;
18  m_FixedImagePoints.clear();
19  m_FixedImageValues.clear();
20 }
21 
22 template <class TFixedImage, class TMovingImage>
25 ::GetValue( const TransformParametersType & parameters ) const
26 {
27  FixedImageConstPointer fixedImage = this->m_FixedImage;
28 
29  if (!fixedImage)
30  itkExceptionMacro( << "Fixed image has not been assigned" );
31 
32  if ( this->m_NumberOfPixelsCounted == 0 )
33  return 0;
34 
35  MeasureType measure;
36  this->SetTransformParameters( parameters );
37 
38  typedef typename itk::NumericTraits< MeasureType >::AccumulateType AccumulateType;
39 
40  AccumulateType smm = itk::NumericTraits< AccumulateType >::Zero;
41  AccumulateType sfm = itk::NumericTraits< AccumulateType >::Zero;
42  AccumulateType sm = itk::NumericTraits< AccumulateType >::Zero;
43 
44  OutputPointType transformedPoint;
45  ContinuousIndexType transformedIndex;
46  RealType movingValue;
47 
48  for (unsigned int i = 0;i < this->m_NumberOfPixelsCounted;++i)
49  {
50  transformedPoint = this->m_Transform->TransformPoint(m_FixedImagePoints[i]);
51  this->m_Interpolator->GetInputImage()->TransformPhysicalPointToContinuousIndex(transformedPoint,transformedIndex);
52 
53  movingValue = m_DefaultBackgroundValue;
54  if (this->m_Interpolator->IsInsideBuffer(transformedIndex))
55  movingValue = this->m_Interpolator->EvaluateAtContinuousIndex(transformedIndex);
56 
57  if (movingValue != 0.0)
58  {
59  if (m_ScaleIntensities)
60  {
61  typedef itk::MatrixOffsetTransformBase <typename TransformType::ScalarType,
62  TFixedImage::ImageDimension, TFixedImage::ImageDimension> BaseTransformType;
63  BaseTransformType *currentTrsf = dynamic_cast<BaseTransformType *> (this->m_Transform.GetPointer());
64 
65  double factor = vnl_determinant(currentTrsf->GetMatrix().GetVnlMatrix());
66  movingValue *= factor;
67  }
68 
69  smm += movingValue * movingValue;
70  sfm += m_FixedImageValues[i] * movingValue;
71  sm += movingValue;
72  }
73  }
74 
75  RealType movingVariance = smm - sm * sm / this->m_NumberOfPixelsCounted;
76  if (movingVariance <= 0)
77  return 0;
78 
79  RealType covData = sfm - m_SumFixed * sm / this->m_NumberOfPixelsCounted;
80  RealType multVars = m_VarFixed * movingVariance;
81 
82  if (this->m_NumberOfPixelsCounted > 1 && multVars > 0)
83  {
84  if (m_SquaredCorrelation)
85  measure = covData * covData / multVars;
86  else
87  measure = std::max(0.0,covData / sqrt(multVars));
88  }
89  else
90  {
91  measure = itk::NumericTraits< MeasureType >::Zero;
92  }
93 
94  return measure;
95 }
96 
97 template < class TFixedImage, class TMovingImage>
98 void
101 {
102  FixedImageConstPointer fixedImage = this->m_FixedImage;
103 
104  if( !fixedImage )
105  {
106  itkExceptionMacro( << "Fixed image has not been assigned" );
107  }
108 
109  m_SumFixed = 0;
110  m_VarFixed = 0;
111  RealType sumSquared = 0;
112 
113  typedef itk::ImageRegionConstIteratorWithIndex<FixedImageType> FixedIteratorType;
114 
115  FixedIteratorType ti( fixedImage, this->GetFixedImageRegion() );
116  typename FixedImageType::IndexType index;
117 
118  this->m_NumberOfPixelsCounted = this->GetFixedImageRegion().GetNumberOfPixels();
119 
120  m_FixedImagePoints.resize(this->m_NumberOfPixelsCounted);
121  m_FixedImageValues.resize(this->m_NumberOfPixelsCounted);
122 
123  InputPointType inputPoint;
124 
125  unsigned int pos = 0;
126  RealType fixedValue;
127  while(!ti.IsAtEnd())
128  {
129  index = ti.GetIndex();
130  fixedImage->TransformIndexToPhysicalPoint( index, inputPoint );
131 
132  m_FixedImagePoints[pos] = inputPoint;
133  fixedValue = ti.Value();
134  m_FixedImageValues[pos] = fixedValue;
135 
136  sumSquared += fixedValue * fixedValue;
137  m_SumFixed += fixedValue;
138 
139  ++ti;
140  ++pos;
141  }
142 
143  m_VarFixed = sumSquared - m_SumFixed * m_SumFixed / this->m_NumberOfPixelsCounted;
144 }
145 
146 template < class TFixedImage, class TMovingImage>
147 void
150  DerivativeType & derivative ) const
151 {
152  itkExceptionMacro("Derivative not implemented yet...");
153 }
154 
155 template <class TFixedImage, class TMovingImage>
156 void
159  MeasureType & value, DerivativeType & derivative) const
160 {
161  itkExceptionMacro("Derivative not implemented yet...");
162 }
163 
164 template < class TFixedImage, class TMovingImage>
165 void
167 ::PrintSelf(std::ostream& os, itk::Indent indent) const
168 {
169  Superclass::PrintSelf(os, indent);
170  os << indent << m_SumFixed << " " << m_VarFixed << std::endl;
171 }
172 
173 } // end of namespace anima
void GetValueAndDerivative(const TransformParametersType &parameters, MeasureType &Value, DerivativeType &Derivative) const ITK_OVERRIDE
void GetDerivative(const TransformParametersType &parameters, DerivativeType &Derivative) const ITK_OVERRIDE
itk::ContinuousIndex< double, TFixedImage::ImageDimension > ContinuousIndexType
void PrintSelf(std::ostream &os, itk::Indent indent) const ITK_OVERRIDE
MeasureType GetValue(const TransformParametersType &parameters) const ITK_OVERRIDE