Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

Filter.hpp

Go to the documentation of this file.
00001 /* ImLib3D
00002  * Copyright (c) 2001, ULP-IPB Strasbourg.
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or (at
00007  * your option) any later version.
00008  * 
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  * 
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00019 #ifndef _Filter_hpp
00020 #define _Filter_hpp
00021 
00022 #include<iterator>
00023 #include<ImLib3D/Image3Dlinear.hpp>
00024 #include<algorithm>
00025 
00026 
00027 // ****************** Filter ************************ 
00029 
00031 // **************************************************
00032 class Filter : public Image3Df
00033 {
00034 private:
00035 //  Vect3Di center;
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);// calculate using double for higher precision(pb with high order filters)
00121 
00122         // prune at +- 4.5 sigma (sigma*sigme=order/4)
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) // (support*2+1) > filtermask.size()
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         // assign components
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         //      assert(filtermask.size()%2); // if not impair result will be deplaced one voxel towards the origin
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

Generated on Fri Jun 17 13:36:03 2005 for ImLib3D by  doxygen 1.4.2