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