Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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