Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
itkGaussianInterpolateImageFunction.txx
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 /*===================================================================
18 
19 This file is based heavily on a corresponding ITK filter.
20 
21 ===================================================================*/
22 #ifndef __itkGaussianInterpolateImageFunction_txx
23 #define __itkGaussianInterpolateImageFunction_txx
24 
25 #include "itkGaussianInterpolateImageFunction.h"
26 
27 #include "itkImageRegionConstIteratorWithIndex.h"
28 
29 namespace itk
30 {
31 
32 /**
33  * Constructor
34  */
35 template <class TImageType, class TCoordRep>
36 GaussianInterpolateImageFunction<TImageType, TCoordRep>
37 ::GaussianInterpolateImageFunction()
38 {
39  this->m_Alpha = 1.0;
40  this->m_Sigma.Fill( 1.0 );
41 }
42 
43 /**
44  * Standard "PrintSelf" method
45  */
46 template <class TImageType, class TCoordRep>
47 void
48 GaussianInterpolateImageFunction<TImageType, TCoordRep>
49 ::PrintSelf( std::ostream& os, Indent indent ) const
50 {
51  Superclass::PrintSelf( os, indent );
52  os << indent << "Alpha: " << this->m_Alpha << std::endl;
53  os << indent << "Sigma: " << this->m_Sigma << std::endl;
54 }
55 
56 template <class TImageType, class TCoordRep>
57 void
58 GaussianInterpolateImageFunction<TImageType, TCoordRep>
59 ::ComputeBoundingBox()
60 {
61  if( !this->GetInputImage() )
62  {
63  return;
64  }
65 
66  for( unsigned int d = 0; d < ImageDimension; d++ )
67  {
68  this->m_BoundingBoxStart[d] = -0.5;
69  this->m_BoundingBoxEnd[d] = static_cast<RealType>(
70  this->GetInputImage()->GetBufferedRegion().GetSize()[d] ) - 0.5;
71  this->m_ScalingFactor[d] = 1.0 / ( vnl_math::sqrt2 * this->m_Sigma[d] /
72  this->GetInputImage()->GetSpacing()[d] );
73  this->m_CutoffDistance[d] = this->m_Sigma[d] * this->m_Alpha /
74  this->GetInputImage()->GetSpacing()[d];
75  }
76 }
77 
78 template <class TImageType, class TCoordRep>
79 typename GaussianInterpolateImageFunction<TImageType, TCoordRep>
80 ::OutputType
81 GaussianInterpolateImageFunction<TImageType, TCoordRep>
82 ::EvaluateAtContinuousIndex( const ContinuousIndexType &cindex,
83  OutputType *grad ) const
84 {
85  vnl_vector<RealType> erfArray[ImageDimension];
86  vnl_vector<RealType> gerfArray[ImageDimension];
87 
88  // Compute the ERF difference arrays
89  for( unsigned int d = 0; d < ImageDimension; d++ )
90  {
91  bool evaluateGradient = false;
92  if( grad )
93  {
94  evaluateGradient = true;
95  }
96  this->ComputeErrorFunctionArray( d, cindex[d], erfArray[d],
97  gerfArray[d], evaluateGradient );
98  }
99 
100  RealType sum_me = 0.0;
101  RealType sum_m = 0.0;
102  ArrayType dsum_me;
103  ArrayType dsum_m;
104  ArrayType dw;
105 
106  dsum_m.Fill( 0.0 );
107  dsum_me.Fill( 0.0 );
108 
109  // Loop over the voxels in the region identified
110  ImageRegion<ImageDimension> region;
111  for( unsigned int d = 0; d < ImageDimension; d++ )
112  {
113  int boundingBoxSize = static_cast<int>(
114  this->m_BoundingBoxEnd[d] - this->m_BoundingBoxStart[d] + 0.5 );
115  int begin = vnl_math_max( 0, static_cast<int>( vcl_floor( cindex[d] -
116  this->m_BoundingBoxStart[d] - this->m_CutoffDistance[d] ) ) );
117  int end = vnl_math_min( boundingBoxSize, static_cast<int>( vcl_ceil(
118  cindex[d] - this->m_BoundingBoxStart[d] + this->m_CutoffDistance[d] ) ) );
119  region.SetIndex( d, begin );
120  region.SetSize( d, end - begin );
121  }
122 
123  ImageRegionConstIteratorWithIndex<InputImageType> It(
124  this->GetInputImage(), region );
125  for( It.GoToBegin(); !It.IsAtEnd(); ++It )
126  {
127  unsigned int j = It.GetIndex()[0];
128  RealType w = erfArray[0][j];
129  if( grad )
130  {
131  dw[0] = gerfArray[0][j];
132  for( unsigned int d = 1; d < ImageDimension; d++ )
133  {
134  dw[d] = erfArray[0][j];
135  }
136  }
137  for( unsigned int d = 1; d < ImageDimension; d++)
138  {
139  j = It.GetIndex()[d];
140  w *= erfArray[d][j];
141  if( grad )
142  {
143  for( unsigned int q = 0; q < ImageDimension; q++ )
144  {
145  if( d == q )
146  {
147  dw[q] *= gerfArray[d][j];
148  }
149  else
150  {
151  dw[q] *= erfArray[d][j];
152  }
153  }
154  }
155  }
156  RealType V = It.Get();
157  sum_me += V * w;
158  sum_m += w;
159  if( grad )
160  {
161  for( unsigned int q = 0; q < ImageDimension; q++ )
162  {
163  dsum_me[q] += V * dw[q];
164  dsum_m[q] += dw[q];
165  }
166  }
167  }
168  RealType rc = sum_me / sum_m;
169 
170  if( grad )
171  {
172  for( unsigned int q = 0; q < ImageDimension; q++ )
173  {
174  grad[q] = ( dsum_me[q] - rc * dsum_m[q] ) / sum_m;
175  grad[q] /= -vnl_math::sqrt2 * this->m_Sigma[q];
176  }
177  }
178 
179  return rc;
180 }
181 
182 template <class TImageType, class TCoordRep>
183 void
184 GaussianInterpolateImageFunction<TImageType, TCoordRep>
185 ::ComputeErrorFunctionArray( unsigned int dimension, RealType cindex,
186  vnl_vector<RealType> &erfArray, vnl_vector<RealType> &gerfArray,
187  bool evaluateGradient ) const
188 {
189  // Determine the range of voxels along the line where to evaluate erf
190  int boundingBoxSize = static_cast<int>(
191  this->m_BoundingBoxEnd[dimension] - this->m_BoundingBoxStart[dimension] +
192  0.5 );
193  int begin = vnl_math_max( 0, static_cast<int>( vcl_floor( cindex -
194  this->m_BoundingBoxStart[dimension] -
195  this->m_CutoffDistance[dimension] ) ) );
196  int end = vnl_math_min( boundingBoxSize, static_cast<int>( vcl_ceil( cindex -
197  this->m_BoundingBoxStart[dimension] +
198  this->m_CutoffDistance[dimension] ) ) );
199 
200  erfArray.set_size( boundingBoxSize );
201  gerfArray.set_size( boundingBoxSize );
202 
203  // Start at the first voxel
204  RealType t = ( this->m_BoundingBoxStart[dimension] - cindex +
205  static_cast<RealType>( begin ) ) * this->m_ScalingFactor[dimension];
206  RealType e_last = vnl_erf( t );
207  RealType g_last = 0.0;
208  if( evaluateGradient )
209  {
210  g_last = vnl_math::two_over_sqrtpi * vcl_exp( -vnl_math_sqr( t ) );
211  }
212 
213  for( int i = begin; i < end; i++ )
214  {
215  t += this->m_ScalingFactor[dimension];
216  RealType e_now = vnl_erf( t );
217  erfArray[i] = e_now - e_last;
218  if( evaluateGradient )
219  {
220  RealType g_now = vnl_math::two_over_sqrtpi * vcl_exp( -vnl_math_sqr( t ) );
221  gerfArray[i] = g_now - g_last;
222  g_last = g_now;
223  }
224  e_last = e_now;
225  }
226 }
227 
228 } // namespace itk
229 
230 #endif