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 #include "VFAT/segmentImage2.H"
00039
00040 #include "Util/Assert.H"
00041 #include <iostream>
00042 #include <vector>
00043 #include <cstdio>
00044 #include <cstdlib>
00045
00046
00047
00048
00049
00050
00051
00052 void segmentImage2::SIfindCandidatesRGB()
00053 {
00054 PixRGB<float> pix;
00055
00056 for(unsigned int x = 0; x < SI_masterVec.size(); x++)
00057 SI_masterVec[x] = -1;
00058
00059 for(int x = SI_frameX1; x < SI_frameX2; x++)
00060 {
00061 for(int y = SI_frameY1; y < SI_frameY2; y++)
00062 {
00063 pix = SI_workImage.getVal(x,y);
00064 SI_candidatePixels.setVal(x,y,false);
00065
00066
00067 if ((pix.red() < SI_redUT) &&
00068 (pix.green() < SI_greenUT) &&
00069 (pix.blue() < SI_blueUT) &&
00070 (pix.red() > SI_redLT) &&
00071 (pix.green() > SI_greenLT) &&
00072 (pix.blue() > SI_blueLT))
00073 {
00074 SI_candidatePixels.setVal(x,y,true);
00075
00076 }
00077 }
00078 }
00079 }
00080
00081
00082
00083
00084
00085 void segmentImage2::SIfindCandidatesHSV()
00086 {
00087 PixRGB<float> pix;
00088
00089 for(unsigned int x = 0; x < SI_masterVec.size(); x++)
00090 SI_masterVec[x] = -1;
00091
00092 bool modu = false;
00093 double HmoduL = SI_HLT;
00094 double HmoduU = SI_HUT;
00095
00096 if(SI_HLT < 0)
00097 {
00098 modu = true;
00099 HmoduL = 360.0F + SI_HLT;
00100 }
00101
00102
00103
00104
00105 else if(SI_HUT > 360)
00106 {
00107 modu = true;
00108 HmoduU = SI_HUT - 360.0F;
00109 }
00110
00111 Image<PixRGB<float> >::iterator
00112 workImageIter = SI_workImage.beginw() + SI_frameX1 +
00113 (SI_frameY1*SI_workImage.getWidth());
00114 Image<bool>::iterator
00115 candidatePixelsIter = SI_candidatePixels.beginw() + SI_frameX1 +
00116 (SI_frameY1*SI_workImage.getWidth());
00117 Image<bool>::iterator
00118 preCandidatePixelsIter = SI_preCandidatePixels.beginw() + SI_frameX1 +
00119 (SI_frameY1*SI_workImage.getWidth());
00120
00121 int jump = SI_frameX1 + (SI_workImage.getWidth()-SI_frameX2);
00122
00123 for(int y = SI_frameY1; y < SI_frameY2; y++)
00124 {
00125 for(int x = SI_frameX1; x < SI_frameX2; x++)
00126 {
00127 float pixH,pixS,pixV;
00128 pix = (*workImageIter);
00129 PixHSV<float>(pix).getHSV(pixH,pixS,pixV);
00130 *candidatePixelsIter = false;
00131
00132
00133
00134
00135 if ((pixS < SI_SUT) &&
00136 (pixV < SI_VUT) &&
00137 (pixS > SI_SLT) &&
00138 (pixV > SI_VLT))
00139 {
00140
00141
00142 if(((modu == false) && (pixH < SI_HUT) && (pixH > SI_HLT)) ||
00143 ((modu == true) && (!((pixH > HmoduU) && (pixH < HmoduL)))))
00144 {
00145
00146 if((*preCandidatePixelsIter) == true)
00147 {
00148
00149 *candidatePixelsIter = true;
00150 }
00151 *preCandidatePixelsIter = true;
00152 }
00153 else
00154 {
00155
00156 *preCandidatePixelsIter = false;
00157 }
00158 }
00159 ++workImageIter; ++candidatePixelsIter; ++preCandidatePixelsIter;
00160 }
00161 workImageIter = workImageIter + jump;
00162 candidatePixelsIter = candidatePixelsIter + jump;
00163 preCandidatePixelsIter = preCandidatePixelsIter + jump;
00164 }
00165 }
00166
00167
00168
00169
00170
00171
00172 void segmentImage2::SIfindCandidatesGREY()
00173 {
00174 float pix;
00175
00176 for(unsigned int x = 0; x < SI_masterVec.size(); x++)
00177 SI_masterVec[x] = -1;
00178
00179 for(int x = SI_frameX1; x < SI_frameX2; x++)
00180 {
00181 for(int y = SI_frameY1; y < SI_frameY2; y++)
00182 {
00183 pix = SI_workImageGREY.getVal(x,y);
00184 SI_candidatePixels.setVal(x,y,false);
00185
00186
00187 if ((pix < SI_VUT) && (pix > SI_VLT))
00188 {
00189 SI_candidatePixels.setVal(x,y,true);
00190 }
00191 }
00192 }
00193 }
00194
00195
00196
00197
00198
00199 void segmentImage2::SIremoveSingles()
00200 {
00201 for(int x = SI_frameX1; x < SI_frameX2; x++)
00202 {
00203 for(int y = SI_frameY1; y < SI_frameY2; y++)
00204 {
00205 if(SI_candidatePixels.getVal(x,y))
00206 {
00207 int kill = 0;
00208 int XLeft = x - 1;
00209 int XRight = x + 1;
00210 int YTop = y - 1;
00211 int YBottom = y + 1;
00212 if((XLeft >= 0) && (SI_candidatePixels.getVal(XLeft,y)))
00213 kill++;
00214 if((XRight < SI_candidatePixels.getWidth())
00215 && (SI_candidatePixels.getVal(XRight,y)))
00216 kill++;
00217 if((YTop >= 0) && (SI_candidatePixels.getVal(x,YTop)))
00218 kill++;
00219 if((YBottom < SI_candidatePixels.getHeight())
00220 && (SI_candidatePixels.getVal(x,YBottom)))
00221 kill++;
00222 if(kill < 2)
00223 SI_candidatePixels.setVal(x,y,false);
00224 }
00225 }
00226 }
00227 }
00228
00229
00230
00231
00232
00233
00234 void segmentImage2::SIdiscreteLinking()
00235 {
00236
00237 bool trace = false;
00238 long pixID = 0;
00239 long lastNeighbor;
00240 SI_masters = 0;
00241 SI_mastersCount = 0;
00242 for(int x = SI_frameX1; x < SI_frameX2; x++)
00243 {
00244 trace = false;
00245 lastNeighbor = -2;
00246 for(int y = SI_frameY1; y < SI_frameY2; y++)
00247 {
00248 if(SI_candidatePixels.getVal(x,y))
00249 {
00250 if(!trace)
00251 {
00252 pixID++;
00253 trace = true;
00254 lastNeighbor = -2;
00255 }
00256 SI_blobID.setVal(x,y,pixID);
00257 if((x-1) > SI_frameX1)
00258 {
00259 if(SI_candidatePixels.getVal(x-1,y))
00260 {
00261
00262 long check = SI_blobID.getVal((x-1),y);
00263 if(check != lastNeighbor)
00264 {
00265 SIbackwardLink(pixID,check);
00266 lastNeighbor = check;
00267 }
00268 }
00269 else
00270 {
00271 lastNeighbor = -2;
00272 }
00273 }
00274 else
00275 {
00276 SIbackwardLink(pixID,pixID);
00277 }
00278 }
00279 else
00280 {
00281 trace = false;
00282 SI_blobID.setVal(x,y,0);
00283 lastNeighbor = -2;
00284 }
00285 }
00286 }
00287
00288
00289 SI_num = pixID;
00290 }
00291
00292
00293
00294
00295
00296
00297
00298 void segmentImage2::SIbackwardLink(long slave, long master)
00299 {
00300 long *masterVecMaster = &SI_masterVec[master];
00301 long *masterVecSlave = &SI_masterVec[slave];
00302
00303 if(*masterVecMaster == -1)
00304 {
00305
00306 if(*masterVecSlave == -1)
00307 {
00308
00309 *masterVecMaster = SI_masters;
00310 *masterVecSlave = SI_masters;
00311 SI_masters++;
00312 SI_mastersCount++;
00313 }
00314
00315 else
00316 {
00317
00318 *masterVecMaster = *masterVecSlave;
00319 }
00320 }
00321
00322 else
00323 {
00324
00325 if(*masterVecSlave == -1)
00326 {
00327
00328 *masterVecSlave = *masterVecMaster;
00329 }
00330
00331 else
00332 {
00333
00334 SI_mastersCount--;
00335 for(int i = 0; i < slave; i++)
00336 {
00337 if(SI_masterVec[i] == *masterVecMaster)
00338 {
00339
00340 SI_masterVec[i] = *masterVecSlave;
00341 }
00342 }
00343 }
00344 }
00345 }
00346
00347
00348
00349 void segmentImage2::SIcombine()
00350 {
00351 SI_totalBlobs = 0;
00352 for(int x = SI_frameX1; x < SI_frameX2; x++)
00353 {
00354 for(int y = SI_frameY1; y < SI_frameY2; y++)
00355 {
00356 if(SI_candidatePixels.getVal(x,y))
00357 {
00358 SI_blobID.setVal(x,y,SI_masterVec[SI_blobID.getVal(x,y)]);
00359 }
00360 }
00361 }
00362 for(int x = 0; x < SI_num; x++)
00363 {
00364 bool add = true;
00365
00366 for(int y = 0; y < SI_totalBlobs; y++)
00367 {
00368 if(SI_reOrderVec[y] == SI_masterVec[x])
00369 add = false;
00370 }
00371
00372 if((add) && (SI_masterVec[x] != -1))
00373 {
00374
00375 SI_reOrderVec[SI_totalBlobs] = SI_masterVec[x];
00376 SI_reverseOrderVec[SI_masterVec[x]] = SI_totalBlobs;
00377 SI_reset[SI_totalBlobs] = true;
00378 SI_totalBlobs++;
00379 }
00380 }
00381
00382 }
00383
00384 void segmentImage2::SIdoSegment()
00385 {
00386
00387 if(SI_doType == 1)
00388 {
00389 ASSERT(SI_set1); ASSERT(SI_set2); ASSERT(SI_set3); ASSERT(SI_set4);
00390 SIfindCandidatesRGB();
00391 }
00392 if(SI_doType == 2)
00393 {
00394 ASSERT(SI_set1); ASSERT(SI_set2); ASSERT(SI_set3); ASSERT(SI_set4);
00395 SIfindCandidatesHSV();
00396 }
00397 if(SI_doType == 3)
00398 {
00399 ASSERT(SI_set3); ASSERT(SI_set4);
00400 SIfindCandidatesGREY();
00401 }
00402
00403 SIremoveSingles();
00404
00405 SIdiscreteLinking();
00406
00407 SIcombine();
00408
00409 }
00410
00411
00412
00413
00414
00415 segmentImage2::segmentImage2(int imageType)
00416 {
00417 SI_doType = imageType;
00418 SI_set1 = false; SI_set2 = false; SI_set3 = false; SI_set4 = false;
00419 LINFO("CREATED");
00420 }
00421
00422 segmentImage2::segmentImage2()
00423 {
00424 SI_doType = HSV;
00425 SI_set1 = false; SI_set2 = false; SI_set3 = false; SI_set4 = false;
00426 LINFO("CREATED");
00427 }
00428
00429 segmentImage2::~segmentImage2()
00430 {}
00431
00432
00433
00434
00435
00436 void segmentImage2::SIsetRed(int val, int thresh = 1, int skew = 0)
00437 {
00438 ASSERT(SI_doType == 1);
00439 SI_red = val;
00440 if(skew <= 0)
00441 {
00442 SI_redLT = val - thresh + skew;
00443 SI_redUT = val + thresh;
00444 }
00445 else
00446 {
00447 SI_redLT = val - thresh;
00448 SI_redUT = val + thresh + skew;
00449 }
00450 SI_set1 = true;
00451 }
00452
00453 void segmentImage2::SIsetGreen(int val, int thresh = 1, int skew = 0)
00454 {
00455 ASSERT(SI_doType == 1);
00456 SI_green = val;
00457 if(skew <= 0)
00458 {
00459 SI_greenLT = val - thresh + skew;
00460 SI_greenUT = val + thresh;
00461 }
00462 else
00463 {
00464 SI_greenLT = val - thresh;
00465 SI_greenUT = val + thresh + skew;
00466 }
00467 SI_set2 = true;
00468 }
00469
00470 void segmentImage2::SIsetBlue(int val, int thresh = 1, int skew = 0)
00471 {
00472 ASSERT(SI_doType == 1);
00473 SI_blue = val;
00474 if(skew <= 0)
00475 {
00476 SI_blueLT = val - thresh + skew;
00477 SI_blueUT = val + thresh;
00478 }
00479 else
00480 {
00481 SI_blueLT = val - thresh;
00482 SI_blueUT = val + thresh + skew;
00483 }
00484 SI_set3 = true;
00485 }
00486
00487 void segmentImage2::SIsetHue(double val, double thresh = 1, double skew = 0)
00488 {
00489 ASSERT(SI_doType == 2);
00490 SI_H = val;
00491 if(skew <= 0)
00492 {
00493 SI_HLT = val - thresh + skew;
00494 SI_HUT = val + thresh;
00495 }
00496 else
00497 {
00498 SI_HLT = val - thresh;
00499 SI_HUT = val + thresh + skew;
00500 }
00501 SI_set1 = true;
00502 }
00503
00504 void segmentImage2::SIsetSat(double val, double thresh = 1, double skew = 0)
00505 {
00506 ASSERT(SI_doType == 2);
00507 SI_S = val;
00508 if(skew <= 0)
00509 {
00510 SI_SLT = val - thresh + skew;
00511 SI_SUT = val + thresh;
00512 }
00513 else
00514 {
00515 SI_SLT = val - thresh;
00516 SI_SUT = val + thresh + skew;
00517 }
00518 SI_set2 = true;
00519 }
00520
00521 void segmentImage2::SIsetVal(double val, double thresh = 1, double skew = 0)
00522 {
00523 ASSERT((SI_doType == 2) || (SI_doType == 3));
00524 SI_V = val;
00525 if(skew <= 0)
00526 {
00527 SI_VLT = val - thresh + skew;
00528 SI_VUT = val + thresh;
00529 }
00530 else
00531 {
00532 SI_VLT = val - thresh;
00533 SI_VUT = val + thresh + skew;
00534 }
00535 SI_set3 = true;
00536 }
00537
00538
00539
00540 void segmentImage2::SIsetFrame(int x1, int y1, int x2, int y2,
00541 int realX, int realY)
00542 {
00543 SI_frameX1 = x1;
00544 SI_frameX2 = x2;
00545 SI_frameY1 = y1;
00546 SI_frameY2 = y2;
00547 SI_masterVec.resize(((x2-x1)*(y2-y1)),-1);
00548 SI_reOrderVec.resize(((x2-x1)*(y2-y1)));
00549 SI_reverseOrderVec.resize(((x2-x1)*(y2-y1)));
00550 SI_centerX.resize(((x2-x1)*(y2-y1)));
00551 SI_centerY.resize(((x2-x1)*(y2-y1)));
00552 SI_Xsum.resize(((x2-x1)*(y2-y1)));
00553 SI_Ysum.resize(((x2-x1)*(y2-y1)));
00554 SI_mass.resize(((x2-x1)*(y2-y1)));
00555 SI_xmin.resize(((x2-x1)*(y2-y1)));
00556 SI_xmax.resize(((x2-x1)*(y2-y1)));
00557 SI_ymin.resize(((x2-x1)*(y2-y1)));
00558 SI_ymax.resize(((x2-x1)*(y2-y1)));
00559 SI_reset.resize(((x2-x1)*(y2-y1)));
00560 LINFO("SETTING WIDTH %d, HEIGHT %d",realX,realY);
00561 SI_blobID.resize(realX,realY,-1);
00562 SI_candidatePixels.resize(realX,realY,false);
00563 SI_preCandidatePixels.resize(realX,realY,false);
00564 SI_set4 = true;
00565 }
00566
00567 void segmentImage2::SIsetHSVavg(long doAvg)
00568 {
00569 SI_Havg.resize(doAvg,0);
00570 SI_Savg.resize(doAvg,0);
00571 SI_Vavg.resize(doAvg,0);
00572 SI_Hstdd.resize(doAvg,0);
00573 SI_Sstdd.resize(doAvg,0);
00574 SI_Vstdd.resize(doAvg,0);
00575 SI_HSVN.resize(doAvg,0);
00576 SI_HSViter = doAvg;
00577 SI_HSVcount = 0;
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 void segmentImage2::SIsegment(Image<PixRGB<float> > &image)
00590 {
00591 double micros;
00592 struct timezone tz;
00593 struct timeval start, stop;
00594 tz.tz_minuteswest = 0;
00595 tz.tz_dsttime = 0;
00596 gettimeofday(&start, &tz);
00597
00598 SI_workImage.resize(1,1);
00599 SI_workImage = lowPass5(image);
00600
00601 SIdoSegment();
00602
00603 gettimeofday(&stop,&tz);
00604 micros = stop.tv_usec - start.tv_usec;
00605 LINFO("%.1f Microseconds to segment\n", micros);
00606
00607
00608 }
00609
00610 void segmentImage2::SIsegment(Image<float> &image)
00611 {
00612 struct timezone tz;
00613 struct timeval start, stop;
00614 tz.tz_minuteswest = 0;
00615 tz.tz_dsttime = 0;
00616 gettimeofday(&start, &tz);
00617
00618 SI_workImageGREY.resize(1,1);
00619 SI_workImageGREY = lowPass5(image);
00620
00621 SIdoSegment();
00622
00623 gettimeofday(&stop,&tz);
00624
00625
00626 }
00627
00628
00629
00630
00631
00632 Image<long> segmentImage2::SIcreateMother(Image<long> &img)
00633 {
00634 Image<long> mother;
00635 mother.resize(img.getWidth(),img.getHeight(),ZEROS);
00636 for(int x = SI_frameX1; x < SI_frameX2; x++)
00637 {
00638 for(int y = SI_frameY1; y < SI_frameY2; y++)
00639 {
00640 if(img.getVal(x,y) != 0)
00641 mother.setVal(x,y,1);
00642 else
00643 mother.setVal(x,y,0);
00644 }
00645 }
00646 return mother;
00647 }
00648
00649
00650
00651
00652 Image<long> segmentImage2::SIreturnBlobs()
00653 {
00654 return SI_blobID;
00655 }
00656
00657 Image<bool> segmentImage2::SIreturnCandidates()
00658 {
00659 return SI_candidatePixels;
00660 }
00661
00662 Image<float> segmentImage2::SIreturnNormalizedCandidates()
00663 {
00664 Image<float> NC;
00665 NC.resize(SI_candidatePixels.getWidth(),SI_candidatePixels.getHeight());
00666 for(int x = 0; x < SI_candidatePixels.getWidth(); x++)
00667 {
00668 for(int y = 0; y < SI_candidatePixels.getHeight(); y++)
00669 {
00670 if(SI_candidatePixels.getVal(x,y))
00671 NC.setVal(x,y,255.0F);
00672 else
00673 NC.setVal(x,y,0.0F);
00674 }
00675 }
00676 return NC;
00677 }
00678
00679 Image<PixRGB<float> > segmentImage2::SIreturnWorkImage()
00680 {
00681 ASSERT((SI_doType == 1) || (SI_doType == 2));
00682 return SI_workImage;
00683 }
00684
00685 Image<float> segmentImage2::SIreturnWorkImageGREY()
00686 {
00687 ASSERT(SI_doType == 3);
00688 return SI_workImageGREY;
00689 }
00690
00691
00692 int segmentImage2::SInumberBlobs()
00693 {
00694 return SI_totalBlobs;
00695 }
00696
00697 std::vector<long> segmentImage2::SIgetBlobMap()
00698 {
00699 return SI_reOrderVec;
00700 }
00701
00702 void segmentImage2::SIcalcMassCenter()
00703 {
00704 for(int x = SI_frameX1; x < SI_frameX2; x++)
00705 {
00706 for(int y = SI_frameY1; y < SI_frameY2; y++)
00707 {
00708 if((SI_candidatePixels.getVal(x,y)) && (SI_blobID.getVal(x,y) != -1))
00709 {
00710
00711 long *indexBlob = &SI_reverseOrderVec[SI_blobID.getVal(x,y)];
00712 if(SI_reset[*indexBlob])
00713 {
00714 SI_reset[*indexBlob] = false;
00715 SI_Xsum[*indexBlob] = x;
00716 SI_Ysum[*indexBlob] = y;
00717 SI_mass[*indexBlob] = 1;
00718 SI_xmin[*indexBlob] = x;
00719 SI_ymin[*indexBlob] = y;
00720 SI_xmax[*indexBlob] = x;
00721 SI_ymax[*indexBlob] = y;
00722 }
00723 else
00724 {
00725 SI_Xsum[*indexBlob] += x;
00726 SI_Ysum[*indexBlob] += y;
00727 SI_mass[*indexBlob]++;
00728 if(x <= SI_xmin[*indexBlob])
00729 SI_xmin[*indexBlob] = x;
00730 if(x >= SI_xmax[*indexBlob])
00731 SI_xmax[*indexBlob] = x;
00732 if(y <= SI_ymin[*indexBlob])
00733 SI_ymin[*indexBlob] = y;
00734 if(y >= SI_ymax[*indexBlob])
00735 SI_ymax[*indexBlob] = y;
00736 }
00737 }
00738 }
00739 }
00740
00741 for(int x = 0; x < SI_totalBlobs; x++)
00742 {
00743
00744 if(SI_mass[x] > 0)
00745 {
00746 SI_centerX[x] = SI_Xsum[x]/SI_mass[x];
00747 SI_centerY[x] = SI_Ysum[x]/SI_mass[x];
00748 }
00749 }
00750 }
00751
00752 float segmentImage2::SIgetCenterX(long blob)
00753 {
00754 return SI_centerX[blob];
00755 }
00756
00757 float segmentImage2::SIgetCenterY(long blob)
00758 {
00759 return SI_centerY[blob];
00760 }
00761
00762 long segmentImage2::SIgetMass(long blob)
00763 {
00764 return SI_mass[blob];
00765 }
00766
00767 int segmentImage2::SIgetXmin(long blob)
00768 {
00769 return SI_xmin[blob];
00770 }
00771
00772
00773
00774 int segmentImage2::SIgetXmax(long blob)
00775 {
00776 return SI_xmax[blob];
00777 }
00778
00779
00780
00781 int segmentImage2::SIgetYmin(long blob)
00782 {
00783 return SI_ymin[blob];
00784 }
00785
00786
00787
00788 int segmentImage2::SIgetYmax(long blob)
00789 {
00790 return SI_ymax[blob];
00791 }
00792
00793
00794 int segmentImage2::SIgetImageSizeX()
00795 {
00796 return SI_candidatePixels.getWidth();
00797 }
00798
00799 int segmentImage2::SIgetImageSizeY()
00800 {
00801 return SI_candidatePixels.getHeight();
00802 }
00803
00804 void segmentImage2::SIgetHSVvalue(long blob, float *H, float *S, float *V,
00805 float *Hstd, float *Sstd, float *Vstd)
00806 {
00807 float totH = 0.0F, totS = 0.0F, totV = 0.0F;
00808 float ssH = 0.0F, ssS = 0.0F, ssV = 0.0F;
00809 PixRGB<float> pix;
00810 for(int x = SI_frameX1; x < SI_frameX2; x++)
00811 {
00812 for(int y = SI_frameY1; y < SI_frameY2; y++)
00813 {
00814 if((SI_candidatePixels.getVal(x,y)) && (SI_blobID.getVal(x,y) != -1))
00815 {
00816 if(SI_reverseOrderVec[SI_blobID.getVal(x,y)] == blob)
00817 {
00818 float pixH,pixS,pixV;
00819 pix = SI_workImage.getVal(x,y);
00820 PixHSV<float>(pix).getHSV(pixH,pixS,pixV);
00821 totH +=pixH; totS += pixS; totV += pixV;
00822 ssH += (pow(pixH,2))/SI_mass[blob];
00823 ssS += (pow(pixS,2))/SI_mass[blob];
00824 ssV += (pow(pixV,2))/SI_mass[blob];
00825 }
00826 }
00827 }
00828 }
00829 if(SI_mass[blob] > 0)
00830 {
00831 *H = totH/SI_mass[blob];
00832 *S = totS/SI_mass[blob];
00833 *V = totV/SI_mass[blob];
00834 *Hstd = sqrt(ssH - pow(*H,2));
00835 *Sstd = sqrt(ssS - pow(*S,2));
00836 *Vstd = sqrt(ssV - pow(*V,2));
00837 }
00838 }
00839
00840 void segmentImage2::SIgetHSVvalueMean(long blob, float *H, float *S, float *V,
00841 float *Hstd, float *Sstd, float *Vstd)
00842 {
00843 double massSum = 0;
00844 if(SI_HSVcount == SI_HSViter)
00845 SI_HSVcount = 0;
00846
00847 SIgetHSVvalue(blob, &SI_Havg[SI_HSVcount], &SI_Savg[SI_HSVcount],
00848 &SI_Vavg[SI_HSVcount], &SI_Hstdd[SI_HSVcount],
00849 &SI_Sstdd[SI_HSVcount], &SI_Vstdd[SI_HSVcount]);
00850
00851 SI_HSVN[SI_HSVcount] = SI_mass[blob];
00852 SI_HSVcount++;
00853 for(int i = 0; i < SI_HSViter; i++)
00854 {
00855 massSum += SI_HSVN[i];
00856 *H += SI_Havg[i]*SI_HSVN[i];
00857 *S += SI_Savg[i]*SI_HSVN[i];
00858 *V += SI_Vavg[i]*SI_HSVN[i];
00859 *Hstd += SI_Hstdd[i]*SI_HSVN[i];
00860 *Sstd += SI_Sstdd[i]*SI_HSVN[i];
00861 *Vstd += SI_Vstdd[i]*SI_HSVN[i];
00862 }
00863 if(massSum > 0)
00864 {
00865 *H = *H/massSum;
00866 *S = *S/massSum;
00867 *V = *V/massSum;
00868 *Hstd = *Hstd/massSum;
00869 *Sstd = *Sstd/massSum;
00870 *Vstd = *Vstd/massSum;
00871 }
00872 }
00873
00874
00875
00876
00877
00878