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

MorphologicalOperators.hxx

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 _MorphologicalOperators_hxx
00020 #define _MorphologicalOperators_hxx
00021 
00022 #include<ImLib3D/Image3D.hpp>
00023 #include<ImLib3D/MorphologicalOperators.hpp>
00024 #include<algorithm>
00025 #include<ImLib3D/ImageProgress.hpp>
00026 
00027 template <class ImageType>
00028 void
00029 IP3D::MedianFilter(const ImageType& src, const StructureElement &mask, ImageType& res0)
00030 {
00031     ImageProcessorArgs<ImageType> args(ImArgs(src),res0);
00032     args.SameSize();
00033     ImageType &res=args.GetDest();
00034 
00035     // create vector for containing neighborValues
00036     vector<typename ImageType::value_type> neighborValues;
00037     neighborValues.assign(mask.size(),src(0,0,0));
00038     int imedian=mask.size()/2;
00039 
00040     typename ImageType::iteratorXYZ rp;
00041     ImageProgress tracker("MedianFilter",rp);
00042     for(rp=res.begin();rp!=res.end();rp++)
00043     {
00044         // find neighborValues
00045         neighborValues[0]=src.SafeValue(rp.Pos()+mask.GetPoint(0));
00046         for(uint i=1;i<mask.size();i++)
00047         {
00048             neighborValues[i]=src.SafeValue(rp.Pos()+mask[i]);
00049         }
00050         // now find median of neighborValues
00051         sort(neighborValues.begin(),neighborValues.end());
00052         *rp=neighborValues[imedian];
00053     }   
00054 
00055     //args.Finished();
00056 }
00057 
00058 
00059 template <class ImageType>
00060 void
00061 IP3D::SharpeningFilter(const ImageType& src, const StructureElement &mask, ImageType& res0)
00062 {
00063     typedef typename ImageType::value_type Im3DValue;
00064     ImageProcessorArgs<ImageType> args(ImArgs(src),res0);
00065     args.SameSize();
00066     ImageType &res=args.GetDest();
00067 
00068     // create vector for containing neighborValues
00069     vector<Im3DValue> neighborValues;
00070     neighborValues.assign(mask.size(),src(0,0,0));
00071 
00072     typename ImageType::iteratorXYZ rp;
00073     ImageProgress tracker("SharpeningFilter",rp);
00074     for(rp=res.begin();rp!=res.end();rp++)
00075     {
00076         *rp=src(rp.Pos());
00077         // find neighborValues
00078         neighborValues[0]=src.SafeValue(rp.Pos()+mask.GetPoint(0));
00079         for(uint i=1;i<mask.size();i++)
00080         {
00081             neighborValues[i]=src.SafeValue(rp.Pos()+mask[i]);
00082         }
00083         Im3DValue min = neighborValues[0];
00084         Im3DValue max = neighborValues[0];
00085         int minindex=0;
00086         int maxindex=0; 
00087         // find min and max neighbor-value
00088         for(uint i=1;i<mask.size();i++)
00089         {
00090             if (neighborValues[i] > max)
00091             {max = neighborValues[i];maxindex=i;}
00092             if (neighborValues[i] < min)
00093             {min = neighborValues[i];minindex=i;}
00094         }
00095         // now assign current to min or max, whichever value is closest:
00096         if ( ((*rp)-min) < (max-(*rp)))
00097             *rp = min;
00098         else if ( ((*rp)-min) > (max-(*rp)))
00099             *rp = max;
00100         // or leave unchanged when distance the same
00101     }   
00102     //args.Finished();
00103 }
00104 
00105 
00106 template <class ImageType>
00107 void
00108 IP3D::Erosion(const ImageType& src, const StructureElement &mask, ImageType& res0)
00109 {
00110     ImageProcessorArgs<ImageType> args(ImArgs(src),res0);
00111     args.SameSize();
00112     ImageType &res=args.GetDest();
00113 
00114     ImageNeighbors<const ImageType> neighbors(src,mask);
00115     uint npts=mask.size();
00116     typename ImageType::iteratorXYZ rp;
00117     ImageProgress tracker("Erosion",rp);
00118     for(rp=res.begin();rp!=res.end();rp++)
00119     {
00120         const Vect3Di &pos=rp.Pos();
00121         if(neighbors.IsSafe(pos))
00122         {
00123             neighbors.MoveTo(pos);
00124             *rp=neighbors[0];
00125             for(uint i=1;i<npts;i++)
00126             {
00127                 *rp=min(*rp,neighbors[i]);
00128             }
00129         }
00130         else
00131         {
00132             *rp=src.SafeValue(rp.Pos()+mask.GetPoint(0));
00133             for(uint i=1;i<npts;i++)
00134             {
00135                 *rp=min(*rp,src.SafeValue(rp.Pos()+mask[i]));
00136             }
00137         }
00138     }   
00139 }
00140 
00141 template <class ImageType>
00142 void
00143 IP3D::Dilation(const ImageType& src, const StructureElement &mask, ImageType& res0)
00144 {
00145     ImageProcessorArgs<ImageType> args(ImArgs(src),res0);
00146     args.SameSize();
00147     ImageType &res=args.GetDest(0);
00148     typename ImageType::iteratorXYZ rp;
00149     ImageProgress tracker("Dilation",rp);
00150     for(rp=res.begin();rp!=res.end();rp++)
00151     {
00152         *rp=src.SafeValue(rp.Pos()+mask.GetPoint(0));
00153         for(uint i=1;i<mask.size();i++)
00154         {
00155             *rp=max(*rp,src.SafeValue(rp.Pos()+mask[i]));
00156         }
00157     }   
00158 }
00159 
00160 
00161 template <class ImageType>
00162 void
00163 IP3D::MakeValueList(const ImageType& src, ImageValues<typename ImageType::value_type>& res)
00164 {
00165     typename ImageType::const_iteratorXYZ sp;
00166     for(sp=src.begin();sp!=src.end();sp++)
00167     {
00168         res.values[*sp].point=sp.Pos();
00169         res.values[*sp].size++;
00170     }   
00171 }
00172 
00173 
00174 template <class ImageType>
00175 void
00176 IP3D::ConnectedComponentLabelling(const ImageType& src, const StructureElement &mask0, LabelImage3D& res,typename ImageType::value_type *background0)
00177 {
00178     // ALGO: For each pixel 
00179     typedef typename ImageType::value_type Im3DValue;
00180     pair<bool,Im3DValue> backgroundInfo=DefaultBackground<ImageType>();
00181     bool hasBackground=backgroundInfo.first;
00182     Im3DValue background=backgroundInfo.second;
00183     vector<int> indx2region;
00184     indx2region.reserve(1000);
00185     // default indx=0 -> region=0 = background
00186     indx2region.push_back(0);
00187     int nbRegions=1;
00188 
00189     res.Resize(src.Size());
00190     res.Fill(0);
00191 //      for(LabelImage3D::iteratorFast fp=res.begin();fp!=res.end();fp++){if(*fp){*fp=1;}}
00192 
00193     StructureElement mask(mask0,MORPHO_FORWARD);
00194     LabelImage3D::iteratorXYZ rp;
00195     vector<int> neigborIndexes;
00196     neigborIndexes.reserve(mask.size());
00197 
00198     ImageProgress tracker("ConnectedComponentLabelling",rp);
00199     for(rp=res.begin();rp!=res.end();rp++)
00200     {
00201         int talk=0;
00202         if(rp.Pos()==Vect3Di(48,5,76)){talk=1;}
00203         const Im3DValue &srcval=src(rp.Pos());
00204         if(hasBackground && background==srcval){*rp=0;continue;}
00205         // let's see if this voxel has any neigbors
00206         neigborIndexes.clear();
00207         for(uint i=0;i<mask.size();i++)
00208         {
00209 //          if((currIndex=res.SafeValue(rp.Pos()+mask[i])))
00210             Vect3Di npos=rp.Pos()+mask[i];
00211             if(src.IsInside(npos) && src(npos)==srcval)
00212             {// found a neigbor!
00213 //                      mprintf("found neigbor index:%2d ",currIndex);
00214 //                      (rp.Pos()+mask[i]).Show("pos:","\n");
00215                 int neighborIndex=res(npos);
00216                 neigborIndexes.push_back(neighborIndex);
00217             }
00218         }
00219         if(neigborIndexes.size())
00220         {// found neigbors!
00221             if(talk)
00222             {
00223                 for(uint i=0;i<neigborIndexes.size();i++)
00224                 {
00225                     mprintf("found neigborIndexes:%d:%d\n",i,neigborIndexes[i]);
00226                 }
00227             }
00228             // set this pixel to the same value as one of those neigbors
00229             int anIndexOfThisRegion=neigborIndexes[0];
00230             *rp=anIndexOfThisRegion;
00231             // make all neigbor indexes point to the same region
00232             int thisRegion=indx2region[anIndexOfThisRegion];
00233             if(talk)
00234             {
00235                 mprintf("anIndexOfThisRegion:%d\n",anIndexOfThisRegion);
00236                 mprintf("thisRegion:%d\n",thisRegion);
00237             }
00238             for(uint i=1;i<neigborIndexes.size();i++)
00239             {
00240                 if(talk)
00241                 {
00242                     mprintf("setting neigborIndexes:%d:%d: previous region:%d\n",i,neigborIndexes[i],indx2region[neigborIndexes[i]]);
00243                 }
00244                 int oldNeighborRegion=indx2region[neigborIndexes[i]];
00245                 if(oldNeighborRegion!=thisRegion)
00246                 {// merge 2 regions
00247                     for(uint j=0;j<indx2region.size();j++)
00248                     {
00249                         if(indx2region[j]==oldNeighborRegion)
00250                         {
00251                             indx2region[j]=thisRegion;
00252                         }
00253                     }
00254                 }
00255             }
00256         }
00257         else
00258         {// sorry, no neighbors 
00259             // this lonesome pixel is a new region and index
00260             *rp=indx2region.size();
00261             int thisRegion=nbRegions++;
00262             indx2region.push_back(thisRegion);
00263         }
00264 //      }else
00265 //      {
00266 //          *rp=0;// background index
00267 //      }
00268     }
00269 //      mprintf("CConnectedComponentLabelling:: region image\n");
00270 //      LabelImage3D regions=res;
00271 //      for(LabelImage3D::iteratorFast fp=regions.begin();fp!=regions.end();fp++){*fp=indx2region[*fp];}    
00272 //      ImLib3DDisplay::Show(regions);
00273 
00274     // ***** now compute new unique regions
00275     uint i;
00276     map<int,int> old2newregion;
00277     int nbNewRegions=0;
00278     // add  background region
00279     old2newregion[0]=nbNewRegions++;
00280     for(i=0;i<indx2region.size();i++)
00281     {
00282         int old=indx2region[i];
00283         if(old2newregion.find(old)==old2newregion.end())
00284         {
00285             old2newregion[old]=nbNewRegions++;
00286         }
00287     }
00288     // switch to new regions
00289     for(i=0;i<indx2region.size();i++)
00290     {
00291         indx2region[i]=old2newregion[indx2region[i]];
00292     }   
00293 
00294 
00295     // ***** now let's switch from indexes to regions
00296     for(rp=res.begin();rp!=res.end();rp++)
00297     {
00298         *rp=indx2region[*rp];
00299     }
00300 
00301 }
00302 #endif // _MorphologicalOperators_hxx

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