00001 /*!@file VFAT/segmentImageTrack.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/segmentImageTrack.C $ 00035 // $Id: segmentImageTrack.C 4663 2005-06-23 17:47:28Z rjpeters $ 00036 // 00037 00038 #include "VFAT/segmentImageTrack.H" 00039 00040 #define LOTBOUND 150 00041 #define BOUND 10 00042 #define LEVBOUND 140 00043 #define MINBOUND 5 00044 #define TRAJ 4 00045 #define SAMPLESTART 30 00046 #define MAXTRAJ 50 00047 #define MAXSIZE 100 00048 #define MAXMASS 25000 00049 #define MINMASS 25 00050 #define RATIOMIN 0.3F 00051 #define LEVRATIOMIN -0.3F 00052 #define RATIOMAX 1.7F 00053 #define LEVRATIOMAX 3.3F 00054 00055 void segmentImageTrack::applyHardConst() 00056 { 00057 if(LOT == true) 00058 { 00059 xBound = LOTBOUND; 00060 yBound = LOTBOUND; 00061 } 00062 else 00063 { 00064 xBound = (int)(BOUND + (levity*LEVBOUND)); 00065 yBound = (int)(BOUND + (levity*LEVBOUND)); 00066 } 00067 for(int i = 0; i < image->numberBlobs(); i++) 00068 { 00069 softCandidateBlob[i] = true; 00070 candidateBlob[i] = true; 00071 killedByTrack[i] = false; 00072 // check if a blobs mass is within cosnstraints 00073 if((image->getMass(i) < minMass) || (image->getMass(i) > maxMass)) 00074 { 00075 candidateBlob[i] = false; 00076 softCandidateBlob[i] = false; 00077 killedByTrack[i] = true; 00078 } 00079 00080 // check that a blob is within our X frame 00081 if((image->getCenterX(i) < (centerX - xBound)) || 00082 (image->getCenterX(i) > (centerX + xBound))) 00083 { 00084 candidateBlob[i] = false; 00085 killedByTrack[i] = true; 00086 } 00087 00088 // check that a blob is within our Y frame 00089 if((image->getCenterY(i) < (centerY - yBound)) || 00090 (image->getCenterY(i) > (centerY + yBound))) 00091 { 00092 candidateBlob[i] = false; 00093 killedByTrack[i] = true; 00094 } 00095 00096 // check that blob is within size ratios 00097 float foo = (image->getXmax(i) - image->getXmin(i)); 00098 if(foo != 0) 00099 { 00100 float temp = (image->getYmax(i) - image->getYmin(i))/foo; 00101 if((temp < (RATIOMIN + (levity*LEVRATIOMIN))) 00102 || (temp > (RATIOMAX + (levity*LEVRATIOMAX)))) 00103 { 00104 candidateBlob[i] = false; 00105 killedByTrack[i] = true; 00106 } 00107 } 00108 } 00109 } 00110 00111 // INSERT SIZE TO MASS RATIO 00112 // INSERT DUAL TRACK 00113 00114 void segmentImageTrack::fluidTrackCalc(float *thisMean, float *thisStd, 00115 float *thisCounter, 00116 std::vector<float> &thisList) 00117 { 00118 if((LOT == false) && (doTraj == true)) 00119 { 00120 if(*thisCounter == TRAJ) 00121 *thisCounter = 0; 00122 for(int i = 0; i < TRAJ; i++) 00123 { 00124 *thisMean += thisList[i]; 00125 *thisStd += pow(thisList[i],2)/TRAJ; 00126 } 00127 *thisMean = *thisMean/TRAJ; 00128 *thisStd = sqrt(*thisStd - pow(*thisMean,2)); 00129 } 00130 } 00131 00132 void segmentImageTrack::mergeBlobs() 00133 { 00134 mass = 0; 00135 double meanX = 0; 00136 double meanY = 0; 00137 minX = 640; 00138 minY = 480; 00139 maxX = 0; 00140 maxY = 0; 00141 00142 // calculate the center of a combined blob from the average 00143 // mass center of all remaining blobs 00144 00145 for(int i = 0; i < image->numberBlobs(); i++) 00146 { 00147 if(candidateBlob[i] == true) 00148 { 00149 mass += image->getMass(i); 00150 meanX += image->getMass(i)*image->getCenterX(i); 00151 meanY += image->getMass(i)*image->getCenterY(i); 00152 if(image->getXmax(i) > maxX) maxX = image->getXmax(i); 00153 if(image->getYmax(i) > maxY) maxY = image->getYmax(i); 00154 if(image->getXmin(i) < minX) minX = image->getXmin(i); 00155 if(image->getYmin(i) < minY) minY = image->getYmin(i); 00156 } 00157 } 00158 00159 if(mass > 0) 00160 { 00161 centerX = (int)(meanX/mass); 00162 centerY = (int)(meanY/mass); 00163 //LOT = false; 00164 if(((maxX-minX)*(maxY-minY)) > 00165 ((image->getImageSizeX()*image->getImageSizeY())/2)) 00166 LOT = true; 00167 else 00168 LOT = false; 00169 } 00170 else 00171 { 00172 LOT = true; 00173 } 00174 } 00175 00176 /*=============================================================*/ 00177 /* PUBLIC methods */ 00178 /*=============================================================*/ 00179 00180 segmentImageTrack::segmentImageTrack() 00181 {} 00182 00183 segmentImageTrack::segmentImageTrack(int initSize) 00184 { 00185 setUpVars(initSize); 00186 } 00187 00188 segmentImageTrack::segmentImageTrack(int initSize,segmentImage *seg) 00189 { 00190 image = seg; 00191 setUpVars(initSize); 00192 } 00193 00194 void segmentImageTrack::setImage(segmentImage *seg) 00195 { 00196 image = seg; 00197 } 00198 00199 void segmentImageTrack::setUpVars(int initSize) 00200 { 00201 // after the first iteration, do this 00202 candidateBlob.resize(initSize,true); 00203 softCandidateBlob.resize(initSize,true); 00204 killedByTrack.resize(initSize,true); 00205 Tsize.resize(TRAJ,0); 00206 Tmass.resize(TRAJ,0); 00207 TMS.resize(TRAJ,0); 00208 TsizeStd.resize(TRAJ,0); 00209 TmassStd.resize(TRAJ,0); 00210 TMSStd.resize(TRAJ,0); 00211 pVergance.resize(initSize,0); 00212 minMass = MINMASS; 00213 maxMass = MAXMASS; 00214 xBound = BOUND; 00215 yBound = BOUND; 00216 centerX = 0; 00217 centerY = 0; 00218 iter = false; 00219 LOT = false; 00220 trajCounterM = 0; 00221 trajCounterS = 0; 00222 trajCounterMS = 0; 00223 trajStart = 0; 00224 doTraj = false; 00225 } 00226 00227 segmentImageTrack::~segmentImageTrack() 00228 {} 00229 00230 void segmentImageTrack::track(float _levity) 00231 { 00232 levity = _levity; 00233 if(iter == true) 00234 { 00235 // apply hard constraints to blob 00236 applyHardConst(); 00237 } 00238 else 00239 { 00240 iter = true; 00241 } 00242 // merge all remaining blobs into a super blob 00243 mergeBlobs(); 00244 } 00245 00246 int segmentImageTrack::getObjectX() 00247 { 00248 return centerX; 00249 } 00250 00251 int segmentImageTrack::getObjectY() 00252 { 00253 return centerY; 00254 } 00255 00256 int segmentImageTrack::getXmin() 00257 { 00258 return minX; 00259 } 00260 00261 int segmentImageTrack::getXmax() 00262 { 00263 return maxX; 00264 } 00265 00266 int segmentImageTrack::getYmin() 00267 { 00268 return minY; 00269 } 00270 00271 int segmentImageTrack::getYmax() 00272 { 00273 return maxY; 00274 } 00275 00276 int segmentImageTrack::getMass() 00277 { 00278 return mass; 00279 } 00280 00281 bool segmentImageTrack::isCandidate(int blob) 00282 { 00283 return candidateBlob[blob]; 00284 } 00285 00286 bool segmentImageTrack::isSoftCandidate(int blob) 00287 { 00288 return softCandidateBlob[blob]; 00289 } 00290 00291 bool segmentImageTrack::wasKilledByTrack(int blob) 00292 { 00293 return killedByTrack[blob]; 00294 } 00295 00296 void segmentImageTrack::setCandidate(int blob, bool setThis) 00297 { 00298 candidateBlob[blob] = setThis; 00299 } 00300 00301 bool segmentImageTrack::returnLOT() 00302 { 00303 return LOT; 00304 } 00305 00306 void segmentImageTrack::reset() 00307 { 00308 trajStart = 0; 00309 doTraj = false; 00310 00311 }