Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkBSplineKernelFunction2_h
00018 #define __itkBSplineKernelFunction2_h
00019
00020 #include "itkKernelFunction.h"
00021 #include "vnl/vnl_math.h"
00022
00023 namespace itk
00024 {
00025
00041 template <unsigned int VSplineOrder = 3>
00042 class ITK_EXPORT BSplineKernelFunction2 : public KernelFunction
00043 {
00044 public:
00046 typedef BSplineKernelFunction2 Self;
00047 typedef KernelFunction Superclass;
00048 typedef SmartPointer<Self> Pointer;
00049
00051 itkNewMacro( Self );
00052
00054 itkTypeMacro( BSplineKernelFunction2, KernelFunction );
00055
00057 itkStaticConstMacro( SplineOrder, unsigned int, VSplineOrder );
00058
00060 typedef FixedArray< double,
00061 itkGetStaticConstMacro( SplineOrder ) + 1 > WeightArrayType;
00062
00064 inline double Evaluate( const double & u ) const
00065 {
00066 return this->Evaluate( Dispatch<VSplineOrder>(), u );
00067 }
00068
00072 inline void Evaluate( const double & u, WeightArrayType & weights ) const
00073 {
00074 this->Evaluate( Dispatch<VSplineOrder>(), u, weights );
00075 }
00076
00077 protected:
00078 BSplineKernelFunction2(){};
00079 ~BSplineKernelFunction2(){};
00080
00081 void PrintSelf( std::ostream & os, Indent indent ) const
00082 {
00083 Superclass::PrintSelf( os, indent );
00084 os << indent << "Spline Order: " << SplineOrder << std::endl;
00085 }
00086
00087 private:
00088 BSplineKernelFunction2(const Self&);
00089 void operator=(const Self&);
00090
00092 struct DispatchBase {};
00093 template<unsigned int>
00094 struct Dispatch : DispatchBase {};
00095
00101 inline double Evaluate( const Dispatch<0> &, const double & u ) const
00102 {
00103 double absValue = vnl_math_abs( u );
00104
00105 if ( absValue < 0.5 ) return 1.0;
00106 else if ( absValue == 0.5 ) return 0.5;
00107 else return 0.0;
00108 }
00109
00111 inline double Evaluate( const Dispatch<1> &, const double & u ) const
00112 {
00113 double absValue = vnl_math_abs( u );
00114
00115 if ( absValue < 1.0 ) return 1.0 - absValue;
00116 else return 0.0;
00117 }
00118
00120 inline double Evaluate( const Dispatch<2> &, const double & u ) const
00121 {
00122 double absValue = vnl_math_abs( u );
00123
00124 if ( absValue < 0.5 )
00125 {
00126 return 0.75 - vnl_math_sqr( absValue );
00127 }
00128 else if ( absValue < 1.5 )
00129 {
00130 return ( 9.0 - 12.0 * absValue + 4.0 * vnl_math_sqr( absValue ) ) / 8.0;
00131 }
00132 else return 0.0;
00133 }
00134
00136 inline double Evaluate( const Dispatch<3> &, const double & u ) const
00137 {
00138 double absValue = vnl_math_abs( u );
00139 double sqrValue = vnl_math_sqr( u );
00140
00141 if ( absValue < 1.0 )
00142 {
00143 return ( 4.0 - 6.0 * sqrValue + 3.0 * sqrValue * absValue ) / 6.0;
00144 }
00145 else if ( absValue < 2.0 )
00146 {
00147 return ( 8.0 - 12.0 * absValue + 6.0 * sqrValue - sqrValue * absValue ) / 6.0;
00148 }
00149 else return 0.0;
00150 }
00151
00153 inline double Evaluate( const DispatchBase &, const double & ) const
00154 {
00155 itkExceptionMacro( << "Evaluate not implemented for spline order "
00156 << SplineOrder );
00157 return 0.0;
00158 }
00159
00165 inline void Evaluate( const Dispatch<0> &, const double & u,
00166 WeightArrayType & weights ) const
00167 {
00168 if ( u < 0.5 ) weights[ 0 ] = 1.0;
00169 else weights[ 0 ] = 0.5;
00170 }
00171
00173 inline void Evaluate( const Dispatch<1> &, const double & u,
00174 WeightArrayType & weights ) const
00175 {
00176 weights[ 0 ] = 1.0 - u;
00177 weights[ 1 ] = u - 1.0;
00178 }
00179
00181 inline void Evaluate( const Dispatch<2> &, const double & u,
00182 WeightArrayType & weights ) const
00183 {
00184 const double uu = vnl_math_sqr( u );
00185
00186 weights[ 0 ] = ( 9.0 - 12.0 * u + 4.0 * uu ) / 8.0;
00187 weights[ 1 ] = -0.25 + 2.0 * u - uu;
00188 weights[ 2 ] = ( 1.0 - 4.0 * u + 4.0 * uu ) / 8.0;
00189 }
00190
00192 inline void Evaluate ( const Dispatch<3> &, const double & u,
00193 WeightArrayType & weights ) const
00194 {
00195 const double uu = vnl_math_sqr( u );
00196 const double uuu = uu * u;
00197
00198 weights[ 0 ] = ( 8.0 - 12 * u + 6.0 * uu - uuu ) / 6.0;
00199 weights[ 1 ] = ( -5.0 + 21.0 * u - 15.0 * uu + 3.0 * uuu ) / 6.0;
00200 weights[ 2 ] = ( 4.0 - 12.0 * u + 12.0 * uu - 3.0 * uuu ) / 6.0;
00201 weights[ 3 ] = ( -1.0 + 3.0 * u - 3.0 * uu + uuu ) / 6.0;
00202 }
00203
00205 inline double Evaluate( const DispatchBase &, const double &,
00206 WeightArrayType & ) const
00207 {
00208 itkExceptionMacro( << "Evaluate not implemented for spline order "
00209 << SplineOrder );
00210 return 0.0;
00211 }
00212
00213 };
00214
00215
00216 }
00217
00218 #endif