KWStyle - itkGaussianOperator.txx
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkGaussianOperator.txx.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:36 $
7   Version:   $Revision: 1.4 $
8
9   Copyright (c) Insight Software Consortium. All rights reserved.
10   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11
12      This software is distributed WITHOUT ANY WARRANTY; without even 
13      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14      PURPOSE.  See the above copyright notices for more information.
15
16 =========================================================================*/
17 DEF #ifndef _itkGaussianOperator_txx
18 DEF #define _itkGaussianOperator_txx
19 #include "itkGaussianOperator.h"
20 #include "itkOutputWindow.h"
21 #include "itkMacro.h"
22 namespace itk
23 {
24
25 template<class TPixel,unsigned int VDimension, class TAllocator>
26 typename GaussianOperator<TPixel,VDimension, TAllocator>
27 ::CoefficientVector
28 GaussianOperator<TPixel,VDimension, TAllocator>
29 ::GenerateCoefficients()
30 {
31   CoefficientVector coeff;
32   double sum;
33   int i;
34   int j;
35   typename CoefficientVector::iterator it;
36
37   const double et           = ::exp(-m_Variance);
38   const double cap          = 1.0 - m_MaximumError;
39   
40   // Create the kernel coefficients as a std::vector
41   sum = 0.0;
42   coeff.push_back(et * ModifiedBesselI0(m_Variance));
43   sum += coeff[0];
44   coeff.push_back(et * ModifiedBesselI1(m_Variance));
45   sum += coeff[1]* 2.0;
46
47   for (i=2; sum < cap; i++)
48     {
49     coeff.push_back(et* ModifiedBesselI(i, m_Variance));
50     sum += coeff[i] *2.0;
51     if (coeff[i] <= 0.0) break;  // failsafe
52     if (coeff.size() > m_MaximumKernelWidth )
53       {
54 LEN       itkWarningMacro("Kernel size has exceeded the specified maximum width of " << m_MaximumKernelWidth << " and has been truncated to " << static_cast<unsigned long>( coeff.size() ) << " elements.  You can raise the maximum width using the SetMaximumKernelWidth method.");
55       break;
56       }  
57     }
58   // Normalize the coefficients so that their sum is one.
59   for (it = coeff.begin(); it < coeff.end(); ++it)
60     {
61     *it /= sum;
62     }
63
64   // Make symmetric
65   j = static_cast<int>( coeff.size() ) - 1;
66   coeff.insert(coeff.begin(), j, 0);
67   for (i=0, it = coeff.end()-1; i < j; --it, ++i)
68     {
69     coeff[i] = *it;
70     }
71   
72   return coeff;
73 }
74
75 template<class TPixel,unsigned int VDimension, class TAllocator>
76 double
77 GaussianOperator<TPixel,VDimension, TAllocator>
78 ::ModifiedBesselI0(double y)
79 {
80   double d, accumulator;
81   double m;
82
83   if ((d=fabs(y)) < 3.75)
84     {
85     m=y/3.75;
86     m*=m;
87     accumulator = 1.0 + m *(3.5156229+m*(3.0899424+m*(1.2067492
88 LEN                                                       + m*(0.2659732+m*(0.360768e-1 +m*0.45813e-2)))));
89     }
90   else
91     {
92     m=3.5/d;
93     accumulator =(::exp(d)/::sqrt(d))*(0.39894228+m*(0.1328592e-1
94 LEN                                                      +m*(0.225319e-2+m*(-0.157565e-2+m*(0.916281e-2
95 LEN                                                                                         +m*(-0.2057706e-1+m*(0.2635537e-1+m*(-0.1647633e-1   
96 LEN                                                                                                                              +m*0.392377e-2))))))));
97     }
98   return accumulator;
99 }
100  
101
102 template<class TPixel,unsigned int VDimension, class TAllocator>
103 double
104 GaussianOperator<TPixel,VDimension, TAllocator>
105 ::ModifiedBesselI1(double y)
106 {
107   double d, accumulator;
108   double m;
109
110   if ((d=fabs(y)) < 3.75)
111     {
112     m=y/3.75;
113     m*=m;
114     accumulator = d*(0.5+m*(0.87890594+m*(0.51498869+m*(0.15084934
115 LEN                                                         +m*(0.2658733e-1+m*(0.301532e-2+m*0.32411e-3))))));
116     }
117   else
118     {
119     m=3.75/d;
120     accumulator = 0.2282967e-1+m*(-0.2895312e-1+m*(0.1787654e-1
121                                                    -m*0.420059e-2));
122     accumulator = 0.39894228+m*(-0.3988024e-1+m*(-0.362018e-2
123 LEN                                                  +m*(0.163801e-2+m*(-0.1031555e-1+m*accumulator))));
124
125     accumulator *= (::exp(d)/::sqrt(d));
126     }
127
128   if (y<0.0) return -accumulator;
129   else return accumulator;
130   
131 }
132
133 template<class TPixel,unsigned int VDimension, class TAllocator>
134 double
135 GaussianOperator<TPixel,VDimension, TAllocator>
136 ::ModifiedBesselI(int n, double y)
137 {
138   const double ACCURACY = 40.0;
139   int j;
140   double qim, qi, qip, toy;
141   double accumulator;
142
143   if (n<2)
144     {
145 LEN     throw ExceptionObject(__FILE__, __LINE__, "Order of modified bessel is > 2.", ITK_LOCATION);  // placeholder
146     }
147   if (y==0.0) return 0.0;
148   else
149     {
150     toy=2.0/fabs(y);
151     qip=accumulator=0.0;
152     qi=1.0;
153 SEM     for (j=2*(n+(int)::sqrt(ACCURACY*n)); j>0 ; j--)
154       {
155       qim=qip+j*toy*qi;
156       qip=qi;
157       qi=qim;
158       if (fabs(qi) > 1.0e10)
159         {
160         accumulator*=1.0e-10;
161         qi *=1.0e-10;
162         qip*=1.0e-10;
163         }
164       if (j==n) accumulator=qip;
165       }
166     accumulator *= ModifiedBesselI0(y)/qi;
167     if (y<0.0 && (n&1)) return -accumulator;
168     else return accumulator;
169     }
170 }
171
172 }// end namespace itk
173
174 #endif
175

Generated by KWStyle 1.0b on Tuesday January,17 at 02:14:10PM
© Kitware Inc.