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