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