segmentImageTrackMC.C

Go to the documentation of this file.
00001 /*!@file VFAT/segmentImageTrackMC.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/segmentImageTrackMC.C $
00035 // $Id: segmentImageTrackMC.C 9412 2008-03-10 23:10:15Z farhan $
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_C_DEFINED
00049 #define SEGMENTIMAGETRACKMC_C_DEFINED
00050 
00051 #include "Util/Assert.H"
00052 #include "VFAT/segmentImageTrackMC.H"
00053 #include "Image/DrawOps.H"
00054 #include "Raster/Raster.H"
00055 
00056 #include <climits>
00057 #include <cstdio>
00058 #include <cstdlib>
00059 #include <fstream>
00060 #include <iostream>
00061 #include <time.h>
00062 
00063 
00064 //! maximum lose of tracks before color is reset
00065 #define LOTMAX            5
00066 
00067 //! How many iteration to calculate over for movement statistics
00068 #define ERRINTERVAL       5
00069 
00070 //! decimation size reduction factor
00071 #define DEC               4
00072 
00073 //! Width of channel bars
00074 #define BARWIDTH          10
00075 
00076 //! spacing between channel histo bars
00077 #define BARSPACE          5
00078 
00079 //! histogram height
00080 #define HISTOHEIGHT       450.0F
00081 
00082 /*********************************************************************/
00083 // compute color adaptation
00084 
00085 template SIT_TEMPLATE_CLASS
00086 void segmentImageTrackMC<SIT_TEMPLATE>::SITcolorAdaptation()
00087 {
00088   if(SIT_resetColor == false)
00089   {
00090     FLOAT mass = 0;
00091     typename std::vector<FLOAT>::iterator imean1 = SIT_chMean1.begin();
00092     typename std::vector<FLOAT>::iterator imean2;
00093     typename std::vector<FLOAT>::iterator istd1;
00094     typename std::vector<FLOAT>::iterator istd2;
00095     typename std::vector<FLOAT>::iterator ilb;
00096     typename std::vector<FLOAT>::iterator iub;
00097 
00098     while(imean1 != SIT_chMean1.end())
00099       *imean1++ = 0;
00100 
00101     // iterate over all blobs and asses new color thresholds from
00102     // candidate blobs
00103     SIT_blobListSize = 0;
00104     // (1) figure out which blobs we wish to extract information from
00105     for(INT i = 0; i < (unsigned)SIT_segment.SInumberBlobs(); i++)
00106     {
00107       if(SIT_candidateBlob[i] == true)
00108       {
00109         SIT_blobList[SIT_blobListSize] = i;
00110         SIT_blobListSize++;
00111       }
00112     }
00113     // (2) find mean color values for each blob if we have at least
00114     // one blob. This includes
00115     //        (a) mean color for each blob
00116     //        (b) variance (sum of squares) color for each blob
00117     //        (c) Mass of each blob (number of pixels)
00118     if(SIT_blobListSize > 0)
00119       SIT_segment.SIgetValueMean(&SIT_blobListSize,&SIT_blobList,
00120                                  &SIT_chMean1,&SIT_chStd1,&mass);
00121 
00122     // (3) If we have elected to, draw tracking targets for blobs
00123     if(SIT_drawTargetImage == true)
00124     {
00125       for(INT i = 0; i < SIT_segment.SInumberBlobs(); i++)
00126       {
00127         if(SIT_candidateBlob[i] == true)
00128         {
00129           SITdrawBlobTrack(i);
00130         }
00131         else
00132         {
00133           if(SIT_killedByTrack[i] == false)
00134           {
00135             SITdrawBlobBox(i);
00136           }
00137         }
00138       }
00139     }
00140 
00141     // (4) draw color bar graph if blobs have any mass
00142     if((SIT_LOT == false) && (SIT_drawTargetImage == true))
00143     {
00144       SITdrawBlobTrackMerged();
00145     }
00146 
00147     if(SIT_mass != 0)
00148     {
00149       istd1 = SIT_chStd1.begin();
00150       SIT_oldMean   = SIT_chMean1;
00151       SIT_oldStd    = SIT_chStd1;
00152       SIT_oldUB     = SIT_chUB;
00153       SIT_oldLB     = SIT_chLB;
00154       SIT_oldNorm   = SIT_chNorm;
00155       SIT_draw      = true;
00156     }
00157 
00158     // (5.a) If loss of track is registered 5 times (whatever LOTMAX is)
00159     // , reset color to orignal values from start up. throw away adaptive
00160     // values since they are no longer dependable
00161     if((SIT_LOT == true) && (SIT_useColorAdaptation == true))
00162     {
00163       //LINFO("LOT Number %d",SIT_LOTcount);
00164       if(SIT_drawColorAdaptImage == true)
00165         SITdrawHistoValues(&SIT_oldMean,&SIT_oldStd,
00166                            &SIT_oldUB,&SIT_oldLB,&SIT_oldNorm,true);
00167       if(SIT_LOTcount > LOTMAX)
00168       {
00169         LINFO("COLOR RESET due to LOT COUNT");
00170         SITresetColor(); // Will set SIT_resetColor = true
00171       }
00172       else
00173       {
00174         SIT_LOTcount++;
00175       }
00176     }
00177     else
00178     {
00179       SIT_LOTcount = 0;
00180     }
00181 
00182     //if((SIT_mass != 0) && (SIT_resetColor == false))
00183     if((SIT_LOT == false) && (SIT_useColorAdaptation == true))
00184     //if(SIT_mass != 0)
00185     {
00186       if(SIT_drawColorAdaptImage == true)
00187         SITdrawHistoValues(&SIT_chMean1,&SIT_chStd1,
00188                            &SIT_chUB,&SIT_chLB,&SIT_chNorm,false);
00189       // (5.b) if adaptive thresholding is turned on, adjust color
00190       // by standard deviation of color. As such each blobs color will
00191       // determin the new tracking color.
00192       istd1        = SIT_chStd1.begin();
00193       ilb          = SIT_chLB.begin();
00194       iub          = SIT_chUB.begin();
00195 
00196       typename std::vector<FLOAT>::iterator iadapt = SIT_chAdapt.begin();
00197       typename std::vector<FLOAT>::iterator instd = SIT_chNSTD.begin();
00198 
00199       for(imean1 = SIT_chMean1.begin(); imean1 != SIT_chMean1.end(); ++imean1,
00200             ++istd1, ++iub, ++ilb, ++instd)
00201       {
00202 
00203         *instd = *istd1*(*iadapt);
00204         /*
00205         if(*imean1 > *iub)
00206         {
00207           *imean1 = *iub;
00208         }
00209         else if(*imean1 < *ilb)
00210         {
00211           *imean1 = *ilb;
00212         }
00213         */
00214 
00215       }
00216       if(SIT_useLog == true)
00217       {
00218         std::ofstream outfile(SIT_LOG_FILE,std::ios::app);
00219         outfile << "FRAME " << SIT_frameNumber << " ADAPT " << "\t";
00220         typename std::vector<FLOAT>::iterator instd = SIT_chNSTD.begin();
00221         for(imean1 = SIT_chMean1.begin(); imean1 != SIT_chMean1.end();
00222             ++imean1,++instd)
00223         {
00224           outfile <<  *imean1 << " +/- (" << *instd << ")\t";
00225         }
00226         outfile << "\n";
00227         outfile.close();
00228       }
00229       SIT_segment.SIsetVal(SIT_chMean1,SIT_chNSTD,SIT_chSkew);
00230     }
00231   }
00232   else
00233   {
00234     LINFO("COLOR RESET TO USERS");
00235     SIT_resetColor = false;
00236   }
00237 }
00238 
00239 /*********************************************************************/
00240 template SIT_TEMPLATE_CLASS
00241 void segmentImageTrackMC<SIT_TEMPLATE>::SITresetColor()
00242 {
00243   SIT_segment.SIresetAvg();
00244   SIT_segment.SIsetVal(SIT_initMean,SIT_initStd,SIT_chSkew);
00245 
00246   if(SIT_useLog == true)
00247   {
00248     std::ofstream outfile(SIT_LOG_FILE,std::ios::app);
00249     outfile << "FRAME " << SIT_frameNumber << " RESET " << "\t";
00250     typename std::vector<FLOAT>::iterator imean = SIT_initMean.begin();
00251     typename std::vector<FLOAT>::iterator istd  = SIT_initStd.begin();
00252     while(imean != SIT_initMean.end())
00253     {
00254       outfile <<  *imean << " +/- (" << *istd << ")\t";
00255       ++imean; ++istd;
00256     }
00257     outfile << "\n";
00258     outfile.close();
00259   }
00260 
00261   SIT_segment.SIresetCandidates(true);
00262   SIT_LOTcount = 0;
00263   SIT_resetColor  = true;
00264   SIT_LOTandRESET = true;
00265 }
00266 
00267 /*********************************************************************/
00268 // weed out blobs that suck
00269 
00270 template SIT_TEMPLATE_CLASS
00271 void segmentImageTrackMC<SIT_TEMPLATE>::SITanalyzeBlobs()
00272 {
00273   SIT_totalBlobs = SIT_segment.SInumberBlobs();
00274   SIT_killedBlobs = 0;
00275 
00276   // (1.a) We have a loss of track, as such we need to reset some of
00277   // the adaptive parameters. Here we reset the parameter where we
00278   // expect the target to be to a much larger area since we no longer
00279   // can assume its location do to loss of track.
00280   if(SIT_LOT == true)
00281   {
00282     SIT_xBound = SIT_blobProp.BP_LOTbound;
00283     SIT_yBound = SIT_blobProp.BP_LOTbound;
00284   }
00285   else
00286   {
00287     // (1.b) We expect the target to appear close to where we last saw it
00288     // we set a parameter around the last known location. Any blob outside
00289     // this parameter must be predjidist
00290 
00291     SIT_xBound = (int)(SIT_blobProp.BP_bound +
00292                        (SIT_thresh*SIT_blobProp.BP_softBound));
00293     SIT_yBound = (int)(SIT_blobProp.BP_bound +
00294                        (SIT_thresh*SIT_blobProp.BP_softBound));
00295   }
00296 
00297   std::vector<bool>::iterator softCandidateBlobItr
00298     = SIT_softCandidateBlob.begin();
00299   std::vector<bool>::iterator candidateBlobItr
00300     = SIT_candidateBlob.begin();
00301   std::vector<bool>::iterator killedByTrackItr
00302     = SIT_killedByTrack.begin();
00303   std::vector<std::string>::iterator reasonForKillItr
00304     = SIT_reasonForKill.begin();
00305   std::vector<unsigned short>::iterator reasonForKillCodeItr
00306     = SIT_reasonForKillCode.begin();
00307 
00308   std::string S1,S2,S3;
00309   char C1[48], C2[48], C3[48];
00310   // (2) For each blob that the tracker found as a potential target,
00311   // check its properties such as its location in the image vs.
00312   // where we expect the target to be. Also check to make sure that the
00313   // target is geometrically good. That is, make sure its mass, size and
00314   // basic shape conform to our expectations.
00315   for(INT i = 0; i < SIT_totalBlobs; i++,
00316         ++softCandidateBlobItr, ++candidateBlobItr,
00317         ++killedByTrackItr, ++reasonForKillItr, ++reasonForKillCodeItr)
00318   {
00319     *softCandidateBlobItr = true;
00320     *candidateBlobItr     = true;
00321     *killedByTrackItr     = false;
00322     *reasonForKillCodeItr = 0;
00323     *reasonForKillItr     = "(0) Blob OK ";
00324 
00325     LDEBUG("[%d] expected x min = %d",
00326            SIT_useExpectedLocation == true, SIT_expectedXmin);
00327 
00328 
00329     // (3) check if a blobs mass is within constraints. That is
00330     // Make sure the blob is neither too large or to small. If so, we
00331     // don't like it.
00332     if((SIT_segment.SIgetMass(i) < (INT)SIT_blobProp.BP_minMass)
00333        && (SIT_blobProp.BP_checkMass == true))
00334     {
00335       *candidateBlobItr     = false;
00336       *softCandidateBlobItr = false;
00337       *killedByTrackItr     = true;
00338       *reasonForKillCodeItr = 1;
00339       SIT_killedBlobs++;
00340 
00341       S1 = " Blob Mass Contraints : Min : ";  S2 = " < ";
00342       sprintf(C1,"%d",(int)SIT_segment.SIgetMass(i));
00343       sprintf(C2,"%d",(int)SIT_blobProp.BP_minMass);
00344       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00345       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00346 
00347       LDEBUG("%3d. reason to kill: %s", i, (*reasonForKillItr).c_str());
00348     }
00349     else if((SIT_segment.SIgetMass(i) > (INT)SIT_blobProp.BP_maxMass)
00350             && (SIT_blobProp.BP_checkMass == true))
00351     {
00352 
00353       *candidateBlobItr     = false;
00354       *softCandidateBlobItr = false;
00355       *killedByTrackItr     = true;
00356       *reasonForKillCodeItr = 2;
00357       SIT_killedBlobs++;
00358 
00359       S1 = " Blob Mass Contraints : Max : ";  S2 = " > ";
00360       sprintf(C1,"%d",(int)SIT_segment.SIgetMass(i));
00361       sprintf(C2,"%d",(int)SIT_blobProp.BP_maxMass);
00362       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00363       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00364 
00365       LDEBUG("%3d. reason to kill: %s", i, (*reasonForKillItr).c_str());
00366     }
00367     // (4) check that a blob is within our X frame. That is, does
00368     // a blob fall in the image in a place where we would expect it
00369     // for instance close to where we last saw it.
00370     else if((SIT_segment.SIgetCenterX(i) < (SIT_centerX - SIT_xBound))
00371             && (SIT_blobProp.BP_checkFrameX == true))
00372     {
00373       *candidateBlobItr     = false;
00374       *killedByTrackItr     = true;
00375       *reasonForKillCodeItr = 3;
00376       SIT_killedBlobs++;
00377 
00378       S1 = " Blob Out of X Frame : Low : "; S2 = " < ";
00379       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterX(i));
00380       sprintf(C2,"%d",(int)(SIT_centerX - SIT_xBound));
00381       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00382       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00383 
00384       LDEBUG("%3d. reason to kill: %s", i, (*reasonForKillItr).c_str());
00385     }
00386     else if((SIT_segment.SIgetCenterX(i) > (SIT_centerX + SIT_xBound))
00387             && (SIT_blobProp.BP_checkFrameX == true))
00388     {
00389       *candidateBlobItr     = false;
00390       *killedByTrackItr     = true;
00391       *reasonForKillCodeItr = 4;
00392       SIT_killedBlobs++;
00393 
00394       S1 = " Blob Out of X Frame : High : "; S2 = " > ";
00395       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterX(i));
00396       sprintf(C2,"%d",(int)(SIT_centerX + SIT_xBound));
00397       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00398       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00399 
00400       LDEBUG("%3d. reason to kill: %s", i, (*reasonForKillItr).c_str());
00401     }
00402     // (5) check that a blob is within our Y frame. That is, does
00403     // a blob fall in the image in a place where we would expect it
00404     // for instance close to where we last saw it.
00405     else if((SIT_segment.SIgetCenterY(i) < (SIT_centerY - SIT_yBound))
00406             && (SIT_blobProp.BP_checkFrameY == true))
00407     {
00408       *candidateBlobItr     = false;
00409       *killedByTrackItr     = true;
00410       *reasonForKillCodeItr = 5;
00411       SIT_killedBlobs++;
00412 
00413       S1 = " Blob Out of Y Frame : Low : "; S2 = " < ";
00414       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterY(i));
00415       sprintf(C2,"%d",(int)(SIT_centerY - SIT_yBound));
00416       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00417       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00418 
00419       LDEBUG("%3d. reason to kill: %s", i, (*reasonForKillItr).c_str());
00420     }
00421     else if((SIT_segment.SIgetCenterY(i) > (SIT_centerY + SIT_yBound))
00422             && (SIT_blobProp.BP_checkFrameY == true))
00423     {
00424       *candidateBlobItr     = false;
00425       *killedByTrackItr     = true;
00426       *reasonForKillCodeItr = 6;
00427       SIT_killedBlobs++;
00428 
00429       S1 = " Blob Out of Y Frame : High : "; S2 = " > ";
00430       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterY(i));
00431       sprintf(C2,"%d",(int)(SIT_centerY + SIT_yBound));
00432       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00433       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00434 
00435       LDEBUG("%3d. reason to kill: %s", i, (*reasonForKillItr).c_str());
00436     }
00437     // (6) check that a blob is within our EXPECTED X frame. That is, does
00438     // a blob fall in the image in a place where we would expect it
00439     // for instance close to where we last saw it.
00440     // This is used only if we apriori set this value
00441     else if((SIT_segment.SIgetCenterX(i) > SIT_expectedXmax) &&
00442             (SIT_useExpectedLocation == true))
00443     {
00444       *candidateBlobItr     = false;
00445       *killedByTrackItr     = true;
00446       *reasonForKillCodeItr = 7;
00447       SIT_killedBlobs++;
00448 
00449       S1 = " Blob Out of Set Expected X Frame : High : "; S2 = " > ";
00450       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterX(i));
00451       sprintf(C2,"%d",(int)(SIT_expectedXmax));
00452       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00453       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00454 
00455       LDEBUG("%3d. reason to kill: %s", i, (*reasonForKillItr).c_str());
00456     }
00457     else if((SIT_segment.SIgetCenterX(i) < SIT_expectedXmin) &&
00458             (SIT_useExpectedLocation == true))
00459     {
00460       *candidateBlobItr     = false;
00461       *killedByTrackItr     = true;
00462       *reasonForKillCodeItr = 8;
00463       SIT_killedBlobs++;
00464 
00465       S1 = " Blob Out of Set Expected X Frame : Low : "; S2 = " < ";
00466       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterX(i));
00467       sprintf(C2,"%d",(int)(SIT_expectedXmin));
00468       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00469       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00470 
00471       LDEBUG("%3d. reason to kill: %s", i, (*reasonForKillItr).c_str());
00472     }
00473     // (7) check that a blob is within our EXPECTED Y frame. That is, does
00474     // a blob fall in the image in a place where we would expect it
00475     // for instance close to where we last saw it.
00476     // This is used only if we apriori set this value
00477     else if((SIT_segment.SIgetCenterY(i) > SIT_expectedYmax) &&
00478             (SIT_useExpectedLocation == true))
00479     {
00480       *candidateBlobItr     = false;
00481       *killedByTrackItr     = true;
00482       *reasonForKillCodeItr = 9;
00483       SIT_killedBlobs++;
00484 
00485       S1 = " Blob Out of Set Expected Y Frame : High : "; S2 = " > ";
00486       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterY(i));
00487       sprintf(C2,"%d",(int)(SIT_expectedYmax));
00488       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00489       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00490 
00491       LDEBUG("%3d. reason to kill: %s", i, (*reasonForKillItr).c_str());
00492     }
00493     else if((SIT_segment.SIgetCenterY(i) < SIT_expectedYmin) &&
00494             (SIT_useExpectedLocation == true))
00495     {
00496       *candidateBlobItr     = false;
00497       *killedByTrackItr     = true;
00498       *reasonForKillCodeItr = 10;
00499       SIT_killedBlobs++;
00500 
00501       S1 = " Blob Out of Set Expected Y Frame : Low : "; S2 = " < ";
00502       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterY(i));
00503       sprintf(C2,"%d",(int)(SIT_expectedYmin));
00504       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00505       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00506 
00507       LDEBUG("%3d. reason to kill: %s", i, (*reasonForKillItr).c_str());
00508     }
00509     // (8) check that blob is within size ratios. That is, does the
00510     // blob have a proper height and width for the target as we would
00511     // expect. For instance, as head should have a height and width that
00512     // are about the same.
00513     else if(SIT_blobProp.BP_checkSizeRatios == true)
00514     {
00515       FLOAT foo = (SIT_segment.SIgetXmax(i) - SIT_segment.SIgetXmin(i));
00516       if(foo != 0)
00517       {
00518         FLOAT temp = (SIT_segment.SIgetYmax(i)
00519                       - SIT_segment.SIgetYmin(i))/foo;
00520 
00521         if(temp < (SIT_blobProp.BP_ratioMin
00522                    + (SIT_thresh*SIT_blobProp.BP_softRatioMin)))
00523         {
00524           *candidateBlobItr     = false;
00525           *killedByTrackItr     = true;
00526           *reasonForKillCodeItr = 11;
00527           SIT_killedBlobs++;
00528 
00529           S1 = " Blob Size Ratios Contraint : Min :"; S2 = " < ";
00530           sprintf(C1,"%d",(int)temp);
00531           sprintf(C2,"%d",(int)(SIT_blobProp.BP_ratioMin
00532                                 + (SIT_thresh*SIT_blobProp.BP_softRatioMin)));
00533           sprintf(C3,"(%d)",*reasonForKillCodeItr);
00534           *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00535 
00536           LDEBUG("%3d. reason to kill: %s", i, (*reasonForKillItr).c_str());
00537         }
00538         else if (temp > (SIT_blobProp.BP_ratioMax
00539                          + (SIT_thresh*SIT_blobProp.BP_softRatioMin)))
00540         {
00541           *candidateBlobItr     = false;
00542           *killedByTrackItr     = true;
00543           *reasonForKillCodeItr = 12;
00544           SIT_killedBlobs++;
00545 
00546           S1 = " Blob Size Ratios Contraint : Max : "; S2 = " > ";
00547           sprintf(C1,"%d",(int)temp);
00548           sprintf(C2,"%d",(int)(SIT_blobProp.BP_ratioMax
00549                                 + (SIT_thresh*SIT_blobProp.BP_softRatioMin)));
00550           sprintf(C3,"(%d)",*reasonForKillCodeItr);
00551           *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00552 
00553           LDEBUG("%3d. reason to kill: %s", i, (*reasonForKillItr).c_str());
00554         }
00555         else
00556           LDEBUG("%3d. not killed", i);
00557       }
00558     }
00559   }
00560 }
00561 
00562 
00563 /*********************************************************************/
00564 // merge all remaining blobs into a single new blob
00565 
00566 template SIT_TEMPLATE_CLASS
00567 void segmentImageTrackMC<SIT_TEMPLATE>::SITmergeBlobs()
00568 {
00569   SIT_mass    = 0;
00570   FLOAT meanX = 0;
00571   FLOAT meanY = 0;
00572   SIT_minX    = UINT_MAX;
00573   SIT_minY    = UINT_MAX;
00574   SIT_maxX    = 0;
00575   SIT_maxY    = 0;
00576 
00577   // calculate the center of a combined blob from the average
00578   // mass center of all remaining blobs
00579   std::vector<bool>::iterator candidateBlobItr = SIT_candidateBlob.begin();
00580 
00581   for(INT i = 0; i < SIT_segment.SInumberBlobs(); i++, ++candidateBlobItr)
00582   {
00583     if(*candidateBlobItr == true)
00584     {
00585       LDEBUG("*candidateBlobItr == true");
00586       SIT_mass += SIT_segment.SIgetMass(i);
00587       meanX    += SIT_segment.SIgetMass(i)*SIT_segment.SIgetCenterX(i);
00588       meanY    += SIT_segment.SIgetMass(i)*SIT_segment.SIgetCenterY(i);
00589 
00590       if((unsigned)SIT_segment.SIgetXmax(i) > SIT_maxX)
00591                                 SIT_maxX = SIT_segment.SIgetXmax(i);
00592 
00593       if((unsigned)SIT_segment.SIgetYmax(i) > SIT_maxY)
00594                                 SIT_maxY = SIT_segment.SIgetYmax(i);
00595 
00596       if((unsigned)SIT_segment.SIgetXmin(i) < SIT_minX)
00597                                 SIT_minX = SIT_segment.SIgetXmin(i);
00598 
00599       if((unsigned)SIT_segment.SIgetYmin(i) < SIT_minY)
00600                                 SIT_minY = SIT_segment.SIgetYmin(i);
00601     }
00602 
00603     LDEBUG("%3d. [%3f %3f] SIT_mass: %f ", i,
00604            float(SIT_segment.SIgetCenterX(i)),
00605            float(SIT_segment.SIgetCenterY(i)),
00606            float(SIT_segment.SIgetMass(i)));
00607   }
00608 
00609   // Compute SIT_LOT here and set
00610   if(SIT_mass != 0)
00611   {
00612     SIT_centerX = (int)(meanX/SIT_mass);
00613     SIT_centerY = (int)(meanY/SIT_mass);
00614     SIT_centerM = (int)(SIT_mass);
00615 
00616     if(((SIT_maxX - SIT_minX) * (SIT_maxY - SIT_minY)) >
00617        ((SIT_segment.SIgetImageSizeX() * SIT_segment.SIgetImageSizeY())/
00618         SIT_blobProp.BP_maxFrameSize))
00619     {
00620       SIT_LOT         = true;
00621       SIT_LOTtype     = 1;
00622       SIT_LOTtypeName = "(1) Positive Mass but Spacially too Large";
00623       LDEBUG("(1) Positive Mass but Spacially too Large");
00624     }
00625     else
00626     {
00627       SIT_LOT                 = false;
00628       SIT_LOTtypeName         = "(0) NO LOT, OK";
00629       SIT_useExpectedLocation = false;
00630       LDEBUG("(0) NO LOT, OK");
00631     }
00632   }
00633   else
00634   {
00635     SIT_LOTtypeName = "(2) Zero Mass in merged blobs";
00636     SIT_LOTtype = 2;
00637     SIT_LOT     = true;
00638     LDEBUG("(2) Zero Mass in merged blobs");
00639 
00640     // JACOB: changed this to fixed values instead of calling
00641     // a pointer that may or may not be assigned to something
00642     SIT_centerX = SIT_x_center;
00643     SIT_centerY = SIT_y_center;
00644   }
00645 }
00646 
00647 /*********************************************************************/
00648 // PUBLIC ACCESS METHODS
00649 /*********************************************************************/
00650 
00651 // When called at the start, this will resize all the vectors we use
00652 // We only call this once since it is expensive to call.
00653 template SIT_TEMPLATE_CLASS
00654 segmentImageTrackMC<SIT_TEMPLATE>::segmentImageTrackMC(INT maxBlobCount)
00655 {
00656   SIT_LOTcount            = 0;
00657   SIT_frameNumber         = 0;
00658   SIT_useLog              = false;
00659   SIT_drawTargetImage     = true;
00660   SIT_drawColorAdaptImage = true;
00661   SIT_useColorAdaptation  = true;
00662   SIT_useExpectedLocation = false;
00663 
00664   time_t t       = time(0);
00665   std::string theTime = asctime(localtime(&t));
00666 
00667   std::ofstream outfile(SIT_LOG_FILE,std::ios::out);
00668   outfile << theTime << "\n";
00669   outfile.close();
00670 
00671   SIT_draw           = false;
00672   SIT_didCircleColor = false;
00673   SIT_didBoxColor    = false;
00674   SIT_didTrackColor  = false;
00675 
00676   // resize a bunch of std contaner vectors
00677 
00678   SIT_chMean1.resize( SIT_channels,0);
00679   SIT_chMean2.resize( SIT_channels,0);
00680   SIT_chStd1.resize(  SIT_channels,0);
00681   SIT_chStd2.resize(  SIT_channels,0);
00682   SIT_chLB.resize(    SIT_channels,0);
00683   SIT_chUB.resize(    SIT_channels,0);
00684   SIT_chNSTD.resize(  SIT_channels,0);
00685   SIT_chAdapt.resize( SIT_channels,0);
00686   SIT_chSkew.resize(  SIT_channels,0);
00687   SIT_initMean.resize(SIT_channels,0);
00688   SIT_initStd.resize( SIT_channels,0);
00689 
00690   SIT_softCandidateBlob.resize(maxBlobCount,false);
00691   SIT_candidateBlob.resize(    maxBlobCount,false);
00692   SIT_killedByTrack.resize(    maxBlobCount,false);
00693   SIT_blobList.resize(         maxBlobCount,0);
00694   SIT_reasonForKill.resize(    maxBlobCount,"no reason");
00695   SIT_reasonForKillCode.resize(maxBlobCount,0);
00696 
00697   SIT_barWidth    = BARWIDTH;
00698   SIT_barSpace    = BARSPACE;
00699   SIT_histoHeight = HISTOHEIGHT;
00700 
00701 
00702   // Load the config file and set a whole bunch of parameters from it
00703 
00704    blobConf.openFile("blob.conf",true);
00705 
00706   SIT_blobProp.BP_LOTbound     = (int)blobConf.getItemValueF("BP_LOTbound");
00707   SIT_blobProp.BP_bound        = (int)blobConf.getItemValueF("BP_bound");
00708   SIT_blobProp.BP_softBound    = (int)blobConf.getItemValueF("BP_softBound");
00709   SIT_blobProp.BP_lowBound     = (int)blobConf.getItemValueF("BP_lowBound");
00710   SIT_blobProp.BP_traj         = (int)blobConf.getItemValueF("BP_traj");
00711   SIT_blobProp.BP_sampleStart  = (int)blobConf.getItemValueF("BP_sampleStart");
00712   SIT_blobProp.BP_maxTraj      = (int)blobConf.getItemValueF("BP_maxTraj");
00713   SIT_blobProp.BP_maxSize      = (int)blobConf.getItemValueF("BP_maxSize");
00714   SIT_blobProp.BP_minSize      = (int)blobConf.getItemValueF("BP_minSize");
00715   SIT_blobProp.BP_maxFrameSize = blobConf.getItemValueF("BP_maxFrameSize");
00716   SIT_blobProp.BP_minMass      = (int)blobConf.getItemValueF("BP_minMass");
00717   SIT_blobProp.BP_maxMass      = (int)blobConf.getItemValueF("BP_maxMass");
00718   SIT_blobProp.BP_ratioMin     = blobConf.getItemValueF("BP_ratioMin");
00719   SIT_blobProp.BP_softRatioMin = blobConf.getItemValueF("BP_softRatioMin");
00720   SIT_blobProp.BP_ratioMax     = blobConf.getItemValueF("BP_ratioMax");
00721   SIT_blobProp.BP_softRatioMax = blobConf.getItemValueF("BP_softRatioMax");
00722   SIT_blobProp.BP_checkMass    = blobConf.getItemValueB("BP_checkMass");
00723   SIT_blobProp.BP_checkFrameX  = blobConf.getItemValueB("BP_checkFrameX");
00724   SIT_blobProp.BP_checkFrameY  = blobConf.getItemValueB("BP_checkFrameY");
00725   SIT_blobProp.BP_checkSizeRatios =
00726   blobConf.getItemValueB("BP_checkSizeRatios");
00727 
00728 }
00729 
00730 /*********************************************************************/
00731 
00732 template SIT_TEMPLATE_CLASS
00733 segmentImageTrackMC<SIT_TEMPLATE>::~segmentImageTrackMC()
00734 {}
00735 
00736 /*********************************************************************/
00737 
00738 template SIT_TEMPLATE_CLASS
00739 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetCircleColor(unsigned int r,
00740                                                        unsigned int g,
00741                                                        unsigned int b)
00742 {
00743   SIT_circleRed      = r;
00744   SIT_circleBlue     = g;
00745   SIT_circleGreen    = b;
00746   SIT_didCircleColor = true;
00747 }
00748 
00749 /*********************************************************************/
00750 
00751 template SIT_TEMPLATE_CLASS
00752 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetBoxColor(unsigned int r,
00753                                                     unsigned int g,
00754                                                     unsigned int b,
00755                                                     unsigned int bigr,
00756                                                     unsigned int bigg,
00757                                                     unsigned int bigb)
00758 {
00759   SIT_boxRed      = r;
00760   SIT_boxGreen    = g;
00761   SIT_boxBlue     = b;
00762   SIT_bigBoxRed   = bigr;
00763   SIT_bigBoxGreen = bigg;
00764   SIT_bigBoxBlue  = bigb;
00765   SIT_didBoxColor = true;
00766 }
00767 
00768 
00769 /*********************************************************************/
00770 
00771 template SIT_TEMPLATE_CLASS
00772 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetTrackColor(
00773                                       typename std::vector<FLOAT> *color,
00774                                       typename std::vector<FLOAT> *std,
00775                                       typename std::vector<FLOAT> *norm,
00776                                       typename std::vector<FLOAT> *adapt,
00777                                       typename std::vector<FLOAT> *upperBound,
00778                                       typename std::vector<FLOAT> *lowerBound,
00779                                       bool resetColor,
00780                                       bool resetCandidates)
00781 
00782 {
00783   // make sure that all our contaners are the same size
00784   ASSERT(color->size()      == std->size());
00785   ASSERT(std->size()        == norm->size());
00786   ASSERT(norm->size()       == adapt->size());
00787   ASSERT(adapt->size()      == upperBound->size());
00788   ASSERT(upperBound->size() == lowerBound->size());
00789 
00790   // set initial tracking parameters
00791   SIT_thresh        = 1;
00792   SIT_initMean      = *color;
00793   SIT_initStd       = *std;
00794   SIT_chNorm        = *norm;
00795   SIT_chAdapt       = *adapt;
00796   SIT_chUB          = *upperBound;
00797   SIT_chLB          = *lowerBound;
00798   SIT_didTrackColor = true;
00799   SIT_LOTcount      = 0;
00800   typename std::vector<FLOAT> skew(color->size(),0);
00801   SIT_chSkew = skew;
00802   SIT_segment.SIsetAvg(ERRINTERVAL);
00803   SIT_segment.SIresetAvg();
00804   SIT_segment.SIsetVal(SIT_initMean,SIT_initStd,SIT_chSkew);
00805 
00806   if(SIT_useLog == true)
00807   {
00808     std::ofstream outfile(SIT_LOG_FILE,std::ios::app);
00809     outfile << "FRAME " << SIT_frameNumber << " INIT " << "\t";
00810     typename std::vector<FLOAT>::iterator imean = SIT_initMean.begin();
00811     typename std::vector<FLOAT>::iterator istd  = SIT_initStd.begin();
00812     while(imean != SIT_initMean.end())
00813     {
00814       outfile <<  *imean << " +/- (" << *istd << ")\t";
00815       ++imean; ++istd;
00816     }
00817     outfile << "\n";
00818     outfile.close();
00819   }
00820 
00821 
00822   SIT_resetColor = resetColor;
00823   if(resetCandidates == true)
00824     SIT_segment.SIresetCandidates(true);
00825 }
00826 
00827 
00828 /*********************************************************************/
00829 
00830 template SIT_TEMPLATE_CLASS
00831 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetFrame(int *x, int *y)
00832 {
00833   SIT_segment.SIsetFrame(x,y);
00834   SIT_x_center = *x/2;
00835   SIT_y_center = *y/2;
00836   SIT_centerX = SIT_x_center;
00837   SIT_centerY = SIT_y_center;
00838 }
00839 
00840 /*********************************************************************/
00841 
00842 template SIT_TEMPLATE_CLASS
00843 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetUseSmoothing(bool smoothing, FLOAT alpha)
00844 {
00845   SIT_useSmoothing   = smoothing;
00846   SIT_smoothingAlpha = alpha;
00847   SIT_didSmoothing   = false;
00848 }
00849 
00850 /*********************************************************************/
00851 template SIT_TEMPLATE_CLASS
00852 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetExpectedTargetPosition(
00853                                               const unsigned int posX,
00854                                               const unsigned int posY,
00855                                               const unsigned int maxX,
00856                                               const unsigned int maxY,
00857                                               const unsigned int minX,
00858                                               const unsigned int minY)
00859 {
00860   SIT_expectedX           = posX;
00861   SIT_expectedY           = posY;
00862   SIT_expectedXmax        = maxX;
00863   SIT_expectedYmax        = maxY;
00864   SIT_expectedXmin        = minX;
00865   SIT_expectedYmin        = minY;
00866   SIT_useExpectedLocation = true;
00867 
00868 }
00869 
00870 /*********************************************************************/
00871 template SIT_TEMPLATE_CLASS
00872 void segmentImageTrackMC<SIT_TEMPLATE>::SITgetExpectedTargetPosition(
00873                                               unsigned int *posX,
00874                                               unsigned int *posY,
00875                                               unsigned int *maxX,
00876                                               unsigned int *maxY,
00877                                               unsigned int *minX,
00878                                               unsigned int *minY,
00879                                               bool *isSet)
00880 {
00881   *posX  = SIT_expectedX;
00882   *posY  = SIT_expectedY;
00883   *maxX  = SIT_expectedXmax;
00884   *maxY  = SIT_expectedYmax;
00885   *minX  = SIT_expectedXmin;
00886   *minY  = SIT_expectedYmin;
00887   *isSet = SIT_useExpectedLocation;
00888 }
00889 
00890 /*********************************************************************/
00891 template SIT_TEMPLATE_CLASS
00892 void segmentImageTrackMC<SIT_TEMPLATE>::SITunsetExpectedTargetPosition()
00893 {
00894   SIT_useExpectedLocation = false;
00895 }
00896 
00897 /*********************************************************************/
00898 template SIT_TEMPLATE_CLASS
00899 void segmentImageTrackMC<SIT_TEMPLATE>::SITtoggleCandidateBandPass(bool toggle)
00900 {
00901   SIT_segment.SItoggleCandidateBandPass(toggle);
00902 }
00903 /*********************************************************************/
00904 template SIT_TEMPLATE_CLASS
00905 void segmentImageTrackMC<SIT_TEMPLATE>::SITtoggleColorAdaptation(bool toggle)
00906 {
00907   SIT_useColorAdaptation = toggle;
00908 }
00909 
00910 /*********************************************************************/
00911 template SIT_TEMPLATE_CLASS
00912 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetFrameNumber(unsigned long frame)
00913 {
00914   SIT_frameNumber = frame;
00915 }
00916 
00917 /*********************************************************************/
00918 // MAIN METHOD
00919 /*********************************************************************/
00920 
00921 /* This is a basic tracker access method that tracks on one image at a time */
00922 /* this one is designed to work with any Pixels pixel */
00923 
00924 template SIT_TEMPLATE_CLASS
00925 void segmentImageTrackMC<SIT_TEMPLATE>::SITtrackImageAny
00926                                (Image<PixH2SV2<FLOAT> >& input,
00927                                 Image<PixRGB<byte> > *image,
00928                                 Image<PixRGB<byte> > *auxImage,
00929                                 bool editBlobs)
00930 {
00931   // Assert that parameters have been set up before starting
00932   ASSERT(SIT_didCircleColor == true);
00933   ASSERT(SIT_didBoxColor    == true);
00934   ASSERT(SIT_didTrackColor  == true);
00935 
00936   SIT_imageHold = image;
00937   SIT_auxHold   = auxImage;
00938 
00939   // decimate input image twice to speed things up
00940   input         = decXY(input);
00941   input         = decXY(input);
00942 
00943   Image<FLOAT> timage;
00944   timage.resize(input.getWidth(),input.getHeight(),true);
00945   SIT_chans.resize(SIT_channels,timage);
00946   for(unsigned int i = 0; i < SIT_channels; i++)
00947   {
00948     typename Image<FLOAT>::iterator iSIT_chans = SIT_chans[i].beginw();
00949     for(typename Image<PixH2SV2<FLOAT> >::iterator
00950         iinput = input.beginw();
00951         iinput != input.endw(); ++iinput, ++iSIT_chans)
00952     {
00953       *iSIT_chans = iinput->p[i];
00954     }
00955   }
00956 
00957   if(SIT_useSmoothing)
00958     SITsmoothImage(&SIT_chans);
00959 
00960   SITrunTrack(SIT_imageHold,&SIT_chans,editBlobs);
00961 }
00962 
00963 /*********************************************************************/
00964 
00965 /* This is a basic tracker access method that tracks on one image at a time */
00966 template SIT_TEMPLATE_CLASS
00967 void segmentImageTrackMC<SIT_TEMPLATE>::SITtrackImage
00968                                              (Image<PixRGB<byte> >& input,
00969                                               Image<PixRGB<byte> > *image,
00970                                               Image<PixRGB<byte> > *auxImage,
00971                                               bool editBlobs)
00972 {
00973 
00974   // Assert that parameters have been set up before starting
00975   ASSERT(SIT_didCircleColor == true);
00976   ASSERT(SIT_didBoxColor    == true);
00977   ASSERT(SIT_didTrackColor  == true);
00978 
00979   SIT_imageHold = image;
00980   SIT_auxHold   = auxImage;
00981   Image< PixRGB<FLOAT> > fima;
00982 
00983   // decimate input image twice to speed things up
00984   fima         = decXY(input);
00985   fima         = decXY(fima);
00986   SIT_fimaHold = &fima;
00987 
00988   // break image into seperate channels
00989   Image<FLOAT> timage;
00990   timage.resize(fima.getWidth(),fima.getHeight(),true);
00991 
00992   //typename std::vector<Image<FLOAT> > chans(3,timage);
00993   SIT_chans.resize(3,timage);
00994   typename Image<FLOAT>::iterator iHimage = SIT_chans[0].beginw();
00995   typename Image<FLOAT>::iterator iSimage = SIT_chans[1].beginw();
00996   typename Image<FLOAT>::iterator iVimage = SIT_chans[2].beginw();
00997   for(typename Image<PixRGB<FLOAT> >::iterator iImage = fima.beginw();
00998       iImage != fima.endw(); ++iImage, ++iHimage, ++iSimage, ++iVimage)
00999   {
01000     FLOAT pixH,pixS,pixV;
01001     PixRGB<FLOAT> pix;
01002     pix = *iImage;
01003     PixHSV<FLOAT>(pix).getHSV(pixH,pixS,pixV);
01004     *iHimage = pixH; *iSimage = pixS; *iVimage = pixV;
01005   }
01006 
01007   if(SIT_useSmoothing)
01008     SITsmoothImage(&SIT_chans);
01009 
01010   SITrunTrack(SIT_imageHold,&SIT_chans,editBlobs);
01011 }
01012 
01013 /*********************************************************************/
01014 
01015 template SIT_TEMPLATE_CLASS
01016 void segmentImageTrackMC<SIT_TEMPLATE>::SITtrackImage(typename
01017                                              std::vector<Image<FLOAT> >& input,
01018                                              Image<PixRGB<byte> > *image,
01019                                              Image<PixRGB<byte> > *auxImage,
01020                                              bool editBlobs)
01021 {
01022   SIT_imageHold = image;
01023   SIT_auxHold   = auxImage;
01024   Image<FLOAT> told;
01025   typename std::vector<Image<FLOAT> > fima(input.size(),told);
01026   typename std::vector<Image<FLOAT> >::iterator ifima = fima.begin();
01027   for(typename std::vector<Image<FLOAT> >::iterator iinput = input.begin();
01028       iinput != input.end(); ++iinput, ++ifima)
01029   {
01030     *ifima = decXY(*iinput);
01031     *ifima = decXY(*ifima);
01032   }
01033 
01034   if(SIT_useSmoothing)
01035     SITsmoothImage(&fima);
01036 
01037   SITrunTrack(SIT_imageHold,&fima,editBlobs);
01038 }
01039 
01040 /*********************************************************************/
01041 
01042 template SIT_TEMPLATE_CLASS
01043 void segmentImageTrackMC<SIT_TEMPLATE>::SITsmoothImage(typename
01044                                              std::vector<Image<FLOAT> > *input)
01045 {
01046   if(SIT_didSmoothing == false)
01047   {
01048     Image<FLOAT> timage;
01049     timage.resize(input->at(0).getWidth(),input->at(0).getHeight(),true);
01050     SIT_fimaLast.resize(input->size(),timage);
01051   }
01052 
01053   typename std::vector<Image<FLOAT> >::iterator iinput = input->begin();
01054   typename std::vector<Image<FLOAT> >::iterator ifima  = SIT_fimaLast.begin();
01055   while(iinput != input->end())
01056   {
01057     if(SIT_didSmoothing)
01058     {
01059       *ifima = (*iinput + ((*ifima) * SIT_smoothingAlpha))/
01060         (1+SIT_smoothingAlpha);
01061     }
01062     else
01063     {
01064       *ifima = *iinput;
01065       SIT_didSmoothing = true;
01066     }
01067     ++iinput; ++ifima;
01068   }
01069   input = &SIT_fimaLast;
01070 }
01071 
01072 /*********************************************************************/
01073 
01074 template SIT_TEMPLATE_CLASS
01075 void segmentImageTrackMC<SIT_TEMPLATE>::SITuseLog(bool useLog)
01076 {
01077   SIT_useLog = useLog;
01078 }
01079 
01080 /*********************************************************************/
01081 
01082 template SIT_TEMPLATE_CLASS
01083 void segmentImageTrackMC<SIT_TEMPLATE>::SITtoggleDrawing(bool targetImage,
01084                                                          bool colorAdaptImage)
01085 {
01086   SIT_drawTargetImage     = targetImage;
01087   SIT_drawColorAdaptImage = colorAdaptImage;
01088 }
01089 
01090 /*********************************************************************/
01091 
01092 template SIT_TEMPLATE_CLASS
01093 void segmentImageTrackMC<SIT_TEMPLATE>::SITrunTrack(
01094                                         Image<PixRGB<byte> > *image,
01095                                         typename
01096                                         std::vector<Image<FLOAT> > *input,
01097                                         bool editBlobs = true)
01098 {
01099   SIT_LOTandRESET = false;
01100   // (1) segment the decimated image
01101   SIT_segment.SIsegment(image,input);
01102   LDEBUG("SEGMENTED");
01103   // (2) get center of mass for blobs
01104   SIT_segment.SIcalcMassCenter();
01105   LDEBUG("CALCULATED MASS CENTER");
01106   // (3) edit blobs, weed out all the non-hackers who are not
01107   // fit to carry a rifle
01108   if(editBlobs)
01109     SITanalyzeBlobs();
01110   LDEBUG("BLOBS ANALYZED");
01111   // (4) merge all remaining blobs
01112   SITmergeBlobs();
01113   LDEBUG("BLOBS MERGED");
01114   // (5) apply adaptive color thesholding
01115   SITcolorAdaptation();
01116   LDEBUG("COLORS ADAPTED");
01117 }
01118 
01119 /*********************************************************************/
01120 // DATA RETURN METHODS
01121 /*********************************************************************/
01122 
01123 template SIT_TEMPLATE_CLASS
01124 bool segmentImageTrackMC<SIT_TEMPLATE>::SITreturnLOT()
01125 {
01126   return SIT_LOT;
01127 }
01128 
01129 /*********************************************************************/
01130 
01131 template SIT_TEMPLATE_CLASS
01132 unsigned int segmentImageTrackMC<SIT_TEMPLATE>::SITreturnLOTtype()
01133 {
01134   return SIT_LOTtype;
01135 }
01136 
01137 /*********************************************************************/
01138 
01139 template SIT_TEMPLATE_CLASS
01140 std::string segmentImageTrackMC<SIT_TEMPLATE>::SITreturnLOTtypeName()
01141 {
01142   return SIT_LOTtypeName;
01143 }
01144 
01145 /*********************************************************************/
01146 
01147 template SIT_TEMPLATE_CLASS
01148 Image<long> segmentImageTrackMC<SIT_TEMPLATE>::SITreturnBlobMap()
01149 {
01150   return SIT_segment.SIreturnBlobs();
01151 }
01152 
01153 /*********************************************************************/
01154 
01155 template SIT_TEMPLATE_CLASS
01156 Image<byte> segmentImageTrackMC<SIT_TEMPLATE>::SITreturnCandidateImage()
01157 {
01158   return SIT_segment.SIreturnNormalizedCandidates();
01159 }
01160 
01161 /*********************************************************************/
01162 
01163 template SIT_TEMPLATE_CLASS
01164 void segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobPosition(int &x,
01165                                                            int &y)
01166 {
01167       SIT_centerXmod = SIT_centerX*DEC;
01168       SIT_centerYmod = SIT_centerY*DEC;
01169   x = SIT_centerXmod;
01170   y = SIT_centerYmod;
01171 }
01172 
01173 /*********************************************************************/
01174 
01175 template SIT_TEMPLATE_CLASS
01176 void segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobWeight(int &m)
01177 {
01178   m = SIT_centerM*DEC;
01179 }
01180 
01181 /*********************************************************************/
01182 
01183 template SIT_TEMPLATE_CLASS
01184 void segmentImageTrackMC<SIT_TEMPLATE>::SITgetMinMaxBoundry(unsigned int *minX,
01185                                                             unsigned int *maxX,
01186                                                             unsigned int *minY,
01187                                                             unsigned int *maxY)
01188 {
01189           SIT_minXmod = SIT_minX*DEC;
01190           SIT_maxXmod = SIT_maxX*DEC;
01191           SIT_minYmod = SIT_minY*DEC;
01192           SIT_maxYmod = SIT_maxY*DEC;
01193   *minX = SIT_minXmod;
01194   *maxX = SIT_maxXmod;
01195   *minY = SIT_minYmod;
01196   *maxY = SIT_maxYmod;
01197 }
01198 
01199 /********************************************************************/
01200 
01201 /* commented this out because SIT_MASS is not defined (or even declared)
01202    anywhere, so we get an error with g++ 3.4.1 */
01203 template SIT_TEMPLATE_CLASS
01204 FLOAT segmentImageTrackMC<SIT_TEMPLATE>::SITgetMass()
01205 {
01206   return SIT_mass;
01207 }
01208 
01209 /********************************************************************/
01210 
01211 template SIT_TEMPLATE_CLASS
01212 void segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobAttrition(
01213                                                     INT *totalBlobs,
01214                                                     INT *killedBlobs)
01215 {
01216   totalBlobs  = &SIT_totalBlobs;
01217   killedBlobs = &SIT_killedBlobs;
01218 }
01219 
01220 /********************************************************************/
01221 
01222 template SIT_TEMPLATE_CLASS
01223 void segmentImageTrackMC<SIT_TEMPLATE>::SITgetAdaptiveChannelVals(
01224                                         typename std::vector<FLOAT> *mean,
01225                                         typename std::vector<FLOAT> *std)
01226 {
01227   mean = &SIT_chMean1;
01228   std  = &SIT_chStd1;
01229 }
01230 
01231 /********************************************************************/
01232 
01233 template SIT_TEMPLATE_CLASS
01234 unsigned int segmentImageTrackMC<SIT_TEMPLATE>::SITgetLOTcount()
01235 {
01236   return SIT_LOTcount;
01237 }
01238 
01239 /********************************************************************/
01240 
01241 template SIT_TEMPLATE_CLASS
01242 INT segmentImageTrackMC<SIT_TEMPLATE>::SITnumberBlobs()
01243 {
01244   return SIT_segment.SInumberBlobs();
01245 }
01246 
01247 /********************************************************************/
01248 
01249 template SIT_TEMPLATE_CLASS
01250 unsigned short
01251 segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobReasonForKillCode(INT blob)
01252 {
01253   return SIT_reasonForKillCode[blob];
01254 }
01255 
01256 /********************************************************************/
01257 
01258 template SIT_TEMPLATE_CLASS
01259 std::string segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobReasonForKill(INT blob)
01260 {
01261   return SIT_reasonForKill[blob];
01262 }
01263 
01264 /********************************************************************/
01265 
01266 template SIT_TEMPLATE_CLASS
01267 INT segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobMass(INT blob)
01268 {
01269   return SIT_segment.SIgetMass(blob);
01270 }
01271 
01272 /********************************************************************/
01273 
01274 template SIT_TEMPLATE_CLASS
01275 INT segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobPosX(INT blob)
01276 {
01277   return (INT)floor(SIT_segment.SIgetCenterX(blob));
01278 }
01279 
01280 /********************************************************************/
01281 
01282 template SIT_TEMPLATE_CLASS
01283 INT segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobPosY(INT blob)
01284 {
01285   return (INT)floor(SIT_segment.SIgetCenterY(blob));
01286 }
01287 
01288 
01289 /*********************************************************************/
01290 // DRAWING METHODS
01291 /*********************************************************************/
01292 
01293 template SIT_TEMPLATE_CLASS
01294 void segmentImageTrackMC<SIT_TEMPLATE>::SITdrawBlobTrack(INT i)
01295 {
01296   // find boundaries of this blob
01297   unsigned int tt = SIT_segment.SIgetYmin(i);
01298   unsigned int bb = SIT_segment.SIgetYmax(i);
01299   unsigned int ll = SIT_segment.SIgetXmin(i);
01300   unsigned int rr = SIT_segment.SIgetXmax(i);
01301 
01302   // draw bounding box for this blob
01303   // Note: box must be of height > 1 and width > 1
01304   if((bb != tt) && (ll != rr))
01305     drawRectEZ(*SIT_imageHold, Rectangle::tlbrI(tt*DEC,ll*DEC,bb*DEC,rr*DEC),
01306                PixRGB<byte>(SIT_boxRed,
01307                             SIT_boxGreen,
01308                             SIT_boxBlue),1);
01309 
01310   // draw target circle for this blob
01311   drawCircle(*SIT_imageHold, Point2D<int>((int)SIT_segment.SIgetCenterX(i)
01312                                      *DEC
01313                                      ,(int)SIT_segment.SIgetCenterY(i)*DEC)
01314              ,(int)sqrt((float)SIT_segment.SIgetMass(i)),
01315              PixRGB<byte>(SIT_circleRed,
01316                           SIT_circleGreen,
01317                           SIT_circleBlue),2);
01318 
01319   drawCircle(*SIT_imageHold, Point2D<int>((int)SIT_segment.SIgetCenterX(i)
01320                                      *DEC
01321                                      ,(int)SIT_segment.SIgetCenterY(i)*DEC)
01322              ,2,PixRGB<byte>(255,0,0),2);
01323 }
01324 
01325 /*********************************************************************/
01326 
01327 template SIT_TEMPLATE_CLASS
01328 void segmentImageTrackMC<SIT_TEMPLATE>::SITdrawBlobTrackMerged()
01329 {
01330   if((SIT_minY != SIT_maxY) && (SIT_minX != SIT_maxX))
01331     drawRectEZ(*SIT_imageHold, Rectangle::tlbrI(SIT_minY*DEC,SIT_minX*DEC,
01332                                          SIT_maxY*DEC,SIT_maxX*DEC),
01333                PixRGB<byte>(SIT_bigBoxRed,
01334                             SIT_bigBoxGreen,
01335                             SIT_bigBoxBlue),2);
01336 
01337   // draw target circle for this blob
01338   drawCircle(*SIT_imageHold, Point2D<int>((int)SIT_centerX*DEC,(int)SIT_centerY*DEC)
01339              ,(int)sqrt(SIT_mass),
01340              PixRGB<byte>(SIT_bigBoxRed,
01341                           SIT_bigBoxGreen,
01342                           SIT_bigBoxBlue),2);
01343 
01344   drawCircle(*SIT_imageHold, Point2D<int>((int)SIT_centerX*DEC,(int)SIT_centerY*DEC)
01345              ,2,PixRGB<byte>(255,0,0),2);
01346 }
01347 
01348 
01349 
01350 /*********************************************************************/
01351 template SIT_TEMPLATE_CLASS
01352 void segmentImageTrackMC<SIT_TEMPLATE>::SITdrawBlobBox(INT i)
01353 {
01354   // find boundaries of this blob
01355   unsigned int tt = SIT_segment.SIgetYmin(i);
01356   unsigned int bb = SIT_segment.SIgetYmax(i);
01357   unsigned int ll = SIT_segment.SIgetXmin(i);
01358   unsigned int rr = SIT_segment.SIgetXmax(i);
01359 
01360 
01361   // draw bounding box for this blob
01362   // Note: box must be of height > 1 and width > 1
01363   if((bb != tt) && (ll != rr))
01364     drawRectEZ(*SIT_imageHold, Rectangle::tlbrI(tt*DEC,ll*DEC,bb*DEC,rr*DEC),
01365                PixRGB<byte>(SIT_circleRed,
01366                             SIT_circleGreen,
01367                             SIT_circleBlue),1);
01368 }
01369 
01370 /*********************************************************************/
01371 template SIT_TEMPLATE_CLASS
01372 void segmentImageTrackMC<SIT_TEMPLATE>::SITdrawHistoValues(
01373                                            typename std::vector<FLOAT> *mean,
01374                                            typename std::vector<FLOAT> *std,
01375                                            typename std::vector<FLOAT> *lb,
01376                                            typename std::vector<FLOAT> *ub,
01377                                            typename std::vector<FLOAT> *norm,
01378                                            bool LOT)
01379 {
01380   unsigned int minWidth = SIT_barWidth+SIT_barSpace*mean->size();
01381   if((unsigned)SIT_auxHold->getWidth() < minWidth)
01382     SIT_auxHold->resize(minWidth,(int)SIT_histoHeight,true);
01383   // draw background grid in HSV bar graph
01384   if(LOT == false)
01385     drawGrid(*SIT_auxHold, 25,25,1,1,PixRGB<byte>(100,100,100));
01386   else
01387     drawGrid(*SIT_auxHold, 25,25,1,1,PixRGB<byte>(200,100,100));
01388 
01389   typename std::vector<FLOAT>::iterator imean = mean->begin();
01390   typename std::vector<FLOAT>::iterator istd  = std->begin();
01391   typename std::vector<FLOAT>::iterator ilb   = lb->begin();
01392   typename std::vector<FLOAT>::iterator iub   = ub->begin();
01393   typename std::vector<FLOAT>::iterator inorm = norm->begin();
01394 
01395   unsigned int start = SIT_barSpace;
01396   unsigned int end   = SIT_barWidth + start;
01397 
01398   while(imean != mean->end())
01399   {
01400     FLOAT mean = (*imean/(*inorm));
01401     FLOAT std  = (*istd/(*inorm));
01402     FLOAT ub   = (*iub/(*inorm));
01403     FLOAT lb   = (*ilb/(*inorm));
01404 
01405     // draw HSV mean value bars as a bunch of rectangles
01406     drawRectEZ(*SIT_auxHold, Rectangle::tlbrI(0,start,(int)(mean*
01407                                                      SIT_histoHeight),end),
01408                PixRGB<byte>(0,0,255),1);
01409 
01410     // draw standard deviation bars
01411 
01412     if((((mean-std)*SIT_histoHeight) > 0)
01413        && (((mean+std)*SIT_histoHeight) < SIT_auxHold->getHeight()))
01414       drawRectEZ(*SIT_auxHold, Rectangle::tlbrI((int)((mean-std)*SIT_histoHeight)
01415                                          ,start+2,
01416                                          (int)((mean+std)*SIT_histoHeight)
01417                                          ,end-2),
01418                  PixRGB<byte>(255,255,0),1);
01419 
01420 
01421     drawRectEZ(*SIT_auxHold, Rectangle::tlbrI((int)(lb*(SIT_histoHeight-1))
01422                                        ,(signed)start-3,
01423                                        (int)(ub*(SIT_histoHeight-1))
01424                                        ,(signed)start-1),
01425                PixRGB<byte>(255,0,0),1);
01426 
01427 
01428     ++imean, ++istd, ++ilb, ++iub, ++inorm;
01429     start = end   + SIT_barSpace;
01430     end   = start + SIT_barWidth;
01431   }
01432 }
01433 
01434 #undef SIT_TEMPLATE_CLASS
01435 #undef SIT_TEMPLATE
01436 
01437 template class segmentImageTrackMC<float, unsigned int, 3>;
01438 template class segmentImageTrackMC<float, unsigned int, 4>;
01439 
01440 #endif
01441 
01442 // ######################################################################
01443 /* So things look consistent in everyone's emacs... */
01444 /* Local Variables: */
01445 /* indent-tabs-mode: nil */
01446 /* End: */
Generated on Sun May 8 08:42:35 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3