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

MorphologicalOperators.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  */
00018 
00021 #ifndef _MorphologicalOperators_hpp
00022 #define _MorphologicalOperators_hpp
00023 
00024 #include<ImLib3D/ImageProcessor.hpp>
00025 #include<map>
00026 
00028 
00030 enum StructureElementType
00031 {
00032     MORPHO_CUSTOM,  
00033     MORPHO_FORWARD,  
00034     MORPHO_BACKWARD, 
00035     MORPHO_ALLDIRECTIONS, 
00036     MORPHO_Cubic27, 
00037     MORPHO_Cross7,  
00038     MORPHO_Planar19,
00039     MORPHO_Corner9 ,
00040     MORPHO_Pts81,       
00041     MORPHO_Pts14,
00042     MORPHO_Pts4,
00043     MORPHO_Pts10,
00044     MORPHO_Pts5,
00045     MORPHO_Pts41,
00046     MORPHO_XYCross5, 
00047     MORPHO_XZCross5, 
00048     MORPHO_YZCross5, 
00049     MORPHO_SphereR3, 
00050     MORPHO_SphereR4  
00051 };
00052 
00054 
00057 class StructureElement
00058 {
00059 protected:
00061     StructureElementType maskType;
00063     void CreateMask();
00064 public:
00066     void ComputeMaskPointsSize(Vect3Di &minv,Vect3Di &maxv) const;
00067 protected:
00069     void CreateMaskPoints(StructureElementType maskType);
00071     void CreateMaskPoints();
00072 
00074     vector<Vect3Di> maskPoints;
00076     vector<float> coeffs;
00078 
00080     Mask3D *mask;
00081 public:
00082     static void CreateSpherePointList(int radius,vector<Vect3Di>& pl);
00083     void ComputeCoeffs();
00085     void Show(const string &name) const;
00087     inline const Vect3Di &GetPoint(int i) const {return maskPoints[i];}
00088     inline const Vect3Di &operator[](uint i) const {return maskPoints[i];}
00089     inline float GetCoeff(int i) const {return coeffs[i];}
00091     RectZone3Di SafeZone(const Size3D &imageSize) const
00092     {
00093         Vect3Di vmin,vmax;
00094         ComputeMaskPointsSize(vmin,vmax);
00095         return RectZone3Di(Vect3Di(0,0,0),imageSize).Intersection(
00096             RectZone3Di(-vmin,imageSize.GetV()-vmax-Vect3Di(1,1,1)));
00097     }
00099     int   FindPoint(const Vect3Di &P) const 
00100     {
00101         for(uint i=0;i<maskPoints.size();i++)
00102         {if(P==maskPoints[i]){return i;}}
00103         return -1;
00104     }
00106     float GetCoeff(const Vect3Di &P) const 
00107     {
00108         int i=FindPoint(P);
00109         if(i<0)ThrowError("GetCoeff(P=%d %d %d) point not found",P.x,P.y,P.z);
00110         return coeffs[i];
00111     }
00112     const Mask3D  &Mask() const {return *mask;}
00113     inline int  GetNbPoints() const {return maskPoints.size();}
00114     inline uint size() const {return maskPoints.size();}
00116     
00118 
00120     void RemoveCenter();
00121     
00123     ~StructureElement()
00124     {
00125         if(mask){delete mask;}
00126     }
00128     StructureElement(const string &s);
00129 
00131     StructureElement(const StructureElement &other,StructureElementType direction);
00132 
00134     StructureElement(StructureElementType _maskType):
00135         maskType(_maskType),
00136         mask(NULL)
00137     {
00138         CreateMaskPoints(maskType);
00139         CreateMask();
00140     }
00142     StructureElement(const vector<Vect3Di> &_maskPoints):
00143         maskType(MORPHO_CUSTOM),
00144         mask(NULL)
00145     {
00146         maskPoints=_maskPoints;
00147         CreateMask();
00148     }
00149 };
00150 
00152 
00154 template<class ImageType,class Inst=typename HasPointerIterators<ImageType>::value >
00155 class ImageNeighbors
00156 {
00157     typedef typename ImageType::value_type Im3DValue;
00158     typedef typename ImageType::iteratorFast Iterator;
00159     ImageType &image;
00160     const StructureElement &sel;
00163     Im3DValue ** iterators;//vector<Iterator> iterators;
00164     typename ImageType::iteratorXYZ p;
00165     uint npts;
00166     RectZone3Di safezone;
00167     int lastY;
00168     int lastX;
00169 public:
00170     inline bool IsSafe(const Vect3Di &pos){return safezone.IsInside(pos);}
00171     inline void MoveTo(const Vect3Di &pos)
00172     {
00173         if(lastY!=pos.y || lastX!=pos.x-1)
00174         {// if we've changed line we have to recompute iterators (slow)
00175             for(uint i=0;i<npts;i++)
00176             {
00177                 iterators[i]=(Im3DValue *)&image(pos+sel[i]);
00178 //              iterators[i].MoveTo(pos+sel[i]);
00179             }
00180             lastY=pos.y;
00181             lastX=pos.x;
00182         }
00183         else
00184         {// fast!, just increment iterators
00185             for(uint i=0;i<npts;i++){iterators[i]++;}
00186             lastX++;
00187         }
00188     }
00189     inline void MoveBackwardsTo(const Vect3Di &pos)
00190     {
00191         if(lastY!=pos.y || lastX!=pos.x+1)
00192         {// if we've changed line we have to recompute iterators (slow)
00193             for(uint i=0;i<npts;i++)
00194             {
00195                 iterators[i]=(Im3DValue *)&image(pos+sel[i]);
00196 //              iterators[i].MoveTo(pos+sel[i]);
00197             }
00198             lastY=pos.y;
00199             lastX=pos.x;
00200         }
00201         else
00202         {// fast!, just decrement iterators
00203             for(uint i=0;i<npts;i++){iterators[i]--;}
00204             lastX--;
00205         }
00206     }
00207     inline Im3DValue &operator[](int i){return *(iterators[i]);}
00208     ~ImageNeighbors(){delete [] iterators;}
00209     ImageNeighbors(ImageType &_image,const StructureElement &_sel):
00210         image(_image),sel(_sel),
00211         iterators(new Im3DValue*[sel.size()]),//iterators(sel.size()),
00212         npts(sel.size()),
00213         safezone(sel.SafeZone(image.Size())),lastY(-1),lastX(-2)
00214     {
00215         //for(uint i=0;i<npts;i++){iterators[i]=image.begin();}
00216     }
00217 };
00218 
00219 template<class ImageType>
00220 struct IteratorType
00221 {
00222     typedef typename ImageType::iterator type;
00223 };
00224 template<class ImageType>
00225 struct IteratorType<const ImageType>
00226 {
00227     typedef typename ImageType::const_iterator type;
00228 };
00229 
00230 template<class ImageType>
00231 class ImageNeighbors<ImageType,__false_type>
00232 {
00233     typedef typename ImageType::value_type Im3DValue;
00234     typedef typename IteratorType<ImageType>::type Iterator;
00235     ImageType &image;
00236     const StructureElement &sel;
00239     vector<Iterator> iterators;
00240     typename ImageType::iteratorXYZ p;
00241     uint npts;
00242     RectZone3Di safezone;
00243     int lastY;
00244     int lastX;
00245 public:
00246     inline bool IsSafe(const Vect3Di &pos){return safezone.IsInside(pos);}
00247     inline void MoveTo(const Vect3Di &pos)
00248     {
00249         if(lastY!=pos.y || lastX!=pos.x-1)
00250         {// if we've changed line we have to recompute iterators (slow)
00251             for(uint i=0;i<npts;i++)
00252             {
00253                 iterators[i]=pos+sel[i];
00254             }
00255             lastY=pos.y;
00256             lastX=pos.x;
00257         }
00258         else
00259         {// fast!, just increment iterators
00260             for(uint i=0;i<npts;i++){iterators[i]++;}
00261             lastX++;
00262         }
00263     }
00264     inline void MoveBackwardsTo(const Vect3Di &pos)
00265     {
00266         if(lastY!=pos.y || lastX!=pos.x+1)
00267         {// if we've changed line we have to recompute iterators (slow)
00268             for(uint i=0;i<npts;i++)
00269             {
00270 //              iterators[i]=(Im3DValue *)&image(pos+sel[i]);
00271                 iterators[i]=pos+sel[i];
00272             }
00273             lastY=pos.y;
00274             lastX=pos.x;
00275         }
00276         else
00277         {// fast!, just decrement iterators
00278             for(uint i=0;i<npts;i++){iterators[i]--;}
00279             lastX--;
00280         }
00281     }
00282     inline Im3DValue operator[](int i){return *(iterators[i]);}
00283     ~ImageNeighbors(){}
00284     ImageNeighbors(ImageType &_image,const StructureElement &_sel):
00285         image(_image),sel(_sel),
00286 //      iterators(new Im3DValue*[sel.size()]),
00287         iterators(sel.size()),
00288         npts(sel.size()),
00289         safezone(sel.SafeZone(image.Size())),lastY(-1),lastX(-2)
00290     {
00291         for(uint i=0;i<npts;i++){iterators[i]=image.begin();}
00292     }
00293 };
00294 
00295 
00296 
00297 namespace IP3D
00298 {
00308     template <class ImageType>
00309     void MedianFilter(const ImageType& src, const StructureElement &mask, ImageType& res);
00310 };
00311 
00312 namespace IP3D
00313 {
00324     template <class ImageType>
00325     void SharpeningFilter(const ImageType& src, const StructureElement &mask, ImageType& res);
00326 };
00327 
00328 
00329 namespace IP3D
00330 {
00340     template <class ImageType>
00341     void Erosion(const ImageType& src, const StructureElement &mask, ImageType& res);
00342 };
00343 
00344 namespace IP3D
00345 {
00355     template <class ImageType>
00356     void Dilation(const ImageType& src, const StructureElement &mask, ImageType& res);
00357 };
00358 
00359 namespace IP3D
00360 {
00369     template <class ImageType>
00370     void Opening(const ImageType& src, const StructureElement &mask, ImageType& res)
00371     {
00372         IP3D::Erosion(src,mask,res);
00373         IP3D::Dilation(res,mask,res);
00374     }
00375 };
00376 
00377 namespace IP3D
00378 {
00387     template <class ImageType>
00388     void Closing(const ImageType& src, const StructureElement &mask, ImageType& res)
00389     {
00390         IP3D::Dilation(src,mask,res);
00391         IP3D::Erosion(res,mask,res);
00392     }
00393 };
00394 
00395 namespace IP3D
00396 {
00411         void DistanceTransform(const Mask3D& src, const StructureElement &mask, Image3Df& res,bool borderExtend=false);
00412 };
00413 
00414 namespace IP3D
00415 {
00427     template <class ImageType>
00428     void ConnectedComponentLabelling(const ImageType& src, const StructureElement &mask0, LabelImage3D& res,typename ImageType::value_type *background0=NULL);
00429 };
00430 template <class ImageType> inline pair<bool,typename ImageType::value_type> DefaultBackground(){return pair<bool,typename ImageType::value_type>(false,typename ImageType::value_type());}
00431 template <> inline pair<bool,byte> DefaultBackground<Mask3D>(){return pair<bool,byte>(true,0);}
00432 
00433 namespace IP3D
00434 {
00444         void FillHoles(const Mask3D& src, const StructureElement &mask, Mask3D& res);
00445 };
00446 
00447 class CMakeValueList;
00448 
00449 
00451 template<class Im3DValue>
00452 class ImageValues
00453 {
00454     friend class CMakeValueList;
00455 public:
00456     class ImageValue
00457     {
00458     public:
00459         int size;// number of voxels having this value
00460         Vect3Di point;// position of a voxel having this value
00461         ImageValue(){size=0;point.x=-1;point.y=-1;}
00462     };
00463     typedef map<Im3DValue,ImageValue> MapType;
00464     map<Im3DValue,ImageValue> values;
00465     ImageValue operator[](const Im3DValue &v)
00466     {
00467         return values[v];
00468     }
00469 
00470 };
00471 namespace IP3D
00472 {
00480     template <class ImageType>
00481     void MakeValueList(const ImageType& src, ImageValues<typename ImageType::value_type>& res);
00482 };
00483 
00484 namespace IP3D
00485 {
00493         void LargestConnectedComponent(const Mask3D &src,Mask3D &res);
00494 };
00495 
00496 
00497 #include<ImLib3D/MorphologicalOperators.hxx>
00498 
00499 #endif // _MorphologicalOperators_hpp

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