00001 /*!@file VFAT/segmentImageTrackMC.H 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/segmentImageTrackMC.H $ 00035 // $Id: segmentImageTrackMC.H 6795 2006-06-29 20:45:32Z rjpeters $ 00036 // 00037 00038 // ############################################################ 00039 // ############################################################ 00040 // ##### --- VFAT --- 00041 // ##### Vision Feature Analysis Tool: 00042 // ##### T. Nathan Mundhenk nathan@mundhenk.com 00043 // ##### Laurent Itti itti@pollux.usc.edu 00044 // ##### 00045 // ############################################################ 00046 // ############################################################ 00047 00048 #ifndef SEGMENTIMAGETRACKMC_H_DEFINED 00049 #define SEGMENTIMAGETRACKMC_H_DEFINED 00050 00051 #include "Image/Image.H" 00052 #include "Util/Timer.H" 00053 #include "Util/log.H" 00054 #include "Util/readConfig.H" 00055 #include "VFAT/blobProp.H" 00056 #include "segmentImageMC.H" 00057 #include <math.h> 00058 00059 //******************************************* 00060 /* ABOUT THE USE OF TEMPLATES HERE 00061 00062 the INT value is an integer number and should be an unsigned 00063 number (but isn't required to be). However, for images larger 00064 than 256x256 after decimation 00065 e.g. that contain more than 2^16 pixels, you should use a long instead 00066 this is because the number of blobs may be as large as the number 00067 of pixels. 00068 00069 the FLOAT is for a floating point. A double may be used to obtain more 00070 accurate values at run time. This is at your discression 00071 00072 */ 00073 00074 //! Define the template declaration for this class 00075 #define SIT_TEMPLATE_CLASS <class FLOAT, class INT, unsigned int SIT_channels> 00076 //! further define templates for this class 00077 #define SIT_TEMPLATE FLOAT,INT,SIT_channels 00078 //! log file 00079 #define SIT_LOG_FILE "segmentTrack.log" 00080 //! This is a class to track hyper spectal blobs 00081 /*! This class will segment blobs and track them using adaptive 00082 thresholding and by calling segmentImageMC. It can be used as a 00083 simple color tracker or can track anything else in real time so 00084 long as its features are continuous 00085 */ 00086 template SIT_TEMPLATE_CLASS 00087 class segmentImageTrackMC 00088 { 00089 private: 00090 blobProp SIT_blobProp; 00091 segmentImageMC<SIT_TEMPLATE> SIT_segment; 00092 Image<PixRGB<byte> > *SIT_imageHold; 00093 Image<PixRGB<byte> > *SIT_auxHold; 00094 Image<PixRGB<FLOAT> > *SIT_fimaHold; 00095 typename std::vector<INT> SIT_blobList; 00096 //! holder for PixRGB to channel conversion 00097 typename std::vector<Image<FLOAT> > SIT_chans; 00098 //! holder for temporal image smoothing 00099 typename std::vector<Image<FLOAT> > SIT_fimaLast; 00100 readConfig configIn; 00101 readConfig polySet; 00102 readConfig blobConf; 00103 //! run color adaptation methods on all channels 00104 void SITcolorAdaptation(); 00105 //! reset color values 00106 void SITresetColor(); 00107 //! analyze blobs, remove those that are no good 00108 void SITanalyzeBlobs(); 00109 //! merge all remaining blobs into a single motherblob 00110 void SITmergeBlobs(); 00111 00112 unsigned int SIT_LOTcount; 00113 unsigned int SIT_LOTtype; 00114 std::string SIT_LOTtypeName; 00115 //! boundary for blobs to be considered at close to last blob 00116 int SIT_xBound; 00117 int SIT_yBound; 00118 int SIT_centerX; 00119 int SIT_centerY; 00120 int SIT_centerM; //!< mass of the tracked object 00121 int SIT_centerXmod; 00122 int SIT_centerYmod; 00123 unsigned int SIT_minX; 00124 unsigned int SIT_maxX; 00125 unsigned int SIT_minY; 00126 unsigned int SIT_maxY; 00127 unsigned int SIT_minXmod; 00128 unsigned int SIT_maxXmod; 00129 unsigned int SIT_minYmod; 00130 unsigned int SIT_maxYmod; 00131 unsigned int SIT_circleRed; 00132 unsigned int SIT_circleGreen; 00133 unsigned int SIT_circleBlue; 00134 unsigned int SIT_boxRed; 00135 unsigned int SIT_boxGreen; 00136 unsigned int SIT_boxBlue; 00137 unsigned int SIT_bigBoxRed; 00138 unsigned int SIT_bigBoxGreen; 00139 unsigned int SIT_bigBoxBlue; 00140 unsigned int SIT_barSpace; 00141 unsigned int SIT_barWidth; 00142 unsigned int SIT_totalBlobs; 00143 unsigned int SIT_killedBlobs; 00144 unsigned int SIT_expectedX; 00145 unsigned int SIT_expectedY; 00146 unsigned int SIT_expectedXmax; 00147 unsigned int SIT_expectedYmax; 00148 unsigned int SIT_expectedXmin; 00149 unsigned int SIT_expectedYmin; 00150 //! what frame are we in? 00151 unsigned long SIT_frameNumber; 00152 00153 FLOAT SIT_thresh; 00154 FLOAT SIT_mass; 00155 FLOAT SIT_histoHeight; 00156 FLOAT SIT_smoothingAlpha; 00157 //! if set, we edit blobs based on expected locations 00158 bool SIT_useExpectedLocation; 00159 bool SIT_LOT, SIT_didCircleColor, SIT_didBoxColor, SIT_didTrackColor; 00160 bool SIT_useSmoothing, SIT_didSmoothing, SIT_draw, SIT_resetColor; 00161 //! This toggles the loging to file 00162 bool SIT_useLog; 00163 //! This toggles drawing the target image 00164 bool SIT_drawTargetImage; 00165 //! This toggles drawing the color adaptation image 00166 bool SIT_drawColorAdaptImage; 00167 //! toggles color adaptation (defaults to true, on) 00168 bool SIT_useColorAdaptation; 00169 00170 INT SIT_blobListSize; 00171 00172 //! mean color value for this channel 00173 typename std::vector<FLOAT> SIT_chMean1; 00174 //! temp holder for the mean value on this channel 00175 typename std::vector<FLOAT> SIT_chMean2; 00176 //! old mean value on this channel 00177 typename std::vector<FLOAT> SIT_oldMean; 00178 //! standard deviation for the color on this channel 00179 typename std::vector<FLOAT> SIT_chStd1; 00180 //! temp holder for the standard deviation on this channel 00181 typename std::vector<FLOAT> SIT_chStd2; 00182 //! old standard deviation on this channel 00183 typename std::vector<FLOAT> SIT_oldStd; 00184 //! lower bound for this channel 00185 typename std::vector<FLOAT> SIT_chLB; 00186 //! upper bound for this channel 00187 typename std::vector<FLOAT> SIT_chUB; 00188 //! old lower bound for this channel 00189 typename std::vector<FLOAT> SIT_oldLB; 00190 //! old upper bound for this channel 00191 typename std::vector<FLOAT> SIT_oldUB; 00192 //! special holder for standard deviation in colot adaptation 00193 typename std::vector<FLOAT> SIT_chNSTD; 00194 //! adaptation bias per channel 00195 typename std::vector<FLOAT> SIT_chAdapt; 00196 //! normalizer over channels 00197 typename std::vector<FLOAT> SIT_chNorm; 00198 //! old normalizer over channels 00199 typename std::vector<FLOAT> SIT_oldNorm; 00200 //! holder for skew 00201 typename std::vector<FLOAT> SIT_chSkew; 00202 //! Initial mean color for tracking 00203 typename std::vector<FLOAT> SIT_initMean; 00204 //! Inital standard Deviation for tracking 00205 typename std::vector<FLOAT> SIT_initStd; 00206 00207 std::vector<bool> SIT_softCandidateBlob; 00208 std::vector<bool> SIT_candidateBlob; 00209 std::vector<bool> SIT_killedByTrack; 00210 //! why was this blob killed string version 00211 std::vector<std::string> SIT_reasonForKill; 00212 //! why was this blob killed unsigned short int code 00213 std::vector<unsigned short> SIT_reasonForKillCode; 00214 00215 // center of the frame 00216 int SIT_x_center, SIT_y_center; 00217 00218 public: 00219 00220 //! default constructor, also sets up number of color channels 00221 segmentImageTrackMC(INT maxBlobCount); 00222 ~segmentImageTrackMC(); 00223 00224 //! set the tracking color for mass circle 00225 /*! 00226 @param r this is the red color for the output circle 00227 @param g this is the green color for the output circle 00228 @param b this is the blue color for the output circle 00229 @param instance this is the tracker to apply these settings to 00230 */ 00231 void SITsetCircleColor(unsigned int r, unsigned int g, unsigned int b); 00232 00233 //! set the tracking color for the bounding box 00234 //! set the tracking color for mass circle 00235 /*! 00236 @param r this is the red color for the output bounding box 00237 @param g this is the green color for the output bounding box 00238 @param b this is the blue color for the output bounding box 00239 @param bigr this is the red color for the merged bounding box 00240 @param bigg this is the green color for the merged bounding box 00241 @param bigb this is the blue color for the merged bounding box 00242 @param instance this is the tracker to apply these settings to 00243 */ 00244 void SITsetBoxColor(unsigned int r, unsigned int g, unsigned int b, 00245 unsigned int bigr, unsigned int bigg, unsigned int bigb); 00246 00247 //! set default tracking color values 00248 /*! 00249 In this method you place the properties for the colors you wish 00250 to track as a list from a std::vector. You upload the mean color 00251 on each channel which is the color you wish to initially track. You 00252 also upload the boundary for the color as the parameter std. This tells 00253 the inital range for considering a pixel as OK. The range is 00254 color +/- std. Norm is a normalizer to the color. For instance, if a 00255 channel ranges between 0 and 255 then this should be set to 255. The 00256 parameter adapt is for the color adaptation. This defines the range 00257 around which new colors can be found. This is a value that is multiplied 00258 by standard deviation of adapted color mean. Higher values mean less 00259 selective. The upper and lower bound determine the values above or 00260 below color adaptation can never go (ever). This keeps the adaptation 00261 in check. 00262 @param color This is the mean color to track on each channel 00263 @param std This is the threshold for color (color +/- std) 00264 @param norm This is the normalizer range for a color channel 00265 @param adapt This is the adaptation multiplier for color adaption 00266 @param upperBound This is the hard upper bound on channel values 00267 @param lowerBound This is the hard lower bound on channel values 00268 */ 00269 void SITsetTrackColor(typename std::vector<FLOAT> *color, 00270 typename std::vector<FLOAT> *std, 00271 typename std::vector<FLOAT> *norm, 00272 typename std::vector<FLOAT> *adapt, 00273 typename std::vector<FLOAT> *upperBound, 00274 typename std::vector<FLOAT> *lowerBound, 00275 bool resetColor = true, 00276 bool resetCandidates = false); 00277 00278 //! set frame size for color tracker 00279 /*! This allows the algorithm to inpect an area within each image 00280 rather than the whole image. Thus, images do not need to be resized in 00281 order to contrain the region processed. 00282 */ 00283 void SITsetFrame(int *x, int *y); 00284 //! set this if you want to temporally smooth frames 00285 /*! this will use a Kalman like filter to preserve past images 00286 @param alpha This is the percentage of last iteration to keep 0-1 00287 */ 00288 void SITsetUseSmoothing(bool smoothing, FLOAT alpha); 00289 00290 //! OPTIONAL - set where you expect the target appear 00291 /*! 00292 @param posX This is the centroid in X where you expect the target 00293 @param posY This is the centroid in Y where you expect the target 00294 @param maxX This creates a boundary for expectations 00295 @param maxY This creates a boundary for expectations 00296 @param minX This creates a boundary for expectations 00297 @param minY This creates a boundary for expectations 00298 */ 00299 void SITsetExpectedTargetPosition(const unsigned int posX, 00300 const unsigned int posY, 00301 const unsigned int maxX, 00302 const unsigned int maxY, 00303 const unsigned int minX, 00304 const unsigned int minY); 00305 //! return the expect target positions you set 00306 void SITgetExpectedTargetPosition(unsigned int *posX, 00307 unsigned int *posY, 00308 unsigned int *maxX, 00309 unsigned int *maxY, 00310 unsigned int *minX, 00311 unsigned int *minY, 00312 bool *isSet); 00313 //! unset the bool to use expected location 00314 void SITunsetExpectedTargetPosition(); 00315 //! turn on or off candidate pixel band passing (on,true by default) 00316 void SITtoggleCandidateBandPass(bool toggle); 00317 //! turn on or off color adaptation 00318 void SITtoggleColorAdaptation(bool toggle); 00319 00320 //! OPTIONAL set the frame number 00321 void SITsetFrameNumber(unsigned long frame); 00322 //! Put image one at a time into tracker and get back tracker image output 00323 /*! 00324 This is designed to run any pixel type images. 00325 If one wishes to use hyperspectral 00326 images use SITtrackImage with an input of vectorized images. 00327 @param input this is the raw input image 00328 @param image this is a pointer to the output image 00329 @param auxImage this is a pointer to the channel threshold bar image 00330 */ 00331 void SITtrackImageAny(Image<PixH2SV2<FLOAT> >& input, 00332 Image<PixRGB<byte> > *image, 00333 Image<PixRGB<byte> > *auxImage, 00334 bool editBlobs); 00335 //! Put image one at a time into tracker and get back tracker image output 00336 /*! 00337 @param input this is the raw input image 00338 @param image this is a pointer to the output image 00339 @param auxImage this is a pointer to the channel threshold bar image 00340 */ 00341 void SITtrackImage(Image<PixRGB<byte> >& input, 00342 Image<PixRGB<byte> > *image, 00343 Image<PixRGB<byte> > *auxImage, 00344 bool editBlobs); 00345 //! Put image one at a time into tracker and get back tracker image output 00346 /*! 00347 @param input this a set of input channel images 00348 @param image this is a pointer to the output image 00349 @param auxImage this is a pointer to the channel threshold bar image 00350 */ 00351 void SITtrackImage(typename std::vector<Image<FLOAT> >& input, 00352 Image<PixRGB<byte> > *image, 00353 Image<PixRGB<byte> > *auxImage, 00354 bool editBlobs); 00355 //! smooth the input image with a temporal Kalman filter 00356 void SITsmoothImage(typename std::vector<Image<FLOAT> > *input); 00357 //! OPTIONAL call this to turn on the logger 00358 void SITuseLog(bool useLog); 00359 //! OPTIONAL call this to turn off some drawing functions 00360 void SITtoggleDrawing(bool targetImage, 00361 bool colorAdaptImage); 00362 //! run the tracker 00363 void SITrunTrack(Image<PixRGB<byte> > *image, 00364 typename std::vector<Image<FLOAT> > *input, 00365 bool editBlobs); 00366 00367 //! This tells if no good target can be found. It returns loss of track. 00368 bool SITreturnLOT(); 00369 00370 //! tells what kind of loss of track we have 00371 /*! Types of loss of track are 00372 1 - object is no longer inside tracking frame 00373 2 - object no longer has mass, this either means a total loss 00374 of track OR all blobs have been edited out 00375 */ 00376 unsigned int SITreturnLOTtype(); 00377 //! returns an explanation of LOT 00378 std::string SITreturnLOTtypeName(); 00379 00380 //! return the blob ID map from SI 00381 Image<long> SITreturnBlobMap(); 00382 //! return the image of candidate pixels 00383 Image<byte> SITreturnCandidateImage(); 00384 //! return gaussian P for X, Xbar and std 00385 FLOAT SITPgauss(FLOAT X, FLOAT Xbar, FLOAT std); 00386 //! draw a tracking circle around blob i 00387 void SITdrawBlobTrack(INT i); 00388 //! draw the merged blob track box 00389 void SITdrawBlobTrackMerged(); 00390 //! draw a tracking blob around bad condidate blob 00391 void SITdrawBlobBox(INT i); 00392 //! draw histogram given the values provided 00393 void SITdrawHistoValues(typename std::vector<FLOAT> *mean, 00394 typename std::vector<FLOAT> *std, 00395 typename std::vector<FLOAT> *lb, 00396 typename std::vector<FLOAT> *ub, 00397 typename std::vector<FLOAT> *norm, 00398 bool LOT); 00399 //! return the blob position (for tracking) as an x y coord 00400 void SITgetBlobPosition(int &x, int &y); 00401 //! return the blob mass (for tracking) as an integer 00402 void SITgetBlobWeight(int &m); 00403 //! return the bounding box to the blobs 00404 void SITgetMinMaxBoundry(unsigned int *minX, unsigned int *maxX, 00405 unsigned int *minY, unsigned int *maxY); 00406 //! return the mass of the remaining blob 00407 FLOAT SITgetMass(); 00408 //! how many potential blobs have been killed 00409 void SITgetBlobAttrition(INT *totalBlobs, 00410 INT *killedBlobs); 00411 //! get new adaptive values for color tracking 00412 void SITgetAdaptiveChannelVals(typename std::vector<FLOAT> *mean, 00413 typename std::vector<FLOAT> *std); 00414 //! get how many loss of tracks have been found since last reset of color 00415 unsigned int SITgetLOTcount(); 00416 00417 // Use these methods to keep track of simple blob attrition 00418 00419 //! return the total number of blobs 00420 INT SITnumberBlobs(); 00421 //! for each blob this tells why it was killed 00422 unsigned short SITgetBlobReasonForKillCode(INT blob); 00423 //! for each blob this tells why it was killed 00424 std::string SITgetBlobReasonForKill(INT blob); 00425 //! for each blob, return its mass 00426 INT SITgetBlobMass(INT blob); 00427 //! for each blob, return its X position 00428 INT SITgetBlobPosX(INT blob); 00429 //! for each blob, return its Y position 00430 INT SITgetBlobPosY(INT blob); 00431 00432 //! this is set to true if after calling the tracker it reset colors 00433 /*! This indicates that the number of loss of tracks has exceded the 00434 the max number causing the color to be reset. This is only 00435 set once after colors are reset. Then it returns to having a 00436 value of false when the tracker is called again. 00437 */ 00438 bool SIT_LOTandRESET; 00439 00440 }; 00441 00442 #endif 00443 00444 // ###################################################################### 00445 /* So things look consistent in everyone's emacs... */ 00446 /* Local Variables: */ 00447 /* indent-tabs-mode: nil */ 00448 /* End: */