00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00019 #ifndef _Filter_hpp
00020 #define _Filter_hpp
00021
00022 #include<iterator>
00023 #include<ImLib3D/Image3Dlinear.hpp>
00024 #include<algorithm>
00025
00026
00027
00029
00031
00032 class Filter : public Image3Df
00033 {
00034 private:
00035
00036 public:
00037
00038 Filter(const Filter& fi, const Vect3Di& centerpoint):Image3Df(fi)
00039 {properties.iCenter=new Vect3Di(centerpoint);}
00040 Filter(const Size3D & size, const Vect3Di& centerpoint):Image3Df(size)
00041 {properties.iCenter=new Vect3Di(centerpoint);}
00042 Filter(int _width, int _height, int _depth, const Vect3Di centerpoint):Image3Df(_width, _height, _depth)
00043 {properties.iCenter=new Vect3Di(centerpoint);}
00044 Filter(const string& fname):Image3Df()
00045 {Streamable::ReadFromFile(fname);}
00046
00047 Vect3Di GetCenter() const {return *properties.iCenter;}
00048 void SetCenter(const Vect3Di& centerpoint){*properties.iCenter = centerpoint;}
00049 };
00050
00051
00052 class SeparableFilter
00053 {
00054 protected:
00055 void Resize()
00056 {
00057 xcomponent.assign(size.width,0);
00058 ycomponent.assign(size.height,0);
00059 zcomponent.assign(size.depth,0);
00060 }
00061 public:
00062 SeparableFilter(Size3D _size,Vect3Di _iCenter):size(_size),iCenter(_iCenter){Resize();}
00063 SeparableFilter(Vect3Di _size,Vect3Di _iCenter):size(_size),iCenter(_iCenter){Resize();}
00064 vector<float> xcomponent;
00065 vector<float> ycomponent;
00066 vector<float> zcomponent;
00067 Size3D size;
00068 Vect3Di iCenter;
00069 };
00070
00072 template<class RealType>
00073 void BinomialFilterMask(uint order, vector<RealType>& filtermask)
00074 {
00075 if (order == 0)
00076 {
00077 filtermask.assign(1,1);
00078 return;
00079 }
00080 if (order == 1)
00081 {
00082 filtermask.assign(2,1);
00083 return;
00084 }
00085 vector<RealType> upperRow(order+1,0);
00086 vector<RealType> lowerRow(order+1,0);
00087 upperRow[0] = 1;
00088 for (uint i=1; i<order+1; i++)
00089 {
00090 lowerRow[0]=1;
00091 for (uint j=1; j<i; j++)
00092 {
00093 lowerRow[j]=upperRow[j-1]+upperRow[j];
00094 }
00095 lowerRow[i]=1;
00096 upperRow = lowerRow;
00097 }
00098
00099 double sum=0;
00100 for (typename vector<RealType>::iterator p = lowerRow.begin(); p!= lowerRow.end(); ++p)
00101 {
00102 sum += *p;
00103 }
00104 if (sum==0)ThrowError("Runtime error in BinomialFilterMask (sum==0)");
00105
00106 for (typename vector<RealType>::iterator p = lowerRow.begin(); p!= lowerRow.end(); ++p)
00107 {
00108 *p /= sum;
00109 }
00110 filtermask = lowerRow;
00111 }
00112
00114 class BinomialFilter : public SeparableFilter
00115 {
00116 public:
00117 BinomialFilter(int order) : SeparableFilter(Size3D(order+1, order+1, order+1), Vect3Di(order/2, order/2, order/2))
00118 {
00119 vector<double> filtermask;
00120 BinomialFilterMask(order, filtermask);
00121
00122
00123 double sigma = sqrt((double)order/4.0);
00124 int support = (int)(4.5*sigma + 1.0);
00125 int diff = filtermask.size() - (support*2+1);
00126 if (diff > 0)
00127 {
00128 vector<double> fullmask = filtermask;
00129 filtermask.resize(support*2+1);
00130 for (int i = 0; i < (2*support+1) ; ++i)
00131 filtermask[i] = fullmask[diff/2 + i];
00132 if (diff%2)
00133 filtermask.push_back(fullmask[diff/2+2*support+1]);
00134 }
00135
00136
00137 xcomponent.resize(filtermask.size());
00138 copy(filtermask.begin(),filtermask.end(),xcomponent.begin());
00139 ycomponent=zcomponent=xcomponent;
00140 size=Size3D(xcomponent.size(), ycomponent.size(), zcomponent.size());
00141
00142 int c=(filtermask.size()-1)/2;
00143 iCenter = Vect3Di(c,c,c);
00144 }
00145 };
00146
00147 inline ostream& operator<<(ostream& s, SeparableFilter& filt)
00148 {
00149 s << "xVect: " << endl;
00150 copy(filt.xcomponent.begin(),filt.xcomponent.end(),ostream_iterator<float>(s," "));
00151 s << endl;
00152 s << "yVect: " << endl;
00153 copy(filt.ycomponent.begin(),filt.ycomponent.end(),ostream_iterator<float>(s," "));
00154 s << endl;
00155 s << "zVect: " << endl;
00156 copy(filt.zcomponent.begin(),filt.zcomponent.end(),ostream_iterator<float>(s," "));
00157 s << endl;
00158 s << "Center: " << filt.iCenter << endl;
00159 return s;
00160 }
00161
00162
00163 #endif //_Filter_hpp