18 #ifndef __itkGaussianDerivativeOperator_txx
19 #define __itkGaussianDerivativeOperator_txx
28 template<
class TPixel,
unsigned int VDimension,
class TAllocator>
29 typename GaussianDerivativeOperator<TPixel,VDimension, TAllocator>
37 m_Variance /= ( m_Spacing * m_Spacing );
40 double norm = m_NormalizeAcrossScale && m_Order ? vcl_pow( m_Variance, m_Order/2.0 ) : 1.0;
42 if( !this->GetUseDerivativeOperator() )
51 std::vector<int> polyCoeffs;
55 polyCoeffs.push_back(0);
56 polyCoeffs.push_back(-1);
58 else if( m_Order == 2 )
60 polyCoeffs.push_back(-1);
61 polyCoeffs.push_back(0);
62 polyCoeffs.push_back(1);
64 else if( m_Order == 3 )
66 polyCoeffs.push_back(0);
67 polyCoeffs.push_back(3);
68 polyCoeffs.push_back(0);
69 polyCoeffs.push_back(-1);
71 else if( m_Order > 3 )
73 polyCoeffs.push_back(0);
74 polyCoeffs.push_back(3);
75 polyCoeffs.push_back(0);
76 polyCoeffs.push_back(-1);
79 for( i = 4; i <= m_Order; ++i )
83 for( j = 1; j < polyCoeffs.size(); j += 2 )
85 polyCoeffs[j-1] += j*polyCoeffs[j];
86 if( j < polyCoeffs.size()-1 )
87 polyCoeffs[j+1] -= polyCoeffs[j];
90 polyCoeffs.push_back(1);
94 polyCoeffs[1] = -polyCoeffs[0];
96 for( j = 2; j < polyCoeffs.size(); j += 2 )
98 polyCoeffs[j-1] += j*polyCoeffs[j];
99 polyCoeffs[j+1] -= polyCoeffs[j];
102 polyCoeffs.push_back(-1);
112 typename CoefficientVector::iterator it;
114 const double et = vcl_exp(-m_Variance);
115 const double cap = 1.0 - m_MaximumError;
119 coeff.push_back(et * ModifiedBesselI0(m_Variance));
121 coeff.push_back(et * ModifiedBesselI1(m_Variance));
122 sum += coeff[1] * 2.0;
124 for (i = 2; sum < cap; i++ )
126 coeff.push_back(et* ModifiedBesselI(i, m_Variance));
127 sum += coeff[i] * 2.0;
128 if (coeff[i] <= 0.0)
break;
129 if (coeff.size() > m_MaximumKernelWidth )
131 itkWarningMacro(
"Kernel size has exceeded the specified maximum width of "
132 << m_MaximumKernelWidth <<
" and has been truncated to " <<
133 static_cast<unsigned long>( coeff.size() ) <<
" elements. You can raise "
134 "the maximum width using the SetMaximumKernelWidth method.");
140 for (it = coeff.begin(); it < coeff.end(); ++it)
146 j =
static_cast<int>( coeff.size() ) - 1;
147 coeff.insert(coeff.begin(), j, 0);
148 for (i=0, it = coeff.end()-1; i < j; --it, ++i)
159 for( i=-(
int)coeff.size()/2, it = coeff.begin(); i<=(int)coeff.size()/2; ++i )
164 for( j = 0, k = (
int)m_Order/2; j < (int)polyCoeffs.size(); j += 2, k-- )
166 sum += polyCoeffs[j] * vcl_pow( m_Variance,(
double)k ) * vcl_pow( i*m_Spacing,(
double)j );
171 for( j = 1, k = (
int)(m_Order-1)/2; j < (int)polyCoeffs.size(); j += 2, k-- )
173 sum += polyCoeffs[j] * vcl_pow( m_Variance,(
double)k ) * vcl_pow( i*m_Spacing,(
double)j );
176 sum *= norm / vcl_pow( m_Variance, static_cast<int>( m_Order ) );
188 gaussOp.
SetVariance( m_Variance / ( m_Spacing * m_Spacing ) );
202 for( i=0; i<(int)gaussOp.
Size(); ++i )
205 for( j=0; j<(int)derivOp.
Size(); ++j )
207 k = i + j - derivOp.
Size()/2;
208 if( k >= 0 && k < (
int)gaussOp.
Size() )
209 conv += gaussOp[k] * derivOp[derivOp.
Size()-1-j];
211 coeff.push_back( norm * conv );
218 template<
class TPixel,
unsigned int VDimension,
class TAllocator>
223 double d, accumulator;
226 if ((d=vcl_fabs(y)) < 3.75)
230 accumulator = 1.0 + m *(3.5156229+m*(3.0899424+m*(1.2067492
231 + m*(0.2659732+m*(0.360768e-1 +m*0.45813e-2)))));
236 accumulator =(vcl_exp(d)/vcl_sqrt(d))*(0.39894228+m*(0.1328592e-1
237 +m*(0.225319e-2+m*(-0.157565e-2+m*(0.916281e-2
238 +m*(-0.2057706e-1+m*(0.2635537e-1+m*(-0.1647633e-1
239 +m*0.392377e-2))))))));
245 template<
class TPixel,
unsigned int VDimension,
class TAllocator>
250 double d, accumulator;
253 if ((d=vcl_fabs(y)) < 3.75)
257 accumulator = d*(0.5+m*(0.87890594+m*(0.51498869+m*(0.15084934
258 +m*(0.2658733e-1+m*(0.301532e-2+m*0.32411e-3))))));
263 accumulator = 0.2282967e-1+m*(-0.2895312e-1+m*(0.1787654e-1
265 accumulator = 0.39894228+m*(-0.3988024e-1+m*(-0.362018e-2
266 +m*(0.163801e-2+m*(-0.1031555e-1+m*accumulator))));
268 accumulator *= (vcl_exp(d)/vcl_sqrt(d));
271 if (y<0.0)
return -accumulator;
272 else return accumulator;
276 template<
class TPixel,
unsigned int VDimension,
class TAllocator>
281 const double ACCURACY = 40.0;
283 double qim, qi, qip, toy;
288 throw ExceptionObject(__FILE__, __LINE__,
"Order of modified bessel is > 2.", ITK_LOCATION);
290 if (y==0.0)
return 0.0;
296 for (j=2*(n+(
int)vcl_sqrt(ACCURACY*n)); j>0; j--)
301 if (vcl_fabs(qi) > 1.0e10)
303 accumulator *= 1.0e-10;
307 if (j==n) accumulator=qip;
309 accumulator *= ModifiedBesselI0(y)/qi;
310 if (y<0.0 && (n&1))
return -accumulator;
311 else return accumulator;