Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef __cmtkFilterMask_h_included_
00034 #define __cmtkFilterMask_h_included_
00035
00036 #include <cmtkconfig.h>
00037
00038 #include <Base/cmtkTypes.h>
00039 #include <Base/cmtkUnits.h>
00040 #include <Base/cmtkFixedVector.h>
00041 #include <Base/cmtkMathUtil.h>
00042
00043 #include <System/cmtkSmartPtr.h>
00044
00045 #include <math.h>
00046 #include <vector>
00047
00048 namespace
00049 cmtk
00050 {
00051
00054
00060 template<int DIM>
00061 class FilterMaskPixel
00062 {
00063 public:
00065 typedef FilterMaskPixel Self;
00066
00068 typedef SmartPointer<Self> SmartPtr;
00069
00071 FilterMaskPixel() {}
00072
00074 FilterMaskPixel
00075 ( const FixedVector<DIM,int>& location, const int relativeIndex, const Types::DataItem coefficient )
00076 : Location( location ),
00077 RelativeIndex ( relativeIndex ),
00078 Coefficient( coefficient )
00079 {}
00080
00082 FixedVector<DIM,int> Location;
00083
00085 int RelativeIndex;
00086
00088 Types::DataItem Coefficient;
00089
00091 int PixelIndex;
00092
00099 bool Valid;
00100 };
00101
00106 template<int DIM>
00107 class FilterMask :
00109 public std::vector< FilterMaskPixel<DIM> >
00110 {
00111 public:
00113 typedef FilterMask<DIM> Self;
00114
00116 typedef std::vector< FilterMaskPixel<DIM> > Superclass;
00117
00119 typedef SmartPointer<Self> SmartPtr;
00120
00122 template<class F>
00123 FilterMask( const FixedVector<DIM,int>& dims, const FixedVector<DIM,Types::Coordinate>& deltas, const Types::Coordinate radius, F filter )
00124 {
00125 FixedVector<DIM,int> pixel;
00126 FixedVector<DIM,int> width;
00127 FixedVector<DIM,Types::Coordinate> position;
00128
00129 for ( int dim = 0; dim < DIM; ++dim )
00130 {
00131 pixel[dim] = - (width[dim] = 1+static_cast<int>( radius / deltas[dim] ));
00132 position[dim] = pixel[dim] * deltas[dim];
00133 }
00134
00135 bool done = false;
00136 while ( ! done )
00137 {
00138
00139 for ( int dim = 0; dim < DIM; ++dim )
00140 {
00141 ++pixel[dim];
00142 if ( pixel[dim] <= width[dim] )
00143 {
00144
00145 dim = DIM;
00146 }
00147 else
00148 {
00149 if ( dim+1 == DIM )
00150
00151 done = true;
00152 else
00153 {
00154
00155 pixel[dim] = -width[dim];
00156 }
00157 }
00158 }
00159
00160 if ( ! done )
00161 {
00162
00163 Types::Coordinate distance = 0.0;
00164 for ( int dim = 0; dim < DIM; ++dim )
00165 {
00166 position[dim] = pixel[dim] * deltas[dim];
00167 distance += position[dim] * position[dim];
00168 }
00169 distance = sqrt( distance );
00170
00171 if ( distance < radius )
00172 {
00173 const int index = pixel[0] + dims[0] * (pixel[1] + dims[1] * pixel[2] );
00174 this->push_back( FilterMaskPixel<DIM>( pixel, index, filter( position ) ) );
00175 }
00176 }
00177 }
00178 }
00179
00181 class Gaussian
00182 {
00183 public:
00185 Gaussian( const Units::GaussianSigma& standardDeviation )
00186 {
00187 InvStandardDeviation = 1.0 / standardDeviation.Value();
00188 NormFactor = 1.0 / (sqrt(2.0 * M_PI) * standardDeviation.Value());
00189 }
00190
00192 Types::DataItem operator() ( const FixedVector<DIM,Types::Coordinate>& relativePosition )
00193 {
00194 Types::Coordinate distance = 0;
00195 for ( int i = 0; i < DIM; ++i )
00196 distance += relativePosition[i] * relativePosition[i];
00197 return static_cast<Types::DataItem>( NormFactor * exp( -distance * MathUtil::Square( InvStandardDeviation ) / 2 ) );
00198 }
00199
00200 private:
00202 Types::Coordinate InvStandardDeviation;
00203
00205 Types::Coordinate NormFactor;
00206 };
00207 };
00208
00209 }
00210
00211 #endif // #ifndef __cmtkFilterMask_h_included_