00001 /*!@file VFAT/segmentImageMerge2.C Basic image segmenter blob finder using color */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: T. Nathan Mundhenk <mundhenk@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/VFAT/segmentImageMerge2.C $ 00035 // $Id: segmentImageMerge2.C 9412 2008-03-10 23:10:15Z farhan $ 00036 // 00037 00038 #include "VFAT/segmentImageMerge2.H" 00039 00040 #include "Util/Assert.H" 00041 #include "Raster/Raster.H" 00042 00043 #include <cstdio> 00044 #include <cstdlib> 00045 #include <iostream> 00046 00047 //! initial vergance values 00048 #define CAMERAMU1 12.0F 00049 #define CAMERAMU2 23.0F 00050 #define CAMERAMU3 34.0F 00051 #define CAMERASIGMA1 33.0F 00052 #define CAMERASIGMA2 56.0F 00053 #define CAMERASIGMA3 67.0F 00054 00055 //! width distance to center between cameras in inches 00056 /* e.g. take the distance between cameras and divide by half */ 00057 #define DISTANCE 5 00058 00059 //! maximum lose of tracks before color is reset 00060 #define LOTMAX 5 00061 00062 //! How many iteration to calculate over for movement statistics 00063 #define ERRINTERVAL 5 00064 00065 void segmentImageMerge2::SIMcolorProcessBlobs(int instance) 00066 { 00067 float H1,S1,V1,Hs1,Ss1,Vs1; 00068 float mass; 00069 H1 = 0; S1 = 0; V1 = 0; 00070 Hs1 = 0; Ss1 = 0; Vs1 = 0; 00071 mass = 0; 00072 00073 // iterate over all blobs and asses new HSV thresholds from 00074 // candidate blobs 00075 for(int i = 0; i < SIM_segment[instance].SInumberBlobs(); i++) 00076 { 00077 if(SIM_track[instance].SITisCandidate(i) == true) 00078 { 00079 float H2,S2,V2,Hs2,Ss2,Vs2; 00080 // get mean value for this candidate blob, these values will be used 00081 // to create new adaptive color 00082 SIM_segment[instance].SIgetHSVvalueMean(i,&H2,&S2,&V2,&Hs2,&Ss2,&Vs2); 00083 00084 // Add in HSV values for each blob times the blob size 00085 // to make larger blobs give more push on mean values 00086 H1 += H2 * SIM_segment[instance].SIgetMass(i); 00087 S1 += S2 * SIM_segment[instance].SIgetMass(i); 00088 V1 += V2 * SIM_segment[instance].SIgetMass(i); 00089 Hs1 += Hs2 * SIM_segment[instance].SIgetMass(i); 00090 Ss1 += Ss2 * SIM_segment[instance].SIgetMass(i); 00091 Vs1 += Vs2 * SIM_segment[instance].SIgetMass(i); 00092 // increment mass 00093 mass += SIM_segment[instance].SIgetMass(i); 00094 00095 // find boundaries of this blob 00096 int tt = SIM_segment[instance].SIgetYmin(i); 00097 int bb = SIM_segment[instance].SIgetYmax(i); 00098 int ll = SIM_segment[instance].SIgetXmin(i); 00099 int rr = SIM_segment[instance].SIgetXmax(i); 00100 00101 00102 // draw bounding box for this blob 00103 // Note: box must be of height > 1 and width > 1 00104 if((bb != tt) && (ll != rr)) 00105 drawRect(*SIM_imageHold, Rectangle::tlbrI(tt*4,ll*4,bb*4,rr*4), 00106 PixRGB<byte>(SIM_boxRed[instance], 00107 SIM_boxGreen[instance], 00108 SIM_boxBlue[instance]),1); 00109 00110 // draw target circle for this blob 00111 drawCircle(*SIM_imageHold, Point2D<int>((int)SIM_segment[instance].SIgetCenterX(i) 00112 *4 00113 ,(int)SIM_segment[instance].SIgetCenterY(i)*4) 00114 ,(int)sqrt((double)SIM_segment[instance].SIgetMass(i)), 00115 PixRGB<byte>(SIM_circleRed[instance], 00116 SIM_circleGreen[instance], 00117 SIM_circleBlue[instance]),2); 00118 00119 drawCircle(*SIM_imageHold, Point2D<int>((int)SIM_segment[instance].SIgetCenterX(i) 00120 *4 00121 ,(int)SIM_segment[instance].SIgetCenterY(i)*4) 00122 ,2,PixRGB<byte>(255,0,0),2); 00123 00124 } 00125 else 00126 { 00127 if(SIM_track[instance].SITwasKilledByTrack(i) == false) 00128 { 00129 // find boundaries of this blob 00130 int tt = SIM_segment[instance].SIgetYmin(i); 00131 int bb = SIM_segment[instance].SIgetYmax(i); 00132 int ll = SIM_segment[instance].SIgetXmin(i); 00133 int rr = SIM_segment[instance].SIgetXmax(i); 00134 00135 00136 // draw bounding box for this blob 00137 // Note: box must be of height > 1 and width > 1 00138 if((bb != tt) && (ll != rr)) 00139 drawRect(*SIM_imageHold, Rectangle::tlbrI(tt*4,ll*4,bb*4,rr*4), 00140 PixRGB<byte>(SIM_circleRed[instance], 00141 SIM_circleGreen[instance], 00142 SIM_circleBlue[instance]),1); 00143 } 00144 } 00145 } 00146 00147 // draw background grid in HSV bar graph 00148 if(SIM_fast != true) 00149 drawGrid(*SIM_auxHold, 25,25,1,1,PixRGB<byte>(50,50,50)); 00150 00151 // draw HSV bar graph if blobs have any mass 00152 if(mass != 0) 00153 { 00154 // figure out HSV bar values 00155 H1 = H1/mass; S1 = S1/mass; V1 = V1/mass; 00156 Hs1 = Hs1/mass; Ss1 = Ss1/mass; Vs1 = Vs1/mass; 00157 std::cout << "H " << H1 << " S " << S1 << " V " << V1 << "\n"; 00158 std::cout << "Hs " << Hs1 << " Ss " << Ss1 << " Vs " << Vs1 << "\n"; 00159 float htemp = H1-Hs1+6; 00160 float stemp = ((S1-Ss1)*100)+6; 00161 float vtemp = V1-Vs1+6; 00162 if(htemp <= 1) htemp = 1; 00163 if(stemp <= 1) stemp = 1; 00164 if(vtemp <= 1) vtemp = 1; 00165 if(SIM_fast != true) 00166 { 00167 00168 // draw HSV mean value bars as a bunch of rectangles 00169 drawRect(*SIM_auxHold, Rectangle::tlbrI(5,5,((int)H1+6),20), 00170 PixRGB<byte>(255,0,0),1); 00171 drawRect(*SIM_auxHold, Rectangle::tlbrI(5,25,(int)(S1*100)+6,40), 00172 PixRGB<byte>(0,255,0),1); 00173 drawRect(*SIM_auxHold, Rectangle::tlbrI(5,45,((int)V1+6),60), 00174 PixRGB<byte>(0,0,255),1); 00175 00176 // draw standard deviation bars 00177 drawRect(*SIM_auxHold, Rectangle::tlbrI((int)(htemp),10, 00178 (int)(H1+Hs1+6),15), 00179 PixRGB<byte>(255,0,0),1); 00180 drawRect(*SIM_auxHold, Rectangle::tlbrI((int)(stemp),30, 00181 (int)(((S1+Ss1)*100)+6),35), 00182 PixRGB<byte>(0,255,0),1); 00183 drawRect(*SIM_auxHold, Rectangle::tlbrI((int)(vtemp),50, 00184 (int)(V1+Vs1+6),55), 00185 PixRGB<byte>(0,0,255),1); 00186 00187 // find total mass of all candidate blobs 00188 int massCalc = (int)((mass/(SIM_fimaHold->getWidth() 00189 *SIM_fimaHold->getHeight()))*450); 00190 drawRect(*SIM_auxHold, Rectangle::tlbrI(5,65,massCalc+6,80), 00191 PixRGB<byte>(255,0,255),1); 00192 } 00193 } 00194 00195 if(SIM_fast != true) 00196 { 00197 // Draw hard constraint bars into HVS bar graph 00198 drawRect(*SIM_auxHold, Rectangle::tlbrI(((int)SIM_HL[instance]+5),12, 00199 ((int)SIM_HU[instance]+6),13), 00200 PixRGB<byte>(255,255,0),1); 00201 drawRect(*SIM_auxHold, Rectangle::tlbrI((int)(SIM_SL[instance]*100)+5,32, 00202 (int)(SIM_SU[instance]*100)+6,33), 00203 PixRGB<byte>(255,255,0),1); 00204 drawRect(*SIM_auxHold, Rectangle::tlbrI(((int)SIM_VL[instance]+5),52, 00205 ((int)SIM_VU[instance]+6),53), 00206 PixRGB<byte>(255,255,0),1); 00207 } 00208 00209 // If loss of track is registered 5 times, reset color 00210 // values to start up defualt values 00211 if(SIM_track[instance].SITreturnLOT() == true) 00212 { 00213 //LINFO("LOT on %d, Number %d",instance, LOTcount[instance]); 00214 if(SIM_LOTcount[instance] > LOTMAX) 00215 { 00216 SIMresetColor(instance); 00217 } 00218 else 00219 { 00220 SIM_LOTcount[instance]++; 00221 } 00222 } 00223 else 00224 { 00225 00226 //LINFO("Get Value %d - %f,%f,%f,%f,%f,%f",instance,H1,S1,V1,Hs1,Ss1,Vs1); 00227 float hadj, sadj, vadj; 00228 00229 // if adaptive thresholding is turned on, adjust color 00230 // by standard deviation of color 00231 if(SIM_HASTD[instance] == true) 00232 hadj = Hs1*SIM_HA[instance]; 00233 else 00234 hadj = SIM_HA[instance]; 00235 00236 if(SIM_SASTD[instance] == true) 00237 sadj = Ss1*SIM_SA[instance]; 00238 else 00239 sadj = SIM_SA[instance]; 00240 00241 if(SIM_VASTD[instance] == true) 00242 vadj = Vs1*SIM_VA[instance]; 00243 else 00244 vadj = SIM_VA[instance]; 00245 00246 // if adaptation is true, adapt new color to mean values with 00247 // new standard deviation 00248 // but only within boundry constaints 00249 int count = 0; 00250 if(SIM_adpt[instance] == true) 00251 { 00252 if(H1 > SIM_HU[instance]) 00253 { 00254 H1 = SIM_HU[instance]; 00255 count++; 00256 } 00257 else 00258 if(H1 < SIM_HL[instance]) 00259 { 00260 H1 = SIM_HL[instance]; 00261 count++; 00262 } 00263 00264 if(S1 > SIM_SU[instance]) 00265 { 00266 S1 = SIM_SU[instance]; 00267 count++; 00268 } 00269 else 00270 if(S1 < SIM_SL[instance]) 00271 { 00272 S1 = SIM_SL[instance]; 00273 count++; 00274 } 00275 00276 if(V1 > SIM_VU[instance]) 00277 { 00278 V1 = SIM_VU[instance]; 00279 count++; 00280 } 00281 else 00282 if(V1 < SIM_VL[instance]) 00283 { 00284 V1 = SIM_VL[instance]; 00285 count++; 00286 } 00287 00288 LINFO("Set Value %d - %f,%f,%f,%f,%f,%f",instance, 00289 H1,hadj,S1,sadj,V1,vadj); 00290 /* 00291 if(count > 1) 00292 { 00293 if(SIM_LOTcount[instance] > LOTMAX) 00294 { 00295 SIMresetColor(instance); 00296 } 00297 else 00298 { 00299 SIM_LOTcount[instance]++; 00300 } 00301 } 00302 */ 00303 SIM_segment[instance].SIsetHue(H1,hadj,0); 00304 SIM_segment[instance].SIsetSat(S1,sadj,0); 00305 SIM_segment[instance].SIsetVal(V1,vadj,0); 00306 } 00307 } 00308 } 00309 00310 void segmentImageMerge2::SIMresetColor(int instance) 00311 { 00312 00313 if(SIM_useCluster[instance] == false) 00314 { 00315 LINFO("LOT: Setting new colors from pre-defined for %d",instance); 00316 SIM_segment[instance].SIsetHue(SIM_H[instance],SIM_Hstd[instance]*5,0); 00317 SIM_segment[instance].SIsetSat(SIM_S[instance],SIM_Sstd[instance]*5,0); 00318 SIM_segment[instance].SIsetVal(SIM_V[instance],SIM_Vstd[instance]*5,0); 00319 } 00320 else 00321 { 00322 LINFO("LOT: Setting new colors from cluster for %d",instance); 00323 SIMclusterColor(*SIM_fimaHold,instance); 00324 } 00325 SIM_LOTcount[instance] = 0; 00326 SIM_track[instance].SITreset(); 00327 } 00328 00329 /************************/ 00330 /* START PUBLIC METHODS */ 00331 /***********************/ 00332 00333 void segmentImageMerge2::resetAll(int instances) { 00334 00335 delete SIM_segment; 00336 00337 SIM_clusterSet = false; 00338 SIM_instanceNumber = instances; 00339 SIM_useCluster.resize(instances,false); 00340 SIM_H.resize(instances,0); 00341 SIM_S.resize(instances,0); 00342 SIM_V.resize(instances,0); 00343 SIM_Hstd.resize(instances,0); 00344 SIM_Sstd.resize(instances,0); 00345 SIM_Vstd.resize(instances,0); 00346 SIM_HA.resize(instances,3); 00347 SIM_SA.resize(instances,3); 00348 SIM_VA.resize(instances,3); 00349 SIM_HU.resize(instances,360); 00350 SIM_SU.resize(instances,1); 00351 SIM_VU.resize(instances,255); 00352 SIM_HL.resize(instances,0); 00353 SIM_SL.resize(instances,0); 00354 SIM_VL.resize(instances,0); 00355 SIM_delay.resize(instances,0); 00356 SIM_cameraMovePan.resize(instances,90); 00357 SIM_cameraMoveTilt.resize(instances,90); 00358 SIM_cameraGotoPan.resize(instances,90); 00359 SIM_cameraGotoTilt.resize(instances,90); 00360 SIM_cameraMu.resize((instances-1),0); 00361 SIM_cameraSigma.resize((instances-1),0); 00362 SIM_meanMove.resize(instances,0); 00363 00364 SIM_stdMove.resize(instances,0); 00365 00366 std::vector<float> temp; 00367 temp.resize(ERRINTERVAL,0); 00368 SIM_moveRecord.resize(instances,temp); 00369 SIM_moveRecordGrad.resize(instances,temp); 00370 SIM_LOTcount.resize(instances,0); 00371 SIM_height.resize(instances,0); 00372 SIM_width.resize(instances,0); 00373 SIM_gotoX.resize(instances,0); 00374 SIM_gotoY.resize(instances,0); 00375 SIM_circleRed.resize(instances,0); 00376 SIM_circleGreen.resize(instances,0); 00377 SIM_circleBlue.resize(instances,0); 00378 SIM_boxRed.resize(instances,0); 00379 SIM_boxGreen.resize(instances,0); 00380 SIM_boxBlue.resize(instances,0); 00381 SIM_didCircleColor.resize(instances,0); 00382 SIM_didBoxColor.resize(instances,0); 00383 SIM_didTrackColor.resize(instances,0); 00384 SIM_recordCounter.resize(instances,0); 00385 SIM_adpt.resize(instances,true); 00386 SIM_HASTD.resize(instances,false); 00387 SIM_SASTD.resize(instances,false); 00388 SIM_VASTD.resize(instances,false); 00389 SIM_moveCamera.resize(instances,false); 00390 temp.resize(instances); 00391 Timer Ttemp; 00392 SIM_tim.resize(instances,Ttemp); 00393 //segmentImage stmp; 00394 //segment.resize(instances,stmp); 00395 SIM_segment = new segmentImage2[instances]; 00396 segmentImageTrack2 sttmp; 00397 SIM_track.resize(instances,sttmp); 00398 00399 blobConf.openFile("blob.conf",true); 00400 SIM_blobProp.BP_LOTbound = (int)blobConf.getItemValueF("BP_LOTbound"); 00401 SIM_blobProp.BP_bound = (int)blobConf.getItemValueF("BP_bound"); 00402 SIM_blobProp.BP_softBound = (int)blobConf.getItemValueF("BP_softBound"); 00403 SIM_blobProp.BP_lowBound = (int)blobConf.getItemValueF("BP_lowBound"); 00404 SIM_blobProp.BP_traj = (int)blobConf.getItemValueF("BP_traj"); 00405 SIM_blobProp.BP_sampleStart = (int)blobConf.getItemValueF("BP_sampleStart"); 00406 SIM_blobProp.BP_maxTraj = (int)blobConf.getItemValueF("BP_maxTraj"); 00407 SIM_blobProp.BP_maxSize = (int)blobConf.getItemValueF("BP_maxSize"); 00408 SIM_blobProp.BP_minSize = (int)blobConf.getItemValueF("BP_minSize"); 00409 SIM_blobProp.BP_maxFrameSize = blobConf.getItemValueF("BP_maxFrameSize"); 00410 SIM_blobProp.BP_minMass = (int)blobConf.getItemValueF("BP_minMass"); 00411 SIM_blobProp.BP_maxMass = (int)blobConf.getItemValueF("BP_maxMass"); 00412 SIM_blobProp.BP_ratioMin = blobConf.getItemValueF("BP_ratioMin"); 00413 SIM_blobProp.BP_softRatioMin = blobConf.getItemValueF("BP_softRatioMin"); 00414 SIM_blobProp.BP_ratioMax = blobConf.getItemValueF("BP_ratioMax"); 00415 SIM_blobProp.BP_softRatioMax = blobConf.getItemValueF("BP_softRatioMax"); 00416 SIM_blobProp.BP_minClusterSize = 00417 (int)blobConf.getItemValueF("BP_minClusterSize"); 00418 SIM_blobProp.BP_clusterWeightSpat = 00419 blobConf.getItemValueF("BP_clusterWeightSpat"); 00420 //! set the weights in cluster for Hue 00421 SIM_blobProp.BP_clusterWeightH = 00422 blobConf.getItemValueF("BP_clusterWeightH"); 00423 //! set the weights in cluster for Sat 00424 SIM_blobProp.BP_clusterWeightS = 00425 blobConf.getItemValueF("BP_clusterWeightS"); 00426 //! set the weights in cluster for Val 00427 SIM_blobProp.BP_clusterWeightV = 00428 blobConf.getItemValueF("BP_clusterWeightV"); 00429 //! set initial standard deviation for color tracking after Hue 00430 SIM_blobProp.BP_clusterColorStdH = 00431 blobConf.getItemValueF("BP_clusterColorStdH"); 00432 //! set initial standard deviation for color tracking after Sat 00433 SIM_blobProp.BP_clusterColorStdS = 00434 blobConf.getItemValueF("BP_clusterColorStdS"); 00435 //! set initial standard deviation for color tracking after Val 00436 SIM_blobProp.BP_clusterColorStdV = 00437 blobConf.getItemValueF("BP_clusterColorStdV"); 00438 00439 00440 for(int i = 0; i < instances; i++) 00441 { 00442 SIM_track[i].SITsetBlobProp(&SIM_blobProp); 00443 SIM_track[i].SITsetUpVars(1000); 00444 SIM_track[i].SITsetImage(&SIM_segment[i]); 00445 } 00446 00447 SIM_cameraMu[0] = CAMERAMU1; 00448 SIM_cameraMu[1] = CAMERAMU2; 00449 SIM_cameraMu[2] = CAMERAMU3; 00450 SIM_cameraSigma[0] = CAMERASIGMA1; 00451 SIM_cameraSigma[1] = CAMERASIGMA2; 00452 SIM_cameraSigma[2] = CAMERASIGMA3; 00453 00454 } 00455 00456 // When called at the start, this will resize all the vectors we use 00457 segmentImageMerge2::segmentImageMerge2(int instances) 00458 { 00459 SIM_clusterSet = false; 00460 SIM_instanceNumber = instances; 00461 SIM_useCluster.resize(instances,false); 00462 SIM_H.resize(instances,0); 00463 SIM_S.resize(instances,0); 00464 SIM_V.resize(instances,0); 00465 SIM_Hstd.resize(instances,0); 00466 SIM_Sstd.resize(instances,0); 00467 SIM_Vstd.resize(instances,0); 00468 SIM_HA.resize(instances,3); 00469 SIM_SA.resize(instances,3); 00470 SIM_VA.resize(instances,3); 00471 SIM_HU.resize(instances,360); 00472 SIM_SU.resize(instances,1); 00473 SIM_VU.resize(instances,255); 00474 SIM_HL.resize(instances,0); 00475 SIM_SL.resize(instances,0); 00476 SIM_VL.resize(instances,0); 00477 SIM_delay.resize(instances,0); 00478 SIM_cameraMovePan.resize(instances,90); 00479 SIM_cameraMoveTilt.resize(instances,90); 00480 SIM_cameraGotoPan.resize(instances,90); 00481 SIM_cameraGotoTilt.resize(instances,90); 00482 SIM_cameraMu.resize((instances-1),0); 00483 SIM_cameraSigma.resize((instances-1),0); 00484 SIM_meanMove.resize(instances,0); 00485 00486 SIM_stdMove.resize(instances,0); 00487 00488 std::vector<float> temp; 00489 temp.resize(ERRINTERVAL,0); 00490 SIM_moveRecord.resize(instances,temp); 00491 SIM_moveRecordGrad.resize(instances,temp); 00492 SIM_LOTcount.resize(instances,0); 00493 SIM_height.resize(instances,0); 00494 SIM_width.resize(instances,0); 00495 SIM_gotoX.resize(instances,0); 00496 SIM_gotoY.resize(instances,0); 00497 SIM_circleRed.resize(instances,0); 00498 SIM_circleGreen.resize(instances,0); 00499 SIM_circleBlue.resize(instances,0); 00500 SIM_boxRed.resize(instances,0); 00501 SIM_boxGreen.resize(instances,0); 00502 SIM_boxBlue.resize(instances,0); 00503 SIM_didCircleColor.resize(instances,0); 00504 SIM_didBoxColor.resize(instances,0); 00505 SIM_didTrackColor.resize(instances,0); 00506 SIM_recordCounter.resize(instances,0); 00507 SIM_adpt.resize(instances,true); 00508 SIM_HASTD.resize(instances,false); 00509 SIM_SASTD.resize(instances,false); 00510 SIM_VASTD.resize(instances,false); 00511 SIM_moveCamera.resize(instances,false); 00512 temp.resize(instances); 00513 Timer Ttemp; 00514 SIM_tim.resize(instances,Ttemp); 00515 //segmentImage stmp; 00516 //segment.resize(instances,stmp); 00517 SIM_segment = new segmentImage2[instances]; 00518 segmentImageTrack2 sttmp; 00519 SIM_track.resize(instances,sttmp); 00520 00521 blobConf.openFile("blob.conf",true); 00522 SIM_blobProp.BP_LOTbound = (int)blobConf.getItemValueF("BP_LOTbound"); 00523 SIM_blobProp.BP_bound = (int)blobConf.getItemValueF("BP_bound"); 00524 SIM_blobProp.BP_softBound = (int)blobConf.getItemValueF("BP_softBound"); 00525 SIM_blobProp.BP_lowBound = (int)blobConf.getItemValueF("BP_lowBound"); 00526 SIM_blobProp.BP_traj = (int)blobConf.getItemValueF("BP_traj"); 00527 SIM_blobProp.BP_sampleStart = (int)blobConf.getItemValueF("BP_sampleStart"); 00528 SIM_blobProp.BP_maxTraj = (int)blobConf.getItemValueF("BP_maxTraj"); 00529 SIM_blobProp.BP_maxSize = (int)blobConf.getItemValueF("BP_maxSize"); 00530 SIM_blobProp.BP_minSize = (int)blobConf.getItemValueF("BP_minSize"); 00531 SIM_blobProp.BP_maxFrameSize = blobConf.getItemValueF("BP_maxFrameSize"); 00532 SIM_blobProp.BP_minMass = (int)blobConf.getItemValueF("BP_minMass"); 00533 SIM_blobProp.BP_maxMass = (int)blobConf.getItemValueF("BP_maxMass"); 00534 SIM_blobProp.BP_ratioMin = blobConf.getItemValueF("BP_ratioMin"); 00535 SIM_blobProp.BP_softRatioMin = blobConf.getItemValueF("BP_softRatioMin"); 00536 SIM_blobProp.BP_ratioMax = blobConf.getItemValueF("BP_ratioMax"); 00537 SIM_blobProp.BP_softRatioMax = blobConf.getItemValueF("BP_softRatioMax"); 00538 SIM_blobProp.BP_minClusterSize = 00539 (int)blobConf.getItemValueF("BP_minClusterSize"); 00540 SIM_blobProp.BP_clusterWeightSpat = 00541 blobConf.getItemValueF("BP_clusterWeightSpat"); 00542 //! set the weights in cluster for Hue 00543 SIM_blobProp.BP_clusterWeightH = 00544 blobConf.getItemValueF("BP_clusterWeightH"); 00545 //! set the weights in cluster for Sat 00546 SIM_blobProp.BP_clusterWeightS = 00547 blobConf.getItemValueF("BP_clusterWeightS"); 00548 //! set the weights in cluster for Val 00549 SIM_blobProp.BP_clusterWeightV = 00550 blobConf.getItemValueF("BP_clusterWeightV"); 00551 //! set initial standard deviation for color tracking after Hue 00552 SIM_blobProp.BP_clusterColorStdH = 00553 blobConf.getItemValueF("BP_clusterColorStdH"); 00554 //! set initial standard deviation for color tracking after Sat 00555 SIM_blobProp.BP_clusterColorStdS = 00556 blobConf.getItemValueF("BP_clusterColorStdS"); 00557 //! set initial standard deviation for color tracking after Val 00558 SIM_blobProp.BP_clusterColorStdV = 00559 blobConf.getItemValueF("BP_clusterColorStdV"); 00560 00561 00562 for(int i = 0; i < instances; i++) 00563 { 00564 SIM_track[i].SITsetBlobProp(&SIM_blobProp); 00565 SIM_track[i].SITsetUpVars(1000); 00566 SIM_track[i].SITsetImage(&SIM_segment[i]); 00567 } 00568 00569 SIM_cameraMu[0] = CAMERAMU1; 00570 SIM_cameraMu[1] = CAMERAMU2; 00571 SIM_cameraMu[2] = CAMERAMU3; 00572 SIM_cameraSigma[0] = CAMERASIGMA1; 00573 SIM_cameraSigma[1] = CAMERASIGMA2; 00574 SIM_cameraSigma[2] = CAMERASIGMA3; 00575 00576 00577 } 00578 00579 segmentImageMerge2::~segmentImageMerge2() 00580 {} 00581 00582 void segmentImageMerge2::SIMsetCircleColor(int r, int g, int b, int instance) 00583 { 00584 SIM_circleRed[instance] = r; 00585 SIM_circleBlue[instance] = g; 00586 SIM_circleGreen[instance] = b; 00587 SIM_didCircleColor[instance] = 1; 00588 } 00589 00590 void segmentImageMerge2::SIMsetBoxColor(int r, int g, int b, int instance) 00591 { 00592 SIM_boxRed[instance] = r; 00593 SIM_boxBlue[instance] = g; 00594 SIM_boxGreen[instance] = b; 00595 SIM_didBoxColor[instance] = 1; 00596 } 00597 00598 void segmentImageMerge2::SIMsetTrackColor(float h, float hstd, 00599 float s, float sstd, 00600 float v, float vstd, 00601 int instance, bool adapt, int avg) 00602 { 00603 SIM_H[instance] = h; 00604 SIM_S[instance] = s; 00605 SIM_V[instance] = v; 00606 SIM_Hstd[instance] = hstd; 00607 SIM_Sstd[instance] = sstd; 00608 SIM_Vstd[instance] = vstd; 00609 SIM_adpt[instance] = adapt; 00610 SIM_segment[instance].SIsetHue(SIM_H[instance],SIM_Hstd[instance],0); 00611 SIM_segment[instance].SIsetSat(SIM_S[instance],SIM_Sstd[instance],0); 00612 SIM_segment[instance].SIsetVal(SIM_V[instance],SIM_Vstd[instance],0); 00613 SIM_didTrackColor[instance] = 1; 00614 SIM_segment[instance].SIsetHSVavg(avg); 00615 } 00616 00617 void segmentImageMerge2::SIMsetAdapt(float ha, bool haSTD, float sa, 00618 bool saSTD, 00619 float va, bool vaSTD, int instance, 00620 bool useCluster) 00621 { 00622 SIM_useCluster[instance] = useCluster; 00623 SIM_HA[instance] = ha; 00624 SIM_SA[instance] = sa; 00625 SIM_VA[instance] = va; 00626 SIM_HASTD[instance] = haSTD; 00627 SIM_SASTD[instance] = saSTD; 00628 SIM_VASTD[instance] = vaSTD; 00629 } 00630 00631 void segmentImageMerge2::SIMsetAdaptBound(float Hupper, float Hlower, 00632 float Supper, float Slower, 00633 float Vupper, float Vlower, 00634 int instance) 00635 { 00636 SIM_HU[instance] = Hupper; 00637 SIM_SU[instance] = Supper; 00638 SIM_VU[instance] = Vupper; 00639 SIM_HL[instance] = Hlower; 00640 SIM_SL[instance] = Slower; 00641 SIM_VL[instance] = Vlower; 00642 } 00643 00644 void segmentImageMerge2::SIMsetCameraPosition(float pan, float tilt, 00645 int instance, bool stats) 00646 { 00647 // record camera movement 00648 SIM_cameraMovePan[instance] = pan; 00649 SIM_cameraMoveTilt[instance] = tilt; 00650 if(stats == true) 00651 { 00652 int doThisItem; 00653 float SIM_move = sqrt(pow(pan,2)+pow(tilt,2)); 00654 if(SIM_recordCounter[instance] != 0) 00655 { 00656 doThisItem = instance - 1; 00657 } 00658 else 00659 { 00660 doThisItem = ERRINTERVAL - 1; 00661 } 00662 00663 // Calculate finate state gradiant from last iteration to this one and record 00664 SIM_moveRecordGrad[instance][SIM_recordCounter[instance]] = 00665 SIM_move - SIM_moveRecord[instance][SIM_recordCounter[doThisItem]] ; 00666 SIM_moveRecord[instance][SIM_recordCounter[instance]] = SIM_move; 00667 00668 float sumP = 0; 00669 float SSP = 0; 00670 00671 // calcuate mean movements of camera servos 00672 for(int i = 0; i < ERRINTERVAL; i++) 00673 { 00674 sumP += SIM_moveRecordGrad[instance][i]; 00675 } 00676 SIM_meanMove[instance] = sumP/ERRINTERVAL; 00677 00678 // calculate standard deviation of camera servos 00679 for(int i = 0; i < ERRINTERVAL; i++) 00680 { 00681 SSP += pow((SIM_meanMove[instance] - SIM_moveRecordGrad[instance][i]),2); 00682 } 00683 SIM_stdMove[instance] = sqrt(SSP/ERRINTERVAL); 00684 00685 //LINFO("CAM %d Move STD %f",instance,stdMove[instance]); 00686 00687 // increment counter 00688 if(SIM_recordCounter[instance] < ERRINTERVAL) 00689 SIM_recordCounter[instance]++; 00690 else 00691 SIM_recordCounter[instance] = 0; 00692 } 00693 } 00694 00695 void segmentImageMerge2::SIMsetFrame(int x1, int y1, int x2, int y2, 00696 int realX, int realY, int instance) 00697 { 00698 SIM_segment[instance].SIsetFrame(x1,y1,x2,y2,realX,realY); 00699 } 00700 00701 /* This is a basic tracker access method that tracks on one image at a time */ 00702 void segmentImageMerge2::SIMtrackImage(Image<PixRGB<byte> > input, 00703 Image<PixRGB<byte> > *image, int instance, 00704 Image<PixRGB<byte> > *auxImage, bool _fast) 00705 { 00706 // Assert that parameters have been set up before starting 00707 SIM_fast = _fast; 00708 ASSERT(SIM_didCircleColor[instance] == 1); 00709 ASSERT(SIM_didBoxColor[instance] == 1); 00710 ASSERT(SIM_didTrackColor[instance] == 1); 00711 SIM_imageHold = image; 00712 SIM_auxHold = auxImage; 00713 00714 Image< PixRGB<float> > fima; 00715 00716 // decimate input image twice to speed things up 00717 fima = decXY(input); 00718 fima = decXY(fima); 00719 00720 SIM_fimaHold = &fima; 00721 00722 // segment the decimated image 00723 SIM_segment[instance].SIsegment(fima); 00724 00725 // get center of mass for blobs 00726 SIM_segment[instance].SIcalcMassCenter(); 00727 00728 // edit blobs, weed out all the non-hackers who are not fit to carry a rifle 00729 //LINFO("INSTANCE %d",instance); 00730 SIM_track[instance].SITtrack(); 00731 // apply adaptive color thesholding 00732 SIMcolorProcessBlobs(instance); 00733 00734 } 00735 00736 // END 00737 00738 // the statistical multi image tracker we will build 00739 void segmentImageMerge2::SIMtrackImageMulti( 00740 std::vector<Image<PixRGB<byte> > > *image, int instances) 00741 { 00742 SIM_fast = true; 00743 Image< PixRGB<float> > fima; 00744 00745 for(int i = 0; i < instances; i++) 00746 { 00747 ASSERT(SIM_didCircleColor[i] == 1); 00748 ASSERT(SIM_didBoxColor[i] == 1); 00749 ASSERT(SIM_didTrackColor[i] == 1); 00750 00751 SIM_imageHold = &(image->at(i)); 00752 fima = decXY(image->at(i)); 00753 fima = decXY(fima); 00754 00755 // Color segment this instance 00756 SIM_segment[i].SIsegment(fima); 00757 00758 // get center of mass for blobs 00759 SIM_segment[i].SIcalcMassCenter(); 00760 00761 // edit blobs, weed out all the non-hackers who are not fit 00762 // to carry a rifle 00763 SIM_track[i].SITtrack(0); 00764 } 00765 00766 SIM_moveMeanNormal = 0; 00767 SIM_moveStdNormal = 0; 00768 00769 // Normalize over movement statisitcs to apply them in the next iterations 00770 for(int i = 0; i < instances; i++) 00771 { 00772 SIM_moveMeanNormal += SIM_meanMove[i]; 00773 SIM_moveStdNormal += SIM_stdMove[i]; 00774 } 00775 //avoid divide by zero error 00776 SIM_moveMeanNormal += .000001; 00777 SIM_moveStdNormal += .000001; 00778 SIMupdateVergance(48,36); 00779 00780 for(int i = 0; i < instances; i++) 00781 { 00782 SIM_imageHold = &(image->at(i)); 00783 //compute vergance springs for each camera 00784 SIMverganceSpring(instances,i,true); 00785 00786 // apply adaptive color thesholding 00787 SIMcolorProcessBlobs(i); 00788 } 00789 } 00790 00791 void segmentImageMerge2::SIMmergeImages(Image<PixRGB<byte> > *image) 00792 { 00793 SIM_mergeGotoX = 0; SIM_mergeGotoY = 0; 00794 int mergeCount = 0; 00795 for(int i = 0; i < SIM_instanceNumber; i++) 00796 { 00797 SIM_gotoX[i] = SIM_track[i].SITgetObjectX(); 00798 SIM_gotoY[i] = SIM_track[i].SITgetObjectY(); 00799 if(SIM_track[i].SITreturnLOT() == false) 00800 { 00801 SIM_mergeGotoX += SIM_gotoX[i]; 00802 SIM_mergeGotoY += SIM_gotoY[i]; 00803 mergeCount++; 00804 } 00805 } 00806 if(mergeCount != 0) 00807 { 00808 SIM_mergeGotoX = SIM_mergeGotoX/mergeCount; 00809 SIM_mergeGotoY = SIM_mergeGotoY/mergeCount; 00810 } 00811 drawCircle(*image, Point2D<int>((int)SIM_mergeGotoX*4 00812 ,(int)SIM_mergeGotoY*4) 00813 ,10,PixRGB<byte>(255,0,0),2); 00814 } 00815 00816 void segmentImageMerge2::SIMupdateVergance(float distance, float gaussBase) 00817 { 00818 for(int i = 0; i < (SIM_instanceNumber-1); i++) 00819 { 00820 //this is the angle to the target from two apposing cameras. 00821 //Mu is then the differenc between these angles and 90 * 2 00822 SIM_cameraMu[i] = 2*(90-(((2*atan(distance/(DISTANCE*(i+1))))/3.14159)*90)); 00823 // the base angle for something at three feet from target 00824 // i.e. make the gaussian three feet in diameters 00825 float baseAngle = 2*(90-(((2*atan((distance-gaussBase) 00826 /(DISTANCE*(i+1))))/3.14159)*90)); 00827 00828 SIM_cameraSigma[i] = fabs(baseAngle-SIM_cameraMu[i]); 00829 //LINFO("UPDATE VERGANCE camera %d, Mu %f STD %f" 00830 //,i,cameraMu[i],cameraSigma[i]); 00831 } 00832 } 00833 00834 void segmentImageMerge2::SIMverganceSpring(int instances, int current, 00835 bool doTracked) 00836 { 00837 00838 float theta, phi; 00839 int seperation; 00840 00841 00842 int maxBlob = -1; 00843 float maxBlobVal = 0; 00844 00845 // if we didn't lose track and we want to vergance on cameras 00846 // that are tracking... 00847 if((SIM_track[current].SITreturnLOT() == false) && (doTracked == true)) 00848 { 00849 SIM_moveCamera[current] = false; 00850 00851 // for each blob this camera is tracking do 00852 for(int x = 0; x < SIM_segment[current].SInumberBlobs(); x++) 00853 { 00854 // check to make sure we havn't already disqualified this blob 00855 if(SIM_track[current].SITisCandidate(x) == true) 00856 { 00857 SIM_track[current].SIT_pVergance[x] = 0; 00858 // calculate the angle to the target blob being analized at the moment 00859 float gotoCY = fabs((480 - SIM_segment[current].SIgetCenterY(x)*8) 00860 - SIM_camera.Ypixel); 00861 00862 float panConv = ((float)SIM_camera.Xfield/(float)SIM_camera.Xpixel); 00863 float tiltConv = ((float)SIM_camera.Yfield/(float)SIM_camera.Ypixel); 00864 00865 float panOff = ((float)SIM_camera.Xpixel*.5) 00866 - SIM_segment[current].SIgetCenterX(x)*8; 00867 float tiltOff = ((float)SIM_camera.Ypixel*.5)-gotoCY; 00868 00869 float travelPan = SIM_cameraMovePan[current] + 00870 ((panOff*panConv)*SIM_camera.fieldAdjustmentX); 00871 float travelTilt = SIM_cameraMoveTilt[current] + 00872 ((tiltOff*tiltConv)*SIM_camera.fieldAdjustmentY); 00873 00874 // cycle over other camera positions 00875 //and calculate the p of vergance for this camera 00876 for(int j = 0; j < instances; j++) 00877 { 00878 if(j != current) 00879 { 00880 if(j < current) 00881 theta = travelPan - SIM_cameraMovePan[j]; 00882 else 00883 theta = SIM_cameraMovePan[j] - travelPan; 00884 00885 phi = fabs(travelTilt - SIM_cameraMoveTilt[j]); 00886 seperation = abs(current - j); 00887 00888 // p += vergance(tilt,cam(x))*vergance(pan,cam(x)) 00889 SIM_track[current].SIT_pVergance[x] += 00890 (SIM_Stats.gauss(theta,SIM_cameraMu[seperation-1] 00891 ,SIM_cameraSigma[seperation-1]) 00892 *SIM_Stats.gauss(phi,0.0F,21.0F))* 00893 (1-(SIM_stdMove[j]/SIM_moveStdNormal)); 00894 00895 } 00896 } 00897 // if I have the highest P of all the blobs in this 00898 // instance (camera) so far, I win. Take argmax 00899 if(SIM_track[current].SIT_pVergance[x] >= maxBlobVal) 00900 { 00901 if(maxBlob != -1) 00902 { 00903 // turn off this blob, it's no good 00904 SIM_track[current].SITsetCandidate(maxBlob,false); 00905 } 00906 maxBlob = x; 00907 // set this blob as the best one 00908 maxBlobVal = SIM_track[current].SIT_pVergance[x]; 00909 } 00910 else 00911 { 00912 // turn off this blob, it not better than anyone 00913 SIM_track[current].SITsetCandidate(x,false); 00914 } 00915 } 00916 } 00917 } 00918 else 00919 { 00920 // this camera is in a LOT, send it to a vergance coordinate; 00921 if(SIM_LOTcount[current] > LOTMAX) 00922 { 00923 SIM_moveCamera[current] = true; 00924 float doPan = 0; 00925 float doTilt = 0; 00926 int normal = 0; 00927 00928 // for all cameras not in LOT, 00929 // go to the average vergance over those cameras 00930 // e.g. you vergance should reflect the ones tracking 00931 for(int k = 0; k < instances; k++) 00932 { 00933 00934 if((k != current) && (SIM_track[k].SITreturnLOT() == false)) 00935 { 00936 seperation = abs(current - k); 00937 // you should converge to another camera based upon 00938 // the P derived from the gradiant of its 00939 // movement. This is cameras that are more fluid have more influince. 00940 if(k < current) 00941 { 00942 doPan += SIM_cameraMovePan[k] 00943 *(1- SIM_stdMove[k]/SIM_moveStdNormal) 00944 + SIM_cameraMu[seperation-1]; 00945 00946 } 00947 else 00948 { 00949 doPan += SIM_cameraMovePan[k] 00950 *(1 - SIM_stdMove[k]/SIM_moveStdNormal) 00951 - SIM_cameraMu[seperation-1]; 00952 } 00953 doTilt += SIM_cameraMoveTilt[k] 00954 *(1 - SIM_stdMove[k]/SIM_moveStdNormal); 00955 normal++; 00956 } 00957 } 00958 if(normal != 0) 00959 { 00960 // if we can be biased by at least one camera do this 00961 SIM_cameraGotoPan[current] = doPan/normal; 00962 SIM_cameraGotoTilt[current] = doTilt/normal; 00963 } 00964 } 00965 } 00966 } 00967 00968 void segmentImageMerge2::SIMgetImageTrackXY(int *x, int *y, int instance) 00969 { 00970 *x = SIM_gotoX[instance]; 00971 *y = SIM_gotoY[instance]; 00972 } 00973 00974 void segmentImageMerge2::SIMgetImageTrackXY2(int *x, int *y, int instance) 00975 { 00976 *x = SIM_track[instance].SITgetObjectX(); 00977 *y = SIM_track[instance].SITgetObjectY(); 00978 } 00979 00980 void segmentImageMerge2::SIMgetImageTrackXYMerge(int *x, int *y) 00981 { 00982 *x = SIM_mergeGotoX; 00983 *y = SIM_mergeGotoY; 00984 } 00985 00986 bool segmentImageMerge2::SIMreturnLOT(int instance) 00987 { 00988 return SIM_track[instance].SITreturnLOT(); 00989 } 00990 00991 float segmentImageMerge2::SIMreturnCameraProb(int instance) 00992 { 00993 return (1-SIM_stdMove[instance]/SIM_moveStdNormal); 00994 } 00995 00996 bool segmentImageMerge2::SIMdoMoveCamera(int instance, float *doPan, 00997 float *doTilt) 00998 { 00999 *doPan = SIM_cameraGotoPan[instance]; 01000 *doTilt = SIM_cameraGotoTilt[instance]; 01001 01002 // calculate gradiant variance 01003 return SIM_moveCamera[instance]; 01004 } 01005 01006 Image<byte> segmentImageMerge2::SIMreturnCandidateImage(int instance) 01007 { 01008 return SIM_segment[instance].SIreturnNormalizedCandidates(); 01009 } 01010 01011 void segmentImageMerge2::SIMSetCluster(int sizeX, int sizeY, int instances, 01012 float hweight, float sweight, 01013 float vweight) 01014 { 01015 SIM_clusterSet = true; 01016 long totalSize = (sizeX/4)*(sizeY/4); 01017 SIM_Hweight = hweight; 01018 SIM_Sweight = sweight; 01019 SIM_Vweight = vweight; 01020 std::vector<double> tempVec(5,0.0F); 01021 std::vector<float> tempVec2(totalSize,0.0F); 01022 SIM_vectorizedImage.resize(totalSize,tempVec2); 01023 SIM_meanH.resize(instances,tempVec); 01024 SIM_meanS.resize(instances,tempVec); 01025 SIM_meanV.resize(instances,tempVec); 01026 SIM_stdH.resize(instances,tempVec); 01027 SIM_stdS.resize(instances,tempVec); 01028 SIM_stdV.resize(instances,tempVec); 01029 SIM_score.resize(instances,tempVec2); 01030 SIM_item.resize(totalSize,0); 01031 configIn.openFile("NPclassify.conf"); 01032 polySet.openFile("polySet.conf"); 01033 SIM_NP.NPsetup(configIn,polySet,false); 01034 SIM_NP.NPresizeSpace(totalSize,5); 01035 } 01036 01037 void segmentImageMerge2::SIMclusterColor(Image<PixRGB<float> > image 01038 ,int instance) 01039 { 01040 ASSERT(SIM_clusterSet && "You need to set up cluster params first"); 01041 PixRGB<float> pix; 01042 Image<PixRGB<float> > newImage; 01043 newImage = decXY(image); 01044 newImage = decXY(newImage); 01045 Image<PixRGB<float> >::iterator inputIter = newImage.beginw(); 01046 std::vector<std::vector<float> >::iterator imageVecIter 01047 = SIM_vectorizedImage.begin(); 01048 01049 std::vector<float>::iterator imageVecIterIter; 01050 std::vector<int>::iterator item; 01051 01052 std::vector<double>::iterator meanHiter; 01053 meanHiter = SIM_meanH[instance].begin(); 01054 std::vector<double>::iterator meanSiter; 01055 meanSiter = SIM_meanS[instance].begin(); 01056 std::vector<double>::iterator meanViter; 01057 meanViter = SIM_meanV[instance].begin(); 01058 std::vector<double>::iterator stdHiter; 01059 stdHiter = SIM_stdH[instance].begin(); 01060 std::vector<double>::iterator stdSiter; 01061 stdSiter = SIM_stdS[instance].begin(); 01062 std::vector<double>::iterator stdViter; 01063 stdViter = SIM_stdV[instance].begin(); 01064 std::vector<float>::iterator scoreIter; 01065 scoreIter = SIM_score[instance].begin(); 01066 01067 // load the image into a vector of size samples*channels (e.g. HSV) 01068 int place = 0; 01069 int width = newImage.getWidth(); 01070 float pixH, pixS, pixV; 01071 while(inputIter != newImage.endw()) 01072 { 01073 imageVecIterIter = imageVecIter->begin(); 01074 pix = *inputIter; 01075 PixHSV<float>(pix).getHSV(pixH,pixS,pixV); 01076 *imageVecIterIter = (pixH/360) * 100 * SIM_blobProp.BP_clusterWeightH; 01077 ++imageVecIterIter; 01078 *imageVecIterIter = pixS * 100 * SIM_blobProp.BP_clusterWeightS; 01079 ++imageVecIterIter; 01080 *imageVecIterIter = (pixV/255) * 100 * SIM_blobProp.BP_clusterWeightV; 01081 ++imageVecIterIter; 01082 *imageVecIterIter = (place/width)* 0.5 * SIM_blobProp.BP_clusterWeightSpat; 01083 ++imageVecIterIter; 01084 *imageVecIterIter = (place%width)* 0.5 * SIM_blobProp.BP_clusterWeightSpat; 01085 ++imageVecIter; 01086 ++inputIter; 01087 place++; 01088 } 01089 01090 LINFO("RUNNING NEW VECTOR size %"ZU" x %"ZU,SIM_vectorizedImage.size(), 01091 SIM_vectorizedImage[0].size()); 01092 /* 01093 Image<double> temp; 01094 temp = SIM_vectorizedImage; 01095 Image<float> temp2; 01096 temp2 = temp; 01097 Raster::VisuFloat(image,0,"temp.pgm"); 01098 Raster::VisuFloat(temp2,FLOAT_NORM_0_255,"temp.pgm"); 01099 */ 01100 // cluster input image 01101 //SIM_NP.NPresetSpace(); 01102 SIM_NP.NPaddSpace(SIM_vectorizedImage); 01103 SIM_NP.NPclassifySpaceNew(false); 01104 LINFO("Get Return Info"); 01105 //roots = SIM_NP.NPgetStems(); 01106 //parents = SIM_NP.NPgetParents(); 01107 //density = SIM_NP.NPgetDensity(); 01108 double Hsum, HSS; 01109 double Ssum, SSS; 01110 double Vsum, VSS; 01111 float *H = &SIM_H[instance]; 01112 float *S = &SIM_S[instance]; 01113 float *V = &SIM_V[instance]; 01114 SIM_winningScore = 0; 01115 SIM_winningClass = -1; 01116 // get the mean and standard deviation over all clusters 01117 for(int i = 0; i < SIM_NP.NPgetStemNumber(); i++) 01118 { 01119 int classSize = SIM_NP.NPgetClassSize(i); 01120 *scoreIter = 0; 01121 //if(SIM_NP.NPgetMinClassSize() <= classSize) 01122 if(SIM_blobProp.BP_minClusterSize <= classSize) 01123 { 01124 // for each class computer sum and sum squared values over HSV 01125 Hsum = 0.0F; HSS = 0.0F; 01126 item = SIM_item.begin(); 01127 for(int cs = 0; cs < classSize; cs++, ++item) 01128 { 01129 *item = SIM_NP.NPgetClass(i,cs); 01130 Hsum += SIM_NP.NPgetFeature(*item,0); 01131 HSS += pow(SIM_NP.NPgetFeature(*item,0),2)/classSize; 01132 } 01133 *meanHiter = Hsum/classSize; 01134 *stdHiter = HSS - pow(*meanHiter,2); 01135 // for each class computer sum and sum squared values over HSV 01136 Ssum = 0.0F; SSS = 0.0F; 01137 item = SIM_item.begin(); 01138 for(int cs = 0; cs < classSize; cs++, ++item) 01139 { 01140 Ssum += SIM_NP.NPgetFeature(*item,1); 01141 SSS += pow(SIM_NP.NPgetFeature(*item,1),2)/classSize; 01142 } 01143 *meanSiter = Ssum/classSize; 01144 *stdSiter = SSS - pow(*meanSiter,2); 01145 // for each class computer sum and sum squared values over HSV 01146 Vsum = 0.0F; VSS = 0.0F; 01147 item = SIM_item.begin(); 01148 for(int cs = 0; cs < classSize; cs++, ++item) 01149 { 01150 Vsum += SIM_NP.NPgetFeature(*item,2); 01151 VSS += pow(SIM_NP.NPgetFeature(*item,2),2)/classSize; 01152 } 01153 *meanViter = Vsum/classSize; 01154 *stdViter = VSS - pow(*meanViter,2); 01155 // compute the P of this cluster matching the 01156 if((*stdHiter != 0) && (*stdSiter != 0) && (*stdViter != 0)) 01157 { 01158 *scoreIter = 01159 ((SIMPgauss(*H,*meanHiter,*stdHiter)*SIM_Hweight) 01160 + (SIMPgauss(*S,*meanSiter,*stdSiter)*SIM_Sweight) 01161 + (SIMPgauss(*V,*meanViter,*stdViter)*SIM_Vweight)) 01162 / (SIM_Hweight+SIM_Sweight+SIM_Vweight); 01163 } 01164 else 01165 *scoreIter = 0; 01166 // find out if the P is better for this class, if so, set it 01167 if(*scoreIter > SIM_winningScore) 01168 { 01169 SIM_winningScore = *scoreIter; 01170 SIM_winningClass = i; 01171 } 01172 LINFO("Competetors size %d H %f std %f S %f std %f V %f std %f P %f", 01173 classSize, 01174 *meanHiter,*stdHiter,*meanSiter,*stdSiter, 01175 *meanViter,*stdViter,*scoreIter); 01176 } 01177 ++meanHiter; ++meanSiter; ++meanViter; 01178 ++stdHiter; ++stdSiter; ++stdViter; 01179 ++scoreIter; 01180 } 01181 // if we have a winning class, set tracking colors to it 01182 if(SIM_winningClass != -1) 01183 { 01184 LINFO("WINNER %d H %f std %f S %f std %f V %f std %f", 01185 SIM_winningClass, 01186 SIM_meanH[instance][SIM_winningClass], 01187 SIM_stdH[instance][SIM_winningClass], 01188 SIM_meanS[instance][SIM_winningClass], 01189 SIM_stdS[instance][SIM_winningClass], 01190 SIM_meanV[instance][SIM_winningClass], 01191 SIM_stdV[instance][SIM_winningClass]); 01192 01193 SIM_segment[instance].SIsetHue(SIM_meanH[instance][SIM_winningClass], 01194 SIM_stdH[instance][SIM_winningClass] 01195 * SIM_blobProp.BP_clusterColorStdH,0); 01196 01197 SIM_segment[instance].SIsetSat(SIM_meanS[instance][SIM_winningClass], 01198 SIM_stdS[instance][SIM_winningClass] 01199 * SIM_blobProp.BP_clusterColorStdS,0); 01200 01201 SIM_segment[instance].SIsetVal(SIM_meanV[instance][SIM_winningClass], 01202 SIM_stdV[instance][SIM_winningClass] 01203 * SIM_blobProp.BP_clusterColorStdV,0); 01204 } 01205 SIM_NP.NPresetSpace(); 01206 } 01207 01208 bool segmentImageMerge2::SIMstereoMatch(PixelPoint points[2], 01209 CameraParams params[2], 01210 Point3D* retPoint) 01211 { 01212 float PI = 3.14159; 01213 float deg2rad = PI/180.0; 01214 01215 //define the std deviations of the error function(gaussian) for 01216 //various parameters 01217 Point3D* P = (Point3D*)calloc(2, sizeof(Point3D)); 01218 P[0] = Point3D(0.0, 0.0, 0.0); 01219 P[1] = Point3D(0.0, 0.0, 0.0); 01220 01221 Point3D* f = (Point3D*)calloc(2, sizeof(Point3D)); 01222 f[0] = Point3D(0.0, 0.0, 0.0); 01223 f[1] = Point3D(0.0, 0.0, 0.0); 01224 01225 //get ideal case values and max error values 01226 for(int i=0; i<2; i++) 01227 { 01228 P[i].x = params[i].x + params[i].r 01229 * sin(params[i].theta*deg2rad) *cos(params[i].phi*deg2rad) 01230 + points[i].x * cos(params[i].theta*deg2rad) 01231 * cos(params[i].phi*deg2rad) 01232 - points[i].y * sin(params[i].phi*deg2rad); 01233 01234 P[i].y = params[i].y + params[i].r*sin(params[i].theta*deg2rad) 01235 * sin(params[i].phi*deg2rad) 01236 + points[i].x * cos(params[i].theta*deg2rad) 01237 * sin(params[i].phi*deg2rad) 01238 + points[i].y * cos(params[i].phi*deg2rad); 01239 01240 P[i].z = params[i].z + params[i].r*cos(params[i].theta*deg2rad) 01241 - points[i].x * sin(params[i].theta*deg2rad); 01242 01243 f[i].x = params[i].x +params[i].r*sin(params[i].theta*deg2rad) 01244 * cos(params[i].phi*deg2rad) 01245 + params[i].f * sin(params[i].theta*deg2rad) 01246 * cos(params[i].phi*deg2rad); 01247 f[i].y = params[i].y + params[i].r*sin(params[i].theta*deg2rad) 01248 * sin(params[i].phi*deg2rad) 01249 + params[i].f * sin(params[i].theta*deg2rad) 01250 * sin(params[i].phi*deg2rad); 01251 f[i].z = params[i].z + params[i].r*cos(params[i].theta*deg2rad) 01252 + params[i].f * cos(params[i].theta*deg2rad); 01253 } 01254 01255 01256 float r1 = ((f[1].z-P[1].z)*(P[0].x-P[1].x) 01257 - (f[1].x-P[1].x)*(P[0].z-P[1].z))/ 01258 ((f[1].x-P[1].x)*(f[0].z-P[0].z) 01259 - (f[1].z-P[1].z)*(f[0].x-P[0].x)+0.0001); 01260 01261 float r2 = ((f[0].z-P[0].z)*(P[0].x-P[1].x) 01262 - (f[0].x-P[0].x)*(P[0].z-P[1].z))/ 01263 ((f[1].x-P[1].x)*(f[0].z-P[0].z) 01264 - (f[1].z-P[1].z)*(f[0].x-P[0].x)+0.0001); 01265 01266 float lhs = P[0].y + (f[0].y-P[0].y)*r1; 01267 float rhs = P[1].y + (f[1].y-P[1].y)*r2; 01268 01269 //printf("Here!!!!\n"); 01270 if(lhs-rhs>20 || lhs-rhs<-20) 01271 return false; 01272 01273 retPoint->x = P[0].x + (f[0].x-P[0].x)*r1; 01274 retPoint->y = (lhs+rhs)/2.0; 01275 retPoint->z = P[0].z + (f[0].z-P[0].z)*r1; 01276 return true; 01277 } 01278 01279 double segmentImageMerge2::SIMPgauss(double X, double Xbar, double std) 01280 { 01281 double first = 1/(sqrt(2*3.14159*pow(std,2))); 01282 double second = -1*(pow((X - Xbar),2)/(2*pow(std,2))); 01283 return first*exp(second); 01284 } 01285 01286