00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkBSplineKernelFunction_h
00018 #define __itkBSplineKernelFunction_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 BSplineKernelFunction : public KernelFunction
00043 {
00044 public:
00046 typedef BSplineKernelFunction Self;
00047 typedef KernelFunction Superclass;
00048 typedef SmartPointer<Self> Pointer;
00049
00051 itkNewMacro(Self);
00052
00054 itkTypeMacro(BSplineKernelFunction, KernelFunction);
00055
00057 itkStaticConstMacro(SplineOrder, unsigned int, VSplineOrder);
00058
00060 inline double Evaluate( const double & u ) const
00061 {
00062 return this->Evaluate( Dispatch<VSplineOrder>(), u );
00063 }
00064
00065 protected:
00066 BSplineKernelFunction(){};
00067 ~BSplineKernelFunction(){};
00068 void PrintSelf(std::ostream& os, Indent indent) const
00069 {
00070 Superclass::PrintSelf( os, indent );
00071 os << indent << "Spline Order: " << SplineOrder << std::endl;
00072 }
00073
00074 private:
00075 BSplineKernelFunction(const Self&);
00076 void operator=(const Self&);
00077
00079 struct DispatchBase {};
00080 template<unsigned int>
00081 struct Dispatch : DispatchBase {};
00082
00084 inline double Evaluate (const Dispatch<0>&, const double & u) const
00085 {
00086
00087 double absValue = vnl_math_abs( u );
00088
00089 if ( absValue < 0.5 )
00090 {
00091 return 1.0;
00092 }
00093 else if ( absValue == 0.5 )
00094 {
00095 return 0.5;
00096 }
00097 else
00098 {
00099 return 0.0;
00100 }
00101
00102 }
00103
00105 inline double Evaluate ( const Dispatch<1>&, const double& u) const
00106 {
00107
00108 double absValue = vnl_math_abs( u );
00109
00110 if ( absValue < 1.0 )
00111 {
00112 return 1.0 - absValue;
00113 }
00114 else
00115 {
00116 return 0.0;
00117 }
00118
00119 }
00120
00122 inline double Evaluate ( const Dispatch<2>&, const double& u) const
00123 {
00124
00125 double absValue = vnl_math_abs( u );
00126
00127 if ( absValue < 0.5 )
00128 {
00129 return 0.75 - vnl_math_sqr( absValue );
00130 }
00131 else if ( absValue < 1.5 )
00132 {
00133 return ( 9.0 - 12.0 * absValue + 4.0 * vnl_math_sqr( absValue ) ) / 8.0;
00134 }
00135 else
00136 {
00137 return 0.0;
00138 }
00139
00140 }
00141
00143 inline double Evaluate ( const Dispatch<3>&, const double& u) const
00144 {
00145
00146 double absValue = vnl_math_abs( u );
00147 double sqrValue = vnl_math_sqr( u );
00148
00149 if ( absValue < 1.0 )
00150 {
00151 return ( 4.0 - 6.0 * sqrValue + 3.0 * sqrValue * absValue ) / 6.0;
00152 }
00153 else if ( absValue < 2.0 )
00154 {
00155 return ( 8.0 - 12 * absValue + 6.0 * sqrValue -
00156 sqrValue * absValue ) / 6.0;
00157 }
00158 else
00159 {
00160 return 0.0;
00161 }
00162
00163 }
00164
00166 inline double Evaluate ( const DispatchBase&, const double&) const
00167 {
00168 itkExceptionMacro("Evaluate not implemented for spline\
00169 order " << SplineOrder);
00170 return 0.0;
00171
00172 }
00174
00175 };
00176
00177
00178 }
00179
00180 #endif
00181