1 /*===================================================================
3 The Medical Imaging Interaction Toolkit (MITK)
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 See LICENSE.txt or http://www.mitk.org for details.
15 ===================================================================*/
17 /*===================================================================
19 This file is based heavily on a corresponding ITK filter.
21 ===================================================================*/
22 #ifndef __itkGaussianInterpolateImageFunction_txx
23 #define __itkGaussianInterpolateImageFunction_txx
25 #include "itkGaussianInterpolateImageFunction.h"
27 #include "itkImageRegionConstIteratorWithIndex.h"
35 template <class TImageType, class TCoordRep>
36 GaussianInterpolateImageFunction<TImageType, TCoordRep>
37 ::GaussianInterpolateImageFunction()
40 this->m_Sigma.Fill( 1.0 );
44 * Standard "PrintSelf" method
46 template <class TImageType, class TCoordRep>
48 GaussianInterpolateImageFunction<TImageType, TCoordRep>
49 ::PrintSelf( std::ostream& os, Indent indent ) const
51 Superclass::PrintSelf( os, indent );
52 os << indent << "Alpha: " << this->m_Alpha << std::endl;
53 os << indent << "Sigma: " << this->m_Sigma << std::endl;
56 template <class TImageType, class TCoordRep>
58 GaussianInterpolateImageFunction<TImageType, TCoordRep>
59 ::ComputeBoundingBox()
61 if( !this->GetInputImage() )
66 for( unsigned int d = 0; d < ImageDimension; d++ )
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];
78 template <class TImageType, class TCoordRep>
79 typename GaussianInterpolateImageFunction<TImageType, TCoordRep>
81 GaussianInterpolateImageFunction<TImageType, TCoordRep>
82 ::EvaluateAtContinuousIndex( const ContinuousIndexType &cindex,
83 OutputType *grad ) const
85 vnl_vector<RealType> erfArray[ImageDimension];
86 vnl_vector<RealType> gerfArray[ImageDimension];
88 // Compute the ERF difference arrays
89 for( unsigned int d = 0; d < ImageDimension; d++ )
91 bool evaluateGradient = false;
94 evaluateGradient = true;
96 this->ComputeErrorFunctionArray( d, cindex[d], erfArray[d],
97 gerfArray[d], evaluateGradient );
100 RealType sum_me = 0.0;
101 RealType sum_m = 0.0;
109 // Loop over the voxels in the region identified
110 ImageRegion<ImageDimension> region;
111 for( unsigned int d = 0; d < ImageDimension; d++ )
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 );
123 ImageRegionConstIteratorWithIndex<InputImageType> It(
124 this->GetInputImage(), region );
125 for( It.GoToBegin(); !It.IsAtEnd(); ++It )
127 unsigned int j = It.GetIndex()[0];
128 RealType w = erfArray[0][j];
131 dw[0] = gerfArray[0][j];
132 for( unsigned int d = 1; d < ImageDimension; d++ )
134 dw[d] = erfArray[0][j];
137 for( unsigned int d = 1; d < ImageDimension; d++)
139 j = It.GetIndex()[d];
143 for( unsigned int q = 0; q < ImageDimension; q++ )
147 dw[q] *= gerfArray[d][j];
151 dw[q] *= erfArray[d][j];
156 RealType V = It.Get();
161 for( unsigned int q = 0; q < ImageDimension; q++ )
163 dsum_me[q] += V * dw[q];
168 RealType rc = sum_me / sum_m;
172 for( unsigned int q = 0; q < ImageDimension; q++ )
174 grad[q] = ( dsum_me[q] - rc * dsum_m[q] ) / sum_m;
175 grad[q] /= -vnl_math::sqrt2 * this->m_Sigma[q];
182 template <class TImageType, class TCoordRep>
184 GaussianInterpolateImageFunction<TImageType, TCoordRep>
185 ::ComputeErrorFunctionArray( unsigned int dimension, RealType cindex,
186 vnl_vector<RealType> &erfArray, vnl_vector<RealType> &gerfArray,
187 bool evaluateGradient ) const
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] +
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] ) ) );
200 erfArray.set_size( boundingBoxSize );
201 gerfArray.set_size( boundingBoxSize );
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 )
210 g_last = vnl_math::two_over_sqrtpi * vcl_exp( -vnl_math_sqr( t ) );
213 for( int i = begin; i < end; i++ )
215 t += this->m_ScalingFactor[dimension];
216 RealType e_now = vnl_erf( t );
217 erfArray[i] = e_now - e_last;
218 if( evaluateGradient )
220 RealType g_now = vnl_math::two_over_sqrtpi * vcl_exp( -vnl_math_sqr( t ) );
221 gerfArray[i] = g_now - g_last;