00001 /*!@file VFAT/segmentImageTrack2.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/segmentImageTrack2.C $ 00035 // $Id: segmentImageTrack2.C 6003 2005-11-29 17:22:45Z rjpeters $ 00036 // 00037 00038 #include "VFAT/segmentImageTrack2.H" 00039 00040 #include "Util/Assert.H" 00041 00042 #include <iostream> 00043 /* 00044 #define LOTBOUND 150 00045 #define BOUND 10 00046 #define LEVBOUND 140 00047 #define MINBOUND 5 00048 #define TRAJ 4 00049 #define SAMPLESTART 30 00050 #define MAXTRAJ 50 00051 #define MAXSIZE 100 00052 #define MAXMASS 25000 00053 #define MINMASS 25 00054 #define RATIOMIN 0.3F 00055 #define LEVRATIOMIN -0.3F 00056 #define RATIOMAX 1.7F 00057 #define LEVRATIOMAX 3.3F 00058 */ 00059 00060 void segmentImageTrack2::SITapplyHardConst() 00061 { 00062 ASSERT(SIT_blobSet && "Must set blob properties in SITsetBlobProp"); 00063 if(SIT_LOT == true) 00064 { 00065 //std::cerr << "SET new LOT\n"; 00066 SIT_xBound = SIT_blobProp->BP_LOTbound; 00067 SIT_yBound = SIT_blobProp->BP_LOTbound; 00068 } 00069 else 00070 { 00071 //std::cerr << "SET old LOT\n"; 00072 SIT_xBound = (int)(SIT_blobProp->BP_bound + 00073 (SIT_levity*SIT_blobProp->BP_softBound)); 00074 SIT_yBound = (int)(SIT_blobProp->BP_bound + 00075 (SIT_levity*SIT_blobProp->BP_softBound)); 00076 } 00077 00078 for(int i = 0; i < SIT_image->SInumberBlobs(); i++) 00079 { 00080 SIT_softCandidateBlob[i] = true; 00081 SIT_candidateBlob[i] = true; 00082 SIT_killedByTrack[i] = false; 00083 // check if a blobs mass is within cosnstraints 00084 if((SIT_image->SIgetMass(i) < SIT_blobProp->BP_minMass) || 00085 (SIT_image->SIgetMass(i) >SIT_blobProp->BP_maxMass)) 00086 { 00087 SIT_candidateBlob[i] = false; 00088 SIT_softCandidateBlob[i] = false; 00089 SIT_killedByTrack[i] = true; 00090 /*std::cerr << "KILLED " << i << " MASS\n"; 00091 std::cerr << "\t" << SIT_blobProp->BP_minMass 00092 << " < " << SIT_image->SIgetMass(i) 00093 << " < " << SIT_blobProp->BP_maxMass 00094 << "\n";*/ 00095 } 00096 00097 // check that a blob is within our X frame 00098 if((SIT_image->SIgetCenterX(i) < (SIT_centerX - SIT_xBound)) || 00099 (SIT_image->SIgetCenterX(i) > (SIT_centerX + SIT_xBound))) 00100 { 00101 SIT_candidateBlob[i] = false; 00102 SIT_killedByTrack[i] = true; 00103 /*std::cerr << "KILLED " << i << " Xframe\n"; 00104 std::cerr << "\t" << (SIT_centerX - SIT_xBound) 00105 << " < " << SIT_image->SIgetCenterX(i) 00106 << " < " << (SIT_centerX + SIT_xBound) 00107 << "\n";*/ 00108 00109 } 00110 00111 // check that a blob is within our Y frame 00112 if((SIT_image->SIgetCenterY(i) < (SIT_centerY - SIT_yBound)) || 00113 (SIT_image->SIgetCenterY(i) > (SIT_centerY + SIT_yBound))) 00114 { 00115 SIT_candidateBlob[i] = false; 00116 SIT_killedByTrack[i] = true; 00117 /*std::cerr << "KILLED " << i << " Yframe\n"; 00118 std::cerr << "\t" << (SIT_centerY - SIT_yBound) 00119 << " < " << SIT_image->SIgetCenterY(i) 00120 << " < " << (SIT_centerY + SIT_yBound) 00121 << "\n";*/ 00122 } 00123 00124 // check that blob is within size ratios 00125 00126 float foo = (SIT_image->SIgetXmax(i) - SIT_image->SIgetXmin(i)); 00127 if(foo != 0) 00128 { 00129 float temp = (SIT_image->SIgetYmax(i) - SIT_image->SIgetYmin(i))/foo; 00130 if((temp < (SIT_blobProp->BP_ratioMin 00131 + (SIT_levity*SIT_blobProp->BP_softRatioMin))) 00132 || (temp > (SIT_blobProp->BP_ratioMax 00133 + (SIT_levity*SIT_blobProp->BP_softRatioMin)))) 00134 { 00135 SIT_candidateBlob[i] = false; 00136 SIT_killedByTrack[i] = true; 00137 /*std::cerr << "KILLED " << i << " RATIO\n";*/ 00138 } 00139 00140 } 00141 } 00142 } 00143 00144 // INSERT SIZE TO MASS RATIO 00145 // INSERT DUAL TRACK 00146 00147 void segmentImageTrack2::SITfluidTrackCalc(float *thisMean, float *thisStd, 00148 float *thisCounter, 00149 std::vector<float> &thisList) 00150 { 00151 if((SIT_LOT == false) && (SIT_doTraj == true)) 00152 { 00153 if(*thisCounter == SIT_blobProp->BP_traj) 00154 *thisCounter = 0; 00155 for(int i = 0; i < SIT_blobProp->BP_traj; i++) 00156 { 00157 *thisMean += thisList[i]; 00158 *thisStd += pow(thisList[i],2)/SIT_blobProp->BP_traj; 00159 } 00160 *thisMean = *thisMean/SIT_blobProp->BP_traj; 00161 *thisStd = sqrt(*thisStd - pow(*thisMean,2)); 00162 } 00163 } 00164 00165 void segmentImageTrack2::SITmergeBlobs() 00166 { 00167 SIT_mass = 0; 00168 double meanX = 0; 00169 double meanY = 0; 00170 SIT_minX = 640; 00171 SIT_minY = 480; 00172 SIT_maxX = 0; 00173 SIT_maxY = 0; 00174 00175 // calculate the center of a combined blob from the average 00176 // mass center of all remaining blobs 00177 00178 for(int i = 0; i < SIT_image->SInumberBlobs(); i++) 00179 { 00180 //std::cerr << "BLOB " << i << "\n"; 00181 if(SIT_candidateBlob[i] == true) 00182 { 00183 //std::cerr << "OK\n"; 00184 SIT_mass += SIT_image->SIgetMass(i); 00185 meanX += SIT_image->SIgetMass(i)*SIT_image->SIgetCenterX(i); 00186 meanY += SIT_image->SIgetMass(i)*SIT_image->SIgetCenterY(i); 00187 if(SIT_image->SIgetXmax(i) > SIT_maxX) SIT_maxX = 00188 SIT_image->SIgetXmax(i); 00189 if(SIT_image->SIgetYmax(i) > SIT_maxY) SIT_maxY = 00190 SIT_image->SIgetYmax(i); 00191 if(SIT_image->SIgetXmin(i) < SIT_minX) SIT_minX = 00192 SIT_image->SIgetXmin(i); 00193 if(SIT_image->SIgetYmin(i) < SIT_minY) SIT_minY = 00194 SIT_image->SIgetYmin(i); 00195 } 00196 } 00197 00198 if(SIT_mass > 0) 00199 { 00200 SIT_centerX = (int)(meanX/SIT_mass); 00201 SIT_centerY = (int)(meanY/SIT_mass); 00202 //LOT = false; 00203 00204 if(((SIT_maxX-SIT_minX)*(SIT_maxY-SIT_minY)) > 00205 ((SIT_image->SIgetImageSizeX()*SIT_image->SIgetImageSizeY()) 00206 /SIT_blobProp->BP_maxFrameSize)) 00207 { 00208 SIT_LOT = true; 00209 std::cerr << "LOT: " << ((SIT_maxX-SIT_minX)*(SIT_maxY-SIT_minY)) 00210 << " > " << 00211 ((SIT_image->SIgetImageSizeX()*SIT_image->SIgetImageSizeY()) 00212 /SIT_blobProp->BP_maxFrameSize) 00213 << "\n"; 00214 } 00215 else 00216 { 00217 SIT_LOT = false; 00218 } 00219 } 00220 else 00221 { 00222 SIT_LOT = true; 00223 //std::cerr << "LOT: mass < 0" << "\n"; 00224 } 00225 } 00226 00227 /*=============================================================*/ 00228 /* PUBLIC methods */ 00229 /*=============================================================*/ 00230 00231 segmentImageTrack2::segmentImageTrack2() 00232 { 00233 SIT_blobSet = false; 00234 } 00235 00236 segmentImageTrack2::segmentImageTrack2(int initSize) 00237 { 00238 SITsetUpVars(initSize); 00239 SIT_blobSet = false; 00240 } 00241 00242 segmentImageTrack2::segmentImageTrack2(int initSize,segmentImage2 *seg) 00243 { 00244 SIT_image = seg; 00245 SITsetUpVars(initSize); 00246 SIT_blobSet = false; 00247 } 00248 00249 void segmentImageTrack2::SITsetImage(segmentImage2 *seg) 00250 { 00251 SIT_image = seg; 00252 } 00253 00254 void segmentImageTrack2::SITsetBlobProp(blobProp *bp) 00255 { 00256 SIT_blobSet = true; 00257 SIT_blobProp = bp; 00258 } 00259 00260 void segmentImageTrack2::SITsetUpVars(int initSize) 00261 { 00262 // after the first iteration, do this 00263 SIT_candidateBlob.resize(initSize,true); 00264 SIT_softCandidateBlob.resize(initSize,true); 00265 SIT_killedByTrack.resize(initSize,true); 00266 SIT_Tsize.resize(SIT_blobProp->BP_traj,0); 00267 SIT_Tmass.resize(SIT_blobProp->BP_traj,0); 00268 SIT_TMS.resize(SIT_blobProp->BP_traj,0); 00269 SIT_TsizeStd.resize(SIT_blobProp->BP_traj,0); 00270 00271 SIT_TmassStd.resize(SIT_blobProp->BP_traj,0); 00272 SIT_TMSStd.resize(SIT_blobProp->BP_traj,0); 00273 SIT_pVergance.resize(initSize,0); 00274 SIT_centerX = 0; 00275 SIT_centerY = 0; 00276 SIT_iter = false; 00277 SIT_LOT = false; 00278 SIT_trajCounterM = 0; 00279 SIT_trajCounterS = 0; 00280 SIT_trajCounterMS = 0; 00281 SIT_trajStart = 0; 00282 SIT_doTraj = false; 00283 } 00284 00285 segmentImageTrack2::~segmentImageTrack2() 00286 {} 00287 00288 void segmentImageTrack2::SITtrack(float _levity) 00289 { 00290 SIT_levity = _levity; 00291 if(SIT_iter == true) 00292 { 00293 // apply hard constraints to blob 00294 SITapplyHardConst(); 00295 } 00296 else 00297 { 00298 SIT_iter = true; 00299 } 00300 // merge all remaining blobs into a super blob 00301 SITmergeBlobs(); 00302 } 00303 00304 int segmentImageTrack2::SITgetObjectX() 00305 { 00306 return SIT_centerX; 00307 } 00308 00309 int segmentImageTrack2::SITgetObjectY() 00310 { 00311 return SIT_centerY; 00312 } 00313 00314 int segmentImageTrack2::SITgetXmin() 00315 { 00316 return SIT_minX; 00317 } 00318 00319 int segmentImageTrack2::SITgetXmax() 00320 { 00321 return SIT_maxX; 00322 } 00323 00324 int segmentImageTrack2::SITgetYmin() 00325 { 00326 return SIT_minY; 00327 } 00328 00329 int segmentImageTrack2::SITgetYmax() 00330 { 00331 return SIT_maxY; 00332 } 00333 00334 int segmentImageTrack2::SITgetMass() 00335 { 00336 return SIT_mass; 00337 } 00338 00339 bool segmentImageTrack2::SITisCandidate(int blob) 00340 { 00341 return SIT_candidateBlob[blob]; 00342 } 00343 00344 bool segmentImageTrack2::SITisSoftCandidate(int blob) 00345 { 00346 return SIT_softCandidateBlob[blob]; 00347 } 00348 00349 bool segmentImageTrack2::SITwasKilledByTrack(int blob) 00350 { 00351 return SIT_killedByTrack[blob]; 00352 } 00353 00354 void segmentImageTrack2::SITsetCandidate(int blob, bool setThis) 00355 { 00356 SIT_candidateBlob[blob] = setThis; 00357 } 00358 00359 bool segmentImageTrack2::SITreturnLOT() 00360 { 00361 return SIT_LOT; 00362 } 00363 00364 void segmentImageTrack2::SITsetLOT(bool LOT) 00365 { 00366 SIT_LOT = LOT; 00367 } 00368 00369 void segmentImageTrack2::SITreset() 00370 { 00371 SIT_trajStart = 0; 00372 SIT_doTraj = false; 00373 00374 }