00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
00051 sort(neighborValues.begin(),neighborValues.end());
00052 *rp=neighborValues[imedian];
00053 }
00054
00055
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
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
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
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
00096 if ( ((*rp)-min) < (max-(*rp)))
00097 *rp = min;
00098 else if ( ((*rp)-min) > (max-(*rp)))
00099 *rp = max;
00100
00101 }
00102
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
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
00186 indx2region.push_back(0);
00187 int nbRegions=1;
00188
00189 res.Resize(src.Size());
00190 res.Fill(0);
00191
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
00206 neigborIndexes.clear();
00207 for(uint i=0;i<mask.size();i++)
00208 {
00209
00210 Vect3Di npos=rp.Pos()+mask[i];
00211 if(src.IsInside(npos) && src(npos)==srcval)
00212 {
00213
00214
00215 int neighborIndex=res(npos);
00216 neigborIndexes.push_back(neighborIndex);
00217 }
00218 }
00219 if(neigborIndexes.size())
00220 {
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
00229 int anIndexOfThisRegion=neigborIndexes[0];
00230 *rp=anIndexOfThisRegion;
00231
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 {
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 {
00259
00260 *rp=indx2region.size();
00261 int thisRegion=nbRegions++;
00262 indx2region.push_back(thisRegion);
00263 }
00264
00265
00266
00267
00268 }
00269
00270
00271
00272
00273
00274
00275 uint i;
00276 map<int,int> old2newregion;
00277 int nbNewRegions=0;
00278
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
00289 for(i=0;i<indx2region.size();i++)
00290 {
00291 indx2region[i]=old2newregion[indx2region[i]];
00292 }
00293
00294
00295
00296 for(rp=res.begin();rp!=res.end();rp++)
00297 {
00298 *rp=indx2region[*rp];
00299 }
00300
00301 }
00302 #endif // _MorphologicalOperators_hxx