00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 #ifndef SEGMENTIMAGEMC2_C_DEFINED
00049 #define SEGMENTIMAGEMC2_C_DEFINED
00050 
00051 #include "Util/Assert.H"
00052 #include "VFAT/segmentImageMC2.H"
00053 #include <iostream>
00054 #include <vector>
00055 #include <cstdio>
00056 #include <cstdlib>
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 template SI_TEMPLATE_CLASS
00067 segmentImageMC2<SI_TEMPLATE>::segmentImageMC2()
00068 {
00069   SI_set1 = false; SI_set2 = false; SI_set3 = false; SI_set4 = false;
00070   LINFO("CREATED");
00071   SI_lowThresh.resize(SI_channels,0);
00072   SI_highThresh.resize(SI_channels,0);
00073   SI_maxIDVal = 0;
00074   SI_killVal  = 2;
00075   Image<FLOAT> timage;
00076   SI_infeatureMaps.resize(SI_channels,timage);
00077   SI_useCandidateBandPass = true;
00078   SI_removeSingles        = true;
00079   SI_set4                 = true;
00080 }
00081 
00082 
00083 
00084 template SI_TEMPLATE_CLASS
00085 segmentImageMC2<SI_TEMPLATE>::~segmentImageMC2()
00086 {}
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 template SI_TEMPLATE_CLASS inline
00095 void segmentImageMC2<SI_TEMPLATE>::SIsetVal(const typename
00096                                            std::vector<FLOAT> &val,
00097                                            const typename
00098                                            std::vector<FLOAT> &thresh)
00099 {
00100   typename std::vector<FLOAT>::iterator ilowThresh    = SI_lowThresh.begin();
00101   typename std::vector<FLOAT>::iterator ihighThresh   = SI_highThresh.begin();
00102   typename std::vector<FLOAT>::const_iterator ival    = val.begin();
00103   typename std::vector<FLOAT>::const_iterator ithresh = thresh.begin();
00104 
00105   for(INT i = 0; i < val.size(); i++, ++ilowThresh, ++ihighThresh,
00106         ++ival, ++ithresh)
00107   {
00108     *ilowThresh  = *ival - *ithresh;
00109     *ihighThresh = *ival + *ithresh;
00110   }
00111   SI_set1 = true;
00112 }
00113 
00114 
00115 
00116 template SI_TEMPLATE_CLASS inline
00117 void segmentImageMC2<SI_TEMPLATE>::SIsetValThresh(const typename
00118                                                  std::vector<FLOAT> &high,
00119                                                  const typename
00120                                                  std::vector<FLOAT> &low)
00121 {
00122   SI_lowThresh  = low;
00123   SI_highThresh = high;
00124 
00125   typename std::vector<FLOAT>::iterator ilow  = SI_lowThresh.begin();
00126   typename std::vector<FLOAT>::iterator ihigh = SI_highThresh.begin();
00127 
00128   
00129   while(ilow != SI_lowThresh.end())
00130   {
00131     if(*ilow >= *ihigh)
00132     {
00133       LFATAL("Low threshold must be less than high theshold. Got L %f H %f",*ilow,*ihigh);
00134     }
00135     ++ilow; ++ihigh;
00136   }
00137 
00138   SI_set1 = true;
00139 }
00140 
00141 
00142 template SI_TEMPLATE_CLASS inline
00143 void segmentImageMC2<SI_TEMPLATE>::SIresetCandidates(const bool whichWay)
00144 {
00145   Image<bool>::iterator
00146     candidatePixelsIter    = SI_candidatePixels.beginw();
00147 
00148   Image<bool>::iterator
00149     preCandidatePixelsIter = SI_preCandidatePixels.beginw();
00150 
00151   
00152 
00153   while(candidatePixelsIter != SI_candidatePixels.endw())
00154   {
00155     *candidatePixelsIter    = false;
00156     *preCandidatePixelsIter = whichWay;
00157     ++candidatePixelsIter; ++preCandidatePixelsIter;
00158   }
00159 }
00160 
00161 
00162 
00163 
00164 template SI_TEMPLATE_CLASS inline
00165 void segmentImageMC2<SI_TEMPLATE>::SIsetFrame(int *x, int *y)
00166 {
00167   SI_masterVec.resize(*x*(*y),-1);
00168   SI_reOrderVec.resize(*x*(*y));
00169   SI_reverseOrderVec.resize(*x*(*y));
00170   SI_centerX.resize(*x*(*y));
00171   SI_centerY.resize(*x*(*y));
00172   SI_Xsum.resize(*x*(*y));
00173   SI_Ysum.resize(*x*(*y));
00174   SI_mass.resize(*x*(*y));
00175   SI_xmin.resize(*x*(*y));
00176   SI_xmax.resize(*x*(*y));
00177   SI_ymin.resize(*x*(*y));
00178   SI_ymax.resize(*x*(*y));
00179   SI_reset.resize(*x*(*y));
00180   LINFO("SETTING WIDTH %d, HEIGHT %d",*x,*y);
00181   SI_blobID.resize(*x,*y,-1);
00182   SI_candidatePixels.resize(*x,*y,false);
00183   SI_preCandidatePixels.resize(*x,*y,false);
00184   SI_set2 = true;
00185 }
00186 
00187 
00188 
00189 template SI_TEMPLATE_CLASS inline
00190 void segmentImageMC2<SI_TEMPLATE>::SIsetAvg(const INT doAvg)
00191 {
00192   typename std::vector<FLOAT> temp(SI_channels,0);
00193 
00194   SI_avg.resize(doAvg,temp);
00195   SI_std.resize(doAvg,temp);
00196   SI_N.resize(doAvg,0);
00197   SI_tempAvg.resize(doAvg,0);
00198   SI_tempStd.resize(doAvg,0);
00199   SI_iter = doAvg;
00200   SI_count = 0;
00201   SI_set3 = true;
00202 }
00203 
00204 
00205 
00206 template SI_TEMPLATE_CLASS inline
00207 void segmentImageMC2<SI_TEMPLATE>::SIresetAvg()
00208 {
00209   typename std::vector<FLOAT> temp(SI_channels,0);
00210 
00211   for(typename std::vector<std::vector<FLOAT> >::iterator
00212         iavg = SI_avg.begin(); iavg != SI_avg.end(); ++iavg)
00213     *iavg = temp;
00214   for(typename std::vector<std::vector<FLOAT> >::iterator
00215         istd = SI_std.begin(); istd != SI_std.end(); ++istd)
00216     *istd = temp;
00217 
00218   typename std::vector<FLOAT>::iterator itempAvg = SI_tempAvg.begin();
00219   typename std::vector<FLOAT>::iterator itempStd = SI_tempStd.begin();
00220   typename std::vector<INT>::iterator   iN       = SI_N.begin();
00221 
00222   for(unsigned int i = 0; i < SI_N.size(); i++,
00223         ++itempAvg, ++itempStd, ++iN)
00224   {
00225     *itempAvg = 0.0F; *itempStd = 0.0F; *iN = 0;
00226   }
00227   SI_count = 0;
00228 
00229 }
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 template SI_TEMPLATE_CLASS
00244 void segmentImageMC2<SI_TEMPLATE>::SIsegment(
00245                                Image<PixRGB<byte> > *image,
00246                                typename std::vector<Image<FLOAT> > *featureMap,
00247                                const bool lowPass)
00248 {
00249   SI_workImage      = image;
00250   SIsegment(featureMap,lowPass);
00251 }
00252 
00253 
00254 template SI_TEMPLATE_CLASS
00255 void segmentImageMC2<SI_TEMPLATE>::SIsegment(
00256                                typename std::vector<Image<FLOAT> > *featureMap,
00257                                const bool lowPass)
00258 {
00259   struct timezone tz;
00260   struct timeval start, stop;
00261   tz.tz_minuteswest = 0;
00262   tz.tz_dsttime     = 0;
00263   gettimeofday(&start, &tz);
00264 
00265   
00266   if(lowPass)
00267   {
00268     typename std::vector<Image<FLOAT> >::iterator
00269       iimage = featureMap->begin();
00270     typename std::vector<Image<FLOAT> >::iterator
00271       ifmap = SI_infeatureMaps.begin();
00272 
00273     while(iimage != featureMap->end())
00274     {
00275       *ifmap = lowPass5(*iimage);
00276       ++ifmap; ++iimage;
00277     }
00278     SI_featureMaps = &SI_infeatureMaps;
00279   }
00280   else
00281     SI_featureMaps = featureMap;
00282 
00283 
00284   
00285   SIdoSegment();
00286 
00287   gettimeofday(&stop,&tz);
00288 }
00289 
00290 
00291 template SI_TEMPLATE_CLASS
00292 void segmentImageMC2<SI_TEMPLATE>::SItoggleCandidateBandPass(const bool toggle)
00293 {
00294   SI_useCandidateBandPass = toggle;
00295 }
00296 
00297 
00298 template SI_TEMPLATE_CLASS
00299 void segmentImageMC2<SI_TEMPLATE>::SItoggleRemoveSingles(const bool toggle)
00300 {
00301   SI_removeSingles = toggle;
00302 }
00303 
00304 
00305 template SI_TEMPLATE_CLASS
00306 void segmentImageMC2<SI_TEMPLATE>::SIsetKillValue(const unsigned int kv)
00307 {
00308   SI_killVal = kv;
00309 }
00310 
00311 
00312 
00313 
00314 
00315 template SI_TEMPLATE_CLASS
00316 Image<INT> segmentImageMC2<SI_TEMPLATE>::SIcreateMother(const Image<INT> &img) const
00317 {
00318   Image<INT> mother;
00319   mother.resize(img.getWidth(),img.getHeight(),ZEROS);
00320   for(int x = SI_frameX1; x < SI_frameX2; x++)
00321   {
00322     for(int y = SI_frameY1; y < SI_frameY2; y++)
00323     {
00324       if(img.getVal(x,y) != 0)
00325         mother.setVal(x,y,1);
00326       else
00327         mother.setVal(x,y,0);
00328     }
00329   }
00330   return mother;
00331 }
00332 
00333 
00334 
00335 
00336 template SI_TEMPLATE_CLASS
00337 Image<int> segmentImageMC2<SI_TEMPLATE>::SIreturnBlobs() const
00338 {
00339   return SI_blobID;
00340 }
00341 
00342 
00343 
00344 template SI_TEMPLATE_CLASS
00345 Image<bool> segmentImageMC2<SI_TEMPLATE>::SIreturnCandidates() const
00346 {
00347   return SI_candidatePixels;
00348 }
00349 
00350 
00351 
00352 template SI_TEMPLATE_CLASS
00353 Image<FLOAT> segmentImageMC2<SI_TEMPLATE>::SIreturnNormalizedCandidates() const
00354 {
00355   Image<FLOAT> NC;
00356   NC.resize(SI_candidatePixels.getWidth(),SI_candidatePixels.getHeight());
00357   for(int x = 0; x < SI_candidatePixels.getWidth(); x++)
00358   {
00359     for(int y = 0; y < SI_candidatePixels.getHeight(); y++)
00360     {
00361       if(SI_candidatePixels.getVal(x,y))
00362         NC.setVal(x,y,255);
00363       else
00364         NC.setVal(x,y,0);
00365     }
00366   }
00367   return NC;
00368 }
00369 
00370 
00371 
00372 template SI_TEMPLATE_CLASS
00373 Image<PixRGB<FLOAT> > segmentImageMC2<SI_TEMPLATE>::SIreturnWorkImage() const
00374 {
00375   ASSERT((SI_doType == 1) || (SI_doType == 2));
00376   return *SI_workImage;
00377 }
00378 
00379 
00380 
00381 template SI_TEMPLATE_CLASS
00382 INT segmentImageMC2<SI_TEMPLATE>::SInumberBlobs() const
00383 {
00384   return SI_totalBlobs;
00385 }
00386 
00387 
00388 
00389 template SI_TEMPLATE_CLASS
00390 std::vector<INT> segmentImageMC2<SI_TEMPLATE>::SIgetBlobMap() const
00391 {
00392   return SI_reOrderVec;
00393 }
00394 
00395 
00396 
00397 template SI_TEMPLATE_CLASS
00398 void segmentImageMC2<SI_TEMPLATE>::SIcalcMassCenter()
00399 {
00400 
00401   Image<int>::iterator iblobID           = SI_blobID.beginw();
00402   Image<bool>::iterator icandidatePixels = SI_candidatePixels.beginw();
00403 
00404   const ushort width  = (ushort)SI_candidatePixels.getWidth();
00405   const ushort height = (ushort)SI_candidatePixels.getHeight();
00406 
00407   for(ushort y = 0 ; y < height; y++)
00408   {
00409     for(ushort x = 0 ; x < width; x++)
00410     {
00411       if((*icandidatePixels) && (*iblobID != -1))
00412       {
00413         
00414         INT *indexBlob = &SI_reverseOrderVec[*iblobID];
00415         if(SI_reset[*indexBlob])
00416         {
00417           SI_reset[*indexBlob] = false;
00418           SI_Xsum[*indexBlob]  = x;
00419           SI_Ysum[*indexBlob]  = y;
00420           SI_mass[*indexBlob]  = 1;
00421           SI_xmin[*indexBlob]  = x;
00422           SI_ymin[*indexBlob]  = y;
00423           SI_xmax[*indexBlob]  = x;
00424           SI_ymax[*indexBlob]  = y;
00425         }
00426         else
00427         {
00428           SI_Xsum[*indexBlob] += x;
00429           SI_Ysum[*indexBlob] += y;
00430           SI_mass[*indexBlob]++;
00431 
00432           if(x <= SI_xmin[*indexBlob])
00433             SI_xmin[*indexBlob] = x;
00434           if(x >= SI_xmax[*indexBlob])
00435             SI_xmax[*indexBlob] = x;
00436           if(y <= SI_ymin[*indexBlob])
00437             SI_ymin[*indexBlob] = y;
00438           if(y >= SI_ymax[*indexBlob])
00439             SI_ymax[*indexBlob] = y;
00440         }
00441       }
00442       ++iblobID; ++icandidatePixels;
00443     }
00444   }
00445 
00446   for(INT b = 0; b < SI_totalBlobs; b++)
00447   {
00448     
00449     if(SI_mass[b] > 0)
00450     {
00451       SI_centerX[b] = SI_Xsum[b]/SI_mass[b];
00452       SI_centerY[b] = SI_Ysum[b]/SI_mass[b];
00453     }
00454   }
00455 }
00456 
00457 
00458 
00459 template SI_TEMPLATE_CLASS
00460 FLOAT segmentImageMC2<SI_TEMPLATE>::SIgetCenterX(const INT blob) const
00461 {
00462   return SI_centerX[blob];
00463 }
00464 
00465 
00466 
00467 template SI_TEMPLATE_CLASS
00468 FLOAT segmentImageMC2<SI_TEMPLATE>::SIgetCenterY(const INT blob) const
00469 {
00470   return SI_centerY[blob];
00471 }
00472 
00473 
00474 
00475 template SI_TEMPLATE_CLASS
00476 INT segmentImageMC2<SI_TEMPLATE>::SIgetMass(const INT blob) const
00477 {
00478   return SI_mass[blob];
00479 }
00480 
00481 
00482 
00483 template SI_TEMPLATE_CLASS
00484 int segmentImageMC2<SI_TEMPLATE>::SIgetXmin(const INT blob) const
00485 {
00486   return SI_xmin[blob];
00487 }
00488 
00489 
00490 
00491 template SI_TEMPLATE_CLASS
00492 int segmentImageMC2<SI_TEMPLATE>::SIgetXmax(const INT blob) const
00493 {
00494   return SI_xmax[blob];
00495 }
00496 
00497 
00498 
00499 template SI_TEMPLATE_CLASS
00500 int segmentImageMC2<SI_TEMPLATE>::SIgetYmin(const INT blob) const
00501 {
00502   return SI_ymin[blob];
00503 }
00504 
00505 
00506 
00507 template SI_TEMPLATE_CLASS
00508 int segmentImageMC2<SI_TEMPLATE>::SIgetYmax(const INT blob) const
00509 {
00510   return SI_ymax[blob];
00511 }
00512 
00513 
00514 
00515 template SI_TEMPLATE_CLASS
00516 int segmentImageMC2<SI_TEMPLATE>::SIgetImageSizeX() const
00517 {
00518   return SI_candidatePixels.getWidth();
00519 }
00520 
00521 
00522 
00523 template SI_TEMPLATE_CLASS
00524 int segmentImageMC2<SI_TEMPLATE>::SIgetImageSizeY() const
00525 {
00526   return SI_candidatePixels.getHeight();
00527 }
00528 
00529 
00530 template SI_TEMPLATE_CLASS inline
00531 void segmentImageMC2<SI_TEMPLATE>::SIgetValue(INT *blob,
00532                                       typename std::vector<FLOAT> *mean,
00533                                       typename std::vector<FLOAT> *std,
00534                                       INT *in)
00535 {
00536   typename std::vector<FLOAT>::iterator imean = mean->begin();
00537   typename std::vector<FLOAT>::iterator istd  = std->begin();
00538   typename std::vector<Image<FLOAT> >::iterator
00539     ifeatureMaps = SI_featureMaps->begin();
00540 
00541   bool dothis = true;
00542   *in = 0;
00543   for(INT i = 0; i < SI_featureMaps->size(); i++, ++imean, ++istd,
00544         ++ifeatureMaps)
00545   {
00546     Image<bool>::iterator icandidatePixels      = SI_candidatePixels.beginw();
00547     Image<int>::iterator iblobID               = SI_blobID.beginw();
00548     typename Image<FLOAT>::iterator iifeatureMaps = ifeatureMaps->beginw();
00549 
00550     FLOAT tot = 0;
00551     FLOAT ss = 0;
00552 
00553     while(icandidatePixels != SI_candidatePixels.endw())
00554     {
00555       if((*icandidatePixels) && (*iblobID != -1))
00556       {
00557         if(SI_reverseOrderVec[*iblobID] == *blob)
00558         {
00559           tot += *iifeatureMaps;
00560           ss += (pow(*iifeatureMaps,2))/SI_mass[*blob];
00561         }
00562       }
00563       ++icandidatePixels; ++iblobID; ++iifeatureMaps;
00564     }
00565     if(SI_mass[*blob] > 0)
00566     {
00567       *imean = tot/SI_mass[*blob];
00568       *istd = sqrt(fabs(ss - pow(*imean,2)));
00569       if(dothis == true)
00570         *in = SI_mass[*blob] + *in;
00571     }
00572     dothis = false;
00573   }
00574 }
00575 
00576 
00577 
00578 template SI_TEMPLATE_CLASS
00579 void segmentImageMC2<SI_TEMPLATE>::SIgetValueMean(INT *blobListSize,
00580                                           typename std::vector<INT> *blobList,
00581                                           typename std::vector<FLOAT> *mean,
00582                                           typename std::vector<FLOAT> *stdd,
00583                                           FLOAT *mass)
00584 {
00585   
00586   
00587   if(SI_count == SI_iter)
00588     SI_count = 0;
00589 
00590   INT SI_tempN;
00591 
00592   typename std::vector<INT>::iterator iN                   = SI_N.begin();
00593   typename std::vector<std::vector<FLOAT> >::iterator iavg = SI_avg.begin();
00594   typename std::vector<std::vector<FLOAT> >::iterator istd = SI_std.begin();
00595 
00596   typename std::vector<FLOAT> *pavg = &SI_avg[SI_count];
00597   typename std::vector<FLOAT> *pstd = &SI_std[SI_count];
00598   INT *pcount = &SI_N[SI_count];
00599   *pcount = 0;
00600 
00601   
00602   for(INT i = 0; i < *blobListSize; i++)
00603   {
00604     SIgetValue(&blobList->at(i), &SI_tempAvg, &SI_tempStd, &SI_tempN);
00605     *pcount = SI_tempN + (*pcount);
00606     for(INT f = 0; f < SI_featureMaps->size(); f++)
00607     {
00608       pavg->at(f) += SI_tempAvg[f]*SI_tempN;
00609       pstd->at(f) += SI_tempStd[f]*SI_tempN;
00610     }
00611   }
00612 
00613   for(INT f = 0; f < SI_featureMaps->size(); f++)
00614   {
00615     pavg->at(f) = pavg->at(f)/(*pcount);
00616     pstd->at(f) = pstd->at(f)/(*pcount);
00617   }
00618   *mass = *pcount;
00619   SI_count++;
00620 
00621   INT massSum = 0;
00622 
00623   
00624   for(INT c = 0; c < SI_iter; c++, ++iavg, ++istd, ++iN)
00625   {
00626     massSum += *iN;
00627     typename std::vector<FLOAT>::iterator iiavg = iavg->begin();
00628     typename std::vector<FLOAT>::iterator iistd = istd->begin();
00629     typename std::vector<FLOAT>::iterator imean = mean->begin();
00630     typename std::vector<FLOAT>::iterator istdd = stdd->begin();
00631 
00632     for(INT i = 0; i < SI_featureMaps->size(); i++, ++iiavg, ++iistd,
00633           ++imean, ++istdd)
00634     {
00635       if(*iN != 0)
00636       {
00637         *imean += *iiavg*(*iN);
00638         *istdd += *iistd*(*iN);
00639       }
00640     }
00641   }
00642 
00643   
00644   typename std::vector<FLOAT>::iterator imean = mean->begin();
00645   typename std::vector<FLOAT>::iterator istdd = stdd->begin();
00646   for(INT i = 0; i < SI_featureMaps->size(); i++, ++imean, ++istdd)
00647   {
00648     *imean = *imean/massSum;
00649     *istdd = *istdd/massSum;
00650   }
00651 }
00652 
00653 
00654 
00655 
00656 
00657 
00658 
00659 
00660 
00661 
00662 
00663 
00664 
00665 template SI_TEMPLATE_CLASS inline
00666 void segmentImageMC2<SI_TEMPLATE>::SIfindCandidates()
00667 {
00668   
00669   std::vector<int>::iterator imasterVec = SI_masterVec.begin();
00670 
00671   while(imasterVec != SI_masterVec.end())
00672     *imasterVec++ = -1;
00673 
00674   Image<bool>::iterator
00675     candidatePixelsIter    = SI_candidatePixels.beginw();
00676 
00677   Image<bool>::iterator
00678     preCandidatePixelsIter = SI_preCandidatePixels.beginw();
00679 
00680   
00681 
00682   while(candidatePixelsIter != SI_candidatePixels.endw())
00683   {
00684     if((*preCandidatePixelsIter) == true)
00685     {
00686       *candidatePixelsIter = true;
00687     }
00688     else
00689     {
00690       *candidatePixelsIter = false;
00691     }
00692     *preCandidatePixelsIter = true;
00693     ++candidatePixelsIter; ++preCandidatePixelsIter;
00694   }
00695 
00696   typename std::vector<Image<FLOAT> >::iterator ifeatureMaps;
00697   typename std::vector<FLOAT>::iterator ilowThresh  = SI_lowThresh.begin();
00698   typename std::vector<FLOAT>::iterator ihighThresh = SI_highThresh.begin();
00699   
00700 
00701   for(ifeatureMaps = SI_featureMaps->begin();
00702       ifeatureMaps !=  SI_featureMaps->end(); ++ifeatureMaps,
00703         ++ilowThresh, ++ihighThresh)
00704   {
00705     typename Image<FLOAT>::iterator iifeatureMaps = ifeatureMaps->beginw();
00706     preCandidatePixelsIter = SI_preCandidatePixels.beginw();
00707     candidatePixelsIter    = SI_candidatePixels.beginw();
00708 
00709     
00710 
00711     while(iifeatureMaps != ifeatureMaps->endw())
00712     {
00713       if((*iifeatureMaps > *ihighThresh) || (*iifeatureMaps < *ilowThresh))
00714       {
00715         *preCandidatePixelsIter = false;
00716         *candidatePixelsIter    = false;
00717       }
00718       
00719         
00720       ++preCandidatePixelsIter; ++candidatePixelsIter; ++iifeatureMaps;
00721     }
00722   }
00723 }
00724 
00725 
00726 
00727 
00728 
00729 
00730 
00731 template SI_TEMPLATE_CLASS inline
00732 void segmentImageMC2<SI_TEMPLATE>::SIfindCandidatesNoBandPass()
00733 {
00734   
00735   std::vector<int>::iterator imasterVec = SI_masterVec.begin();
00736 
00737   while(imasterVec != SI_masterVec.end())
00738     *imasterVec++ = -1;
00739 
00740   Image<bool>::iterator
00741     candidatePixelsIter    = SI_candidatePixels.beginw();
00742 
00743   
00744 
00745   while(candidatePixelsIter != SI_candidatePixels.endw())
00746   {
00747     *candidatePixelsIter = true;
00748     ++candidatePixelsIter;
00749   }
00750 
00751 
00752   typename std::vector<Image<FLOAT> >::iterator ifeatureMaps;
00753   typename std::vector<FLOAT>::iterator ilowThresh  = SI_lowThresh.begin();
00754   typename std::vector<FLOAT>::iterator ihighThresh = SI_highThresh.begin();
00755   
00756 
00757   for(ifeatureMaps = SI_featureMaps->begin();
00758       ifeatureMaps !=  SI_featureMaps->end(); ++ifeatureMaps,
00759         ++ilowThresh, ++ihighThresh)
00760   {
00761     typename Image<FLOAT>::iterator iifeatureMaps = ifeatureMaps->beginw();
00762     candidatePixelsIter = SI_candidatePixels.beginw();
00763 
00764     
00765 
00766     while(iifeatureMaps != ifeatureMaps->endw())
00767     {
00768       
00769       if((*iifeatureMaps > *ihighThresh) || (*iifeatureMaps < *ilowThresh))
00770         *candidatePixelsIter = false;
00771 
00772       ++candidatePixelsIter; ++iifeatureMaps;
00773     }
00774   }
00775 }
00776 
00777 
00778 
00779 
00780 
00781 template SI_TEMPLATE_CLASS inline
00782 void segmentImageMC2<SI_TEMPLATE>::SIremoveSingles()
00783 {
00784   Image<bool>::iterator icandidatePixels = SI_candidatePixels.beginw();
00785 
00786   const int width  = SI_candidatePixels.getWidth();
00787   const int height = SI_candidatePixels.getHeight();
00788   for(int y = 0; y < height; y++)
00789   {
00790     for(int x = 0; x < width; x++)
00791     {
00792       if(*icandidatePixels)
00793       {
00794         unsigned int kill = 0;
00795         const int XLeft   = x - 1;
00796         const int XRight  = x + 1;
00797         const int YTop    = y - 1;
00798         const int YBottom = y + 1;
00799         if((XLeft >= 0) && (SI_candidatePixels.getVal(XLeft,y)))
00800           kill++;
00801         if((XRight < width)
00802            && (SI_candidatePixels.getVal(XRight,y)))
00803           kill++;
00804         if((YTop >= 0) && (SI_candidatePixels.getVal(x,YTop)))
00805           kill++;
00806         if((YBottom < height)
00807            && (SI_candidatePixels.getVal(x,YBottom)))
00808           kill++;
00809         if(kill < SI_killVal)
00810           *icandidatePixels = false;
00811       }
00812       ++icandidatePixels;
00813     }
00814   }
00815 }
00816 
00817 
00818 
00819 
00820 
00821 template SI_TEMPLATE_CLASS inline
00822 void segmentImageMC2<SI_TEMPLATE>::SIremoveSinglesItr()
00823 {
00824   Image<bool>::iterator icandidatePixels = SI_candidatePixels.beginw();
00825 
00826   const unsigned int width  = SI_candidatePixels.getWidth();
00827   const unsigned int height = SI_candidatePixels.getHeight();
00828 
00829   
00830   
00831   Image<bool>::iterator icandidatePixelsTop    =
00832     SI_candidatePixels.beginw() - width;
00833   Image<bool>::iterator icandidatePixelsBottom =
00834     SI_candidatePixels.beginw() + width;
00835   Image<bool>::iterator icandidatePixelsLeft   =
00836     SI_candidatePixels.beginw() - 1;
00837   Image<bool>::iterator icandidatePixelsRight  =
00838     SI_candidatePixels.beginw() + 1;
00839 
00840   for(unsigned int y = 0; y < height; y++)
00841   {
00842     for(unsigned int x = 0; x < width; x++)
00843     {
00844       if(*icandidatePixels)
00845       {
00846         unsigned int kill = 0;
00847         if(x != 0)
00848           if(*icandidatePixelsLeft)
00849             kill++;
00850         if(x < width - 1)
00851           if(*icandidatePixelsRight)
00852             kill++;
00853         if(y != 0)
00854           if(*icandidatePixelsTop)
00855             kill++;
00856         if(y < height - 1)
00857           if(*icandidatePixelsBottom)
00858             kill++;
00859         if(kill < SI_killVal)
00860           *icandidatePixels = false;
00861       }
00862 
00863       ++icandidatePixels;
00864       ++icandidatePixelsBottom; ++icandidatePixelsRight;
00865       ++icandidatePixelsTop;    ++icandidatePixelsLeft;
00866     }
00867   }
00868 }
00869 
00870 
00871 
00872 
00873 
00874 
00875 template SI_TEMPLATE_CLASS inline
00876 void segmentImageMC2<SI_TEMPLATE>::SIdiscreteLinking()
00877 {
00878   const ushort width    = (ushort)SI_candidatePixels.getWidth();
00879   const ushort height   = (ushort)SI_candidatePixels.getHeight();
00880   bool trace            = false;
00881   INT pixID             = 0;
00882   SI_maxIDVal           = 1;
00883   SI_masters            = 1;
00884   SI_mastersCount       = 0;
00885   int lastNeighbor;
00886 
00887   for(ushort x = 0; x < width; x++)
00888   {
00889     trace        = false;
00890     lastNeighbor = -2;
00891     for(ushort y = 0; y < height; y++)
00892     {
00893       if(SI_candidatePixels.getVal(x,y))
00894       {
00895         if(!trace)
00896         {
00897           pixID++;
00898           trace        = true;
00899           lastNeighbor = -2;
00900         }
00901         SI_blobID.setVal(x,y,pixID);
00902         if(x > 0) 
00903         {
00904           if(SI_candidatePixels.getVal(x-1,y))
00905           {
00906             
00907             const INT check =  SI_blobID.getVal((x-1),y);
00908             if((signed)check != lastNeighbor)
00909             {
00910               SIbackwardLink(pixID,check);
00911               lastNeighbor = check;
00912             }
00913             else
00914             {
00915               SIbasicLink(pixID);
00916             }
00917           }
00918           else
00919           {
00920             lastNeighbor = -2;
00921             SIbasicLink(pixID);
00922           }
00923         }
00924         else
00925         {
00926           SIbasicLink(pixID);
00927         }
00928       }
00929       else
00930       {
00931         trace        = false;
00932         SI_blobID.setVal(x,y,0);
00933         lastNeighbor = -2;
00934       }
00935     }
00936   }
00937   LINFO("Candidate pixels recognized %d",pixID);
00938   SI_num = pixID;
00939 }
00940 
00941 
00942 
00943 
00944 
00945 
00946 template SI_TEMPLATE_CLASS inline
00947 void segmentImageMC2<SI_TEMPLATE>::SIdiscreteLinkingOrtho()
00948 {
00949   const int width       = SI_candidatePixels.getWidth();
00950   const int height      = SI_candidatePixels.getHeight();
00951   bool trace            = false;
00952   INT pixID             = 0;
00953   SI_maxIDVal           = 1;
00954   SI_masters            = 1;
00955   SI_mastersCount       = 0;
00956   int lastNeighbor;
00957 
00958   Image<bool>::iterator candidatePixelsItr = SI_candidatePixels.beginw();
00959   Image<int>::iterator  blobIDItr          = SI_blobID.beginw();
00960 
00961   for(int y = 0; y < height; y++)
00962   {
00963     trace        = false;
00964     lastNeighbor = -2;
00965     for(int x = 0; x < width; x++)
00966     {
00967       
00968       if(*candidatePixelsItr++)
00969       {
00970         
00971         if(!trace)
00972         {
00973           pixID++;
00974           trace        = true;
00975           lastNeighbor = -2;
00976         }
00977         
00978         *blobIDItr++ = pixID;
00979         if(y > 0) 
00980         {
00981           
00982           if(*(candidatePixelsItr - (1 + width)))
00983           {
00984             
00985             
00986             const INT check = *(blobIDItr - (1 + width));
00987             if((signed)check != lastNeighbor)
00988             {
00989               SIbackwardLink(pixID,check);
00990               lastNeighbor = check;
00991             }
00992             else
00993             {
00994               SIbasicLink(pixID);
00995             }
00996           }
00997           else
00998           {
00999             lastNeighbor = -2;
01000             SIbasicLink(pixID);
01001           }
01002         }
01003         else
01004         {
01005           SIbasicLink(pixID);
01006         }
01007       }
01008       else
01009       {
01010         trace        = false;
01011         
01012         *blobIDItr++ = 0;
01013         lastNeighbor = -2;
01014       }
01015     }
01016   }
01017   
01018   SI_num = pixID;
01019 }
01020 
01021 
01022 
01023 
01024 
01025 
01026 
01027 template SI_TEMPLATE_CLASS inline
01028 void segmentImageMC2<SI_TEMPLATE>::SIbackwardLink(const INT slave,
01029                                                   const INT master)
01030 {
01031   if(master > SI_maxIDVal)
01032     SI_maxIDVal = master;
01033   if(slave > SI_maxIDVal)
01034     SI_maxIDVal = slave;
01035 
01036   
01037   if(SI_masterVec[master] == -1)
01038   {
01039     
01040     if(SI_masterVec[slave] == -1)
01041     {
01042       
01043       SI_masterVec[master] = SI_masters;
01044       SI_masterVec[slave]  = SI_masters;
01045       SI_masters++;
01046       SI_mastersCount++;
01047     }
01048     
01049     else
01050     {
01051       
01052       SI_masterVec[master] = SI_masterVec[slave];
01053     }
01054   }
01055   
01056   else
01057   {
01058     
01059     if(SI_masterVec[slave] == -1)
01060     {
01061       
01062       SI_masterVec[slave] = SI_masterVec[master];
01063     }
01064     
01065     else
01066     {
01067       
01068 
01069       std::vector<int>::iterator masterVecItr = SI_masterVec.begin();
01070       for(INT i = 0; i <= SI_maxIDVal; i++, ++masterVecItr)
01071       {
01072         if(*masterVecItr == SI_masterVec[slave])
01073         {
01074           
01075           *masterVecItr = SI_masterVec[master];
01076         }
01077       }
01078       SI_masterVec[slave] = SI_masterVec[master];
01079       SI_mastersCount--;
01080     }
01081   }
01082 }
01083 
01084 
01085 template SI_TEMPLATE_CLASS inline
01086 void segmentImageMC2<SI_TEMPLATE>::SIbasicLink(const INT node)
01087 {
01088   if(node > SI_maxIDVal)
01089     SI_maxIDVal = node;
01090 
01091   
01092   if(SI_masterVec[node] == -1)
01093   {
01094     
01095     SI_masterVec[node] = SI_masters;
01096     SI_masters++;
01097     SI_mastersCount++;
01098   }
01099 }
01100 
01101 
01102 
01103 template SI_TEMPLATE_CLASS inline
01104 void segmentImageMC2<SI_TEMPLATE>::SIcombine()
01105 {
01106   SI_totalBlobs = 0;
01107 
01108   Image<bool>::iterator candidatePixelsItr = SI_candidatePixels.beginw();
01109   Image<int>::iterator  blobIDItr          = SI_blobID.beginw();
01110 
01111   while(candidatePixelsItr != SI_candidatePixels.endw())
01112   {
01113     if(*candidatePixelsItr++)
01114       *blobIDItr = SI_masterVec[*blobIDItr];
01115     blobIDItr++;
01116   }
01117 
01118   
01119 
01120 
01121 
01122 
01123 
01124 
01125 
01126 
01127 
01128 
01129   std::vector<int>::iterator masterVecItr           = SI_masterVec.begin();
01130   typename std::vector<INT>::iterator reOrderVecItr = SI_reOrderVec.begin();
01131   std::vector<bool>::iterator resetItr              = SI_reset.begin();
01132 
01133   for(INT x = 0; x < SI_num; x++, ++masterVecItr)
01134   {
01135     bool add = true;
01136     
01137     for(INT y = 0; y < SI_totalBlobs; y++)
01138     {
01139       if((int)SI_reOrderVec[y] == *masterVecItr)
01140         add = false;
01141     }
01142 
01143     if((add) && (*masterVecItr != -1))
01144     {
01145       
01146       *reOrderVecItr = *masterVecItr;
01147       SI_reverseOrderVec[*masterVecItr] = SI_totalBlobs;
01148       *resetItr = true;
01149       SI_totalBlobs++; ++reOrderVecItr; ++resetItr;
01150     }
01151   }
01152 }
01153 
01154 
01155 
01156 template SI_TEMPLATE_CLASS inline
01157 void segmentImageMC2<SI_TEMPLATE>::SIdoSegment()
01158 {
01159   ASSERT(SI_set1); ASSERT(SI_set2); ASSERT(SI_set3); ASSERT(SI_set4);
01160   
01161   if(SI_useCandidateBandPass == true)
01162     SIfindCandidates();
01163   else
01164     SIfindCandidatesNoBandPass();
01165   
01166   if(SI_removeSingles == true)
01167   {
01168     
01169     SIremoveSinglesItr();
01170   }
01171   
01172   
01173   SIdiscreteLinkingOrtho();
01174   
01175   SIcombine();
01176   
01177 }
01178 
01179 #undef SI_TEMPLATE_CLASS
01180 #undef SI_TEMPLATE
01181 
01182 template class segmentImageMC2<float, unsigned int, 1>;
01183 template class segmentImageMC2<float, unsigned int, 2>;
01184 template class segmentImageMC2<float, unsigned int, 3>;
01185 template class segmentImageMC2<float, unsigned int, 4>;
01186 
01187 
01188 
01189 
01190 
01191 
01192 
01193 #endif