segmentImageTrackMC2.C

Go to the documentation of this file.
00001 /*!@file VFAT/segmentImageTrackMC2.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/segmentImageTrackMC2.C $
00035 // $Id: segmentImageTrackMC2.C 14376 2011-01-11 02:44:34Z pez $
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_C_DEFINED
00049 #define SEGMENTIMAGETRACKMC2_C_DEFINED
00050 
00051 #include "Util/Assert.H"
00052 #include "VFAT/segmentImageTrackMC2.H"
00053 #include "Image/DrawOps.H"
00054 #include "Raster/Raster.H"
00055 
00056 #include <cstdio>
00057 #include <cstdlib>
00058 #include <iostream>
00059 #include <limits>
00060 #include <time.h>
00061 
00062 
00063 //! maximum lose of tracks before color is reset
00064 #define LOTMAX            5
00065 
00066 //! How many iteration to calculate over for movement statistics
00067 #define ERRINTERVAL       5
00068 
00069 //! decimation size reduction factor
00070 //#define DEC               2
00071 
00072 //! Width of channel bars
00073 #define BARWIDTH          10
00074 
00075 //! spacing between channel histo bars
00076 #define BARSPACE          5
00077 
00078 //! histogram height
00079 #define HISTOHEIGHT       450.0F
00080 
00081 /*********************************************************************/
00082 // compute color adaptation
00083 
00084 template SIT_TEMPLATE_CLASS
00085 void segmentImageTrackMC<SIT_TEMPLATE>::SITcolorAdaptation()
00086 {
00087   SIT_totalLifeSpan++;
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       SIT_lifeSpan++;
00187       if(SIT_drawColorAdaptImage == true)
00188         SITdrawHistoValues(&SIT_chMean1,&SIT_chStd1,
00189                            &SIT_chUB,&SIT_chLB,&SIT_chNorm,false);
00190       // (5.b) if adaptive thresholding is turned on, adjust color
00191       // by standard deviation of color. As such each blobs color will
00192       // determin the new tracking color.
00193       istd1        = SIT_chStd1.begin();
00194       ilb          = SIT_chLB.begin();
00195       iub          = SIT_chUB.begin();
00196 
00197       typename std::vector<FLOAT>::iterator iadapt = SIT_chAdapt.begin();
00198       typename std::vector<FLOAT>::iterator instd = SIT_chNSTD.begin();
00199 
00200       for(imean1 = SIT_chMean1.begin(); imean1 != SIT_chMean1.end(); ++imean1,
00201             ++istd1, ++iub, ++ilb, ++instd)
00202       {
00203 
00204         *instd = *istd1*(*iadapt);
00205         if(SIT_useHardBounds == true)
00206         {
00207           if(*imean1 > *iub)
00208           {
00209             *imean1 = *iub;
00210           }
00211           else if(*imean1 < *ilb)
00212           {
00213             *imean1 = *ilb;
00214           }
00215         }
00216       }
00217       if(SIT_useLog == true)
00218       {
00219         std::ofstream outfile(SIT_LOG_FILE,std::ios::app);
00220         outfile << "FRAME " << SIT_frameNumber << " ADAPT " << "\t";
00221         typename std::vector<FLOAT>::iterator instd = SIT_chNSTD.begin();
00222         for(imean1 = SIT_chMean1.begin(); imean1 != SIT_chMean1.end();
00223             ++imean1,++instd)
00224         {
00225           outfile <<  *imean1 << " +/- (" << *instd << ")\t";
00226         }
00227         outfile << "\n";
00228         outfile.close();
00229       }
00230       SIT_segment.SIsetVal(SIT_chMean1,SIT_chNSTD);
00231     }
00232   }
00233   else
00234   {
00235     LINFO("COLOR RESET TO USERS");
00236     SIT_resetColor = false;
00237   }
00238 }
00239 
00240 /*********************************************************************/
00241 template SIT_TEMPLATE_CLASS
00242 void segmentImageTrackMC<SIT_TEMPLATE>::SITresetColor()
00243 {
00244   SIT_segment.SIresetAvg();
00245   SIT_segment.SIsetVal(SIT_initMean,SIT_initStd);
00246 
00247   if(SIT_useLog == true)
00248   {
00249     std::ofstream outfile(SIT_LOG_FILE,std::ios::app);
00250     outfile << "FRAME " << SIT_frameNumber << " RESET " << "\t";
00251     typename std::vector<FLOAT>::iterator imean = SIT_initMean.begin();
00252     typename std::vector<FLOAT>::iterator istd  = SIT_initStd.begin();
00253     while(imean != SIT_initMean.end())
00254     {
00255       outfile <<  *imean << " +/- (" << *istd << ")\t";
00256       ++imean; ++istd;
00257     }
00258     outfile << "\n";
00259     outfile.close();
00260   }
00261 
00262   SIT_segment.SIresetCandidates(true);
00263   SIT_LOTcount      = 0;
00264   SIT_totalLifeSpan = 0;
00265   SIT_lifeSpan      = 0;
00266   SIT_resetColor    = true;
00267   SIT_LOTandRESET   = true;
00268 }
00269 
00270 /*********************************************************************/
00271 // weed out blobs that suck
00272 
00273 template SIT_TEMPLATE_CLASS
00274 void segmentImageTrackMC<SIT_TEMPLATE>::SITanalyzeBlobs()
00275 {
00276   SIT_totalBlobs = SIT_segment.SInumberBlobs();
00277   SIT_killedBlobs = 0;
00278 
00279   // (1.a) We have a loss of track, as such we need to reset some of
00280   // the adaptive parameters. Here we reset the parameter where we
00281   // expect the target to be to a much larger area since we no longer
00282   // can assume its location do to loss of track.
00283   if(SIT_LOT == true)
00284   {
00285     SIT_xBound = SIT_blobProp.BP_LOTbound;
00286     SIT_yBound = SIT_blobProp.BP_LOTbound;
00287   }
00288   else
00289   {
00290     // (1.b) We expect the target to appear close to where we last saw it
00291     // we set a parameter around the last known location. Any blob outside
00292     // this parameter must be predjidist
00293 
00294     SIT_xBound = (int)(SIT_blobProp.BP_bound +
00295                        (SIT_thresh*SIT_blobProp.BP_softBound));
00296     SIT_yBound = (int)(SIT_blobProp.BP_bound +
00297                        (SIT_thresh*SIT_blobProp.BP_softBound));
00298   }
00299 
00300   std::vector<bool>::iterator softCandidateBlobItr
00301     = SIT_softCandidateBlob.begin();
00302   std::vector<bool>::iterator candidateBlobItr
00303     = SIT_candidateBlob.begin();
00304   std::vector<bool>::iterator killedByTrackItr
00305     = SIT_killedByTrack.begin();
00306   std::vector<std::string>::iterator reasonForKillItr
00307     = SIT_reasonForKill.begin();
00308   std::vector<unsigned short>::iterator reasonForKillCodeItr
00309     = SIT_reasonForKillCode.begin();
00310 
00311   std::string S1,S2,S3;
00312   char C1[48], C2[48], C3[48];
00313   // (2) For each blob that the tracker found as a potential target,
00314   // check its properties such as its location in the image vs.
00315   // where we expect the target to be. Also check to make sure that the
00316   // target is geometrically good. That is, make sure its mass, size and
00317   // basic shape conform to our expectations.
00318   for(INT i = 0; i < SIT_totalBlobs; i++,
00319         ++softCandidateBlobItr, ++candidateBlobItr,
00320         ++killedByTrackItr, ++reasonForKillItr, ++reasonForKillCodeItr)
00321   {
00322     *softCandidateBlobItr = true;
00323     *candidateBlobItr     = true;
00324     *killedByTrackItr     = false;
00325     *reasonForKillCodeItr = 0;
00326     *reasonForKillItr     = "(0) Blob OK ";
00327 
00328     // (3) check if a blobs mass is within cosnstraints. That is
00329     // Make sure the blob is neither too large or to small. If so, we
00330     // don't like it.
00331     if((SIT_segment.SIgetMass(i) < (INT)SIT_blobProp.BP_minMass)
00332        && (SIT_blobProp.BP_checkMass == true))
00333     {
00334       *candidateBlobItr     = false;
00335       *softCandidateBlobItr = false;
00336       *killedByTrackItr     = true;
00337       *reasonForKillCodeItr = 1;
00338       SIT_killedBlobs++;
00339 
00340       S1 = " Blob Mass Contraints : Min : ";  S2 = " < ";
00341       sprintf(C1,"%d",(int)SIT_segment.SIgetMass(i));
00342       sprintf(C2,"%d",(int)SIT_blobProp.BP_minMass);
00343       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00344       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00345     }
00346     else if((SIT_segment.SIgetMass(i) > (INT)SIT_blobProp.BP_maxMass)
00347             && (SIT_blobProp.BP_checkMass == true))
00348     {
00349 
00350       *candidateBlobItr     = false;
00351       *softCandidateBlobItr = false;
00352       *killedByTrackItr     = true;
00353       *reasonForKillCodeItr = 2;
00354       SIT_killedBlobs++;
00355 
00356       S1 = " Blob Mass Contraints : Max : ";  S2 = " > ";
00357       sprintf(C1,"%d",(int)SIT_segment.SIgetMass(i));
00358       sprintf(C2,"%d",(int)SIT_blobProp.BP_maxMass);
00359       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00360       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00361     }
00362     // (4) check that a blob is within our X frame. That is, does
00363     // a blob fall in the image in a place where we would expect it
00364     // for instance close to where we last saw it.
00365     else if((SIT_segment.SIgetCenterX(i) < (SIT_centerX - SIT_xBound))
00366             && (SIT_blobProp.BP_checkFrameX == true))
00367     {
00368       *candidateBlobItr     = false;
00369       *killedByTrackItr     = true;
00370       *reasonForKillCodeItr = 3;
00371       SIT_killedBlobs++;
00372 
00373       S1 = " Blob Out of X Frame : Low : "; S2 = " < ";
00374       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterX(i));
00375       sprintf(C2,"%d",(int)(SIT_centerX - SIT_xBound));
00376       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00377       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00378     }
00379     else if((SIT_segment.SIgetCenterX(i) > (SIT_centerX + SIT_xBound))
00380             && (SIT_blobProp.BP_checkFrameX == true))
00381     {
00382       *candidateBlobItr     = false;
00383       *killedByTrackItr     = true;
00384       *reasonForKillCodeItr = 4;
00385       SIT_killedBlobs++;
00386 
00387       S1 = " Blob Out of X Frame : High : "; S2 = " > ";
00388       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterX(i));
00389       sprintf(C2,"%d",(int)(SIT_centerX + SIT_xBound));
00390       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00391       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00392     }
00393     // (5) check that a blob is within our Y frame. That is, does
00394     // a blob fall in the image in a place where we would expect it
00395     // for instance close to where we last saw it.
00396     else if((SIT_segment.SIgetCenterY(i) < (SIT_centerY - SIT_yBound))
00397             && (SIT_blobProp.BP_checkFrameY == true))
00398     {
00399       *candidateBlobItr     = false;
00400       *killedByTrackItr     = true;
00401       *reasonForKillCodeItr = 5;
00402       SIT_killedBlobs++;
00403 
00404       S1 = " Blob Out of Y Frame : Low : "; S2 = " < ";
00405       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterY(i));
00406       sprintf(C2,"%d",(int)(SIT_centerY - SIT_yBound));
00407       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00408       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00409     }
00410     else if((SIT_segment.SIgetCenterY(i) > (SIT_centerY + SIT_yBound))
00411             && (SIT_blobProp.BP_checkFrameY == true))
00412     {
00413       *candidateBlobItr     = false;
00414       *killedByTrackItr     = true;
00415       *reasonForKillCodeItr = 6;
00416       SIT_killedBlobs++;
00417 
00418       S1 = " Blob Out of Y Frame : High : "; S2 = " > ";
00419       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterY(i));
00420       sprintf(C2,"%d",(int)(SIT_centerY + SIT_yBound));
00421       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00422       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00423     }
00424     // (6) check that a blob is within our EXPECTED X frame. That is, does
00425     // a blob fall in the image in a place where we would expect it
00426     // for instance close to where we last saw it.
00427     // This is used only if we apriori set this value
00428     else if((SIT_segment.SIgetCenterX(i) > SIT_expectedXmax) &&
00429             (SIT_useExpectedLocation == true))
00430     {
00431       *candidateBlobItr     = false;
00432       *killedByTrackItr     = true;
00433       *reasonForKillCodeItr = 7;
00434       SIT_killedBlobs++;
00435 
00436       S1 = " Blob Out of Set Expected X Frame : High : "; S2 = " > ";
00437       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterX(i));
00438       sprintf(C2,"%d",(int)(SIT_expectedXmax));
00439       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00440       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00441     }
00442     else if((SIT_segment.SIgetCenterX(i) < SIT_expectedXmin) &&
00443             (SIT_useExpectedLocation == true))
00444     {
00445       *candidateBlobItr     = false;
00446       *killedByTrackItr     = true;
00447       *reasonForKillCodeItr = 8;
00448       SIT_killedBlobs++;
00449 
00450       S1 = " Blob Out of Set Expected X Frame : Low : "; S2 = " < ";
00451       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterX(i));
00452       sprintf(C2,"%d",(int)(SIT_expectedXmin));
00453       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00454       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00455     }
00456     // (7) check that a blob is within our EXPECTED Y frame. That is, does
00457     // a blob fall in the image in a place where we would expect it
00458     // for instance close to where we last saw it.
00459     // This is used only if we apriori set this value
00460     else if((SIT_segment.SIgetCenterY(i) > SIT_expectedYmax) &&
00461             (SIT_useExpectedLocation == true))
00462     {
00463       *candidateBlobItr     = false;
00464       *killedByTrackItr     = true;
00465       *reasonForKillCodeItr = 9;
00466       SIT_killedBlobs++;
00467 
00468       S1 = " Blob Out of Set Expected Y Frame : High : "; S2 = " > ";
00469       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterY(i));
00470       sprintf(C2,"%d",(int)(SIT_expectedYmax));
00471       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00472       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00473     }
00474     else if((SIT_segment.SIgetCenterY(i) < SIT_expectedYmin) &&
00475             (SIT_useExpectedLocation == true))
00476     {
00477       *candidateBlobItr     = false;
00478       *killedByTrackItr     = true;
00479       *reasonForKillCodeItr = 10;
00480       SIT_killedBlobs++;
00481 
00482       S1 = " Blob Out of Set Expected Y Frame : Low : "; S2 = " < ";
00483       sprintf(C1,"%d",(int)SIT_segment.SIgetCenterY(i));
00484       sprintf(C2,"%d",(int)(SIT_expectedYmin));
00485       sprintf(C3,"(%d)",*reasonForKillCodeItr);
00486       *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00487     }
00488     // (8) check that blob is within size ratios. That is, does the
00489     // blob have a proper height and width for the target as we would
00490     // expect. For instance, as head should have a height and width that
00491     // are about the same.
00492     else if(SIT_blobProp.BP_checkSizeRatios == true)
00493     {
00494       FLOAT foo = (SIT_segment.SIgetXmax(i) - SIT_segment.SIgetXmin(i));
00495       if(foo != 0)
00496       {
00497         FLOAT temp = (SIT_segment.SIgetYmax(i)
00498                       - SIT_segment.SIgetYmin(i))/foo;
00499 
00500         if(temp < (SIT_blobProp.BP_ratioMin
00501                    + (SIT_thresh*SIT_blobProp.BP_softRatioMin)))
00502         {
00503           *candidateBlobItr     = false;
00504           *killedByTrackItr     = true;
00505           *reasonForKillCodeItr = 11;
00506           SIT_killedBlobs++;
00507 
00508           S1 = " Blob Size Ratios Contraint : Min :"; S2 = " < ";
00509           sprintf(C1,"%d",(int)temp);
00510           sprintf(C2,"%d",(int)(SIT_blobProp.BP_ratioMin
00511                                 + (SIT_thresh*SIT_blobProp.BP_softRatioMin)));
00512           sprintf(C3,"(%d)",*reasonForKillCodeItr);
00513           *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00514         }
00515         else if (temp > (SIT_blobProp.BP_ratioMax
00516                          + (SIT_thresh*SIT_blobProp.BP_softRatioMin)))
00517         {
00518           *candidateBlobItr     = false;
00519           *killedByTrackItr     = true;
00520           *reasonForKillCodeItr = 12;
00521           SIT_killedBlobs++;
00522 
00523           S1 = " Blob Size Ratios Contraint : Max : "; S2 = " > ";
00524           sprintf(C1,"%d",(int)temp);
00525           sprintf(C2,"%d",(int)(SIT_blobProp.BP_ratioMax
00526                                 + (SIT_thresh*SIT_blobProp.BP_softRatioMin)));
00527           sprintf(C3,"(%d)",*reasonForKillCodeItr);
00528           *reasonForKillItr = C3 + S1 + C1 + S2 + C2;
00529         }
00530       }
00531     }
00532   }
00533 }
00534 
00535 
00536 /*********************************************************************/
00537 // merge all remaining blobs into a single new blob
00538 
00539 template SIT_TEMPLATE_CLASS
00540 void segmentImageTrackMC<SIT_TEMPLATE>::SITmergeBlobs()
00541 {
00542   SIT_mass    = 0;
00543   FLOAT meanX = 0;
00544   FLOAT meanY = 0;
00545   // changed from UINT_MAX to std::numeric_limits<unsigned
00546   // short>::max() to avoid "warning: large integer implicitly
00547   // truncated to unsigned type" from g++ 4.1
00548   SIT_minX    = std::numeric_limits<unsigned short>::max();
00549   SIT_minY    = std::numeric_limits<unsigned short>::max();
00550   SIT_maxX    = 0;
00551   SIT_maxY    = 0;
00552 
00553   // calculate the center of a combined blob from the average
00554   // mass center of all remaining blobs
00555   std::vector<bool>::iterator candidateBlobItr = SIT_candidateBlob.begin();
00556 
00557   for(INT i = 0; i < SIT_segment.SInumberBlobs(); i++, ++candidateBlobItr)
00558   {
00559     if(*candidateBlobItr == true)
00560     {
00561       SIT_mass += SIT_segment.SIgetMass(i);
00562       meanX    += SIT_segment.SIgetMass(i)*SIT_segment.SIgetCenterX(i);
00563       meanY    += SIT_segment.SIgetMass(i)*SIT_segment.SIgetCenterY(i);
00564 
00565       if((unsigned)SIT_segment.SIgetXmax(i) > SIT_maxX)
00566                                 SIT_maxX = SIT_segment.SIgetXmax(i);
00567 
00568       if((unsigned)SIT_segment.SIgetYmax(i) > SIT_maxY)
00569                                 SIT_maxY = SIT_segment.SIgetYmax(i);
00570 
00571       if((unsigned)SIT_segment.SIgetXmin(i) < SIT_minX)
00572                                 SIT_minX = SIT_segment.SIgetXmin(i);
00573 
00574       if((unsigned)SIT_segment.SIgetYmin(i) < SIT_minY)
00575                                 SIT_minY = SIT_segment.SIgetYmin(i);
00576     }
00577   }
00578 
00579   // Compute SIT_LOT here and set
00580   if(SIT_mass != 0)
00581   {
00582     SIT_centerX = (int)(meanX/SIT_mass);
00583     SIT_centerY = (int)(meanY/SIT_mass);
00584 
00585     if(((SIT_maxX-SIT_minX)*(SIT_maxY-SIT_minY)) >
00586        ((SIT_segment.SIgetImageSizeX()*SIT_segment.SIgetImageSizeY())
00587         /SIT_blobProp.BP_maxFrameSize))
00588     {
00589       SIT_LOT         = true;
00590       SIT_LOTtype     = 1;
00591       SIT_LOTtypeName = "(1) Postive Mass but Spacially too Large";
00592     }
00593     else
00594     {
00595       SIT_LOT                 = false;
00596       SIT_LOTtypeName         = "(0) NO LOT, OK";
00597       SIT_useExpectedLocation = false;
00598     }
00599   }
00600   else
00601   {
00602     SIT_LOTtypeName = "(2) Zero Mass in merged blobs";
00603     SIT_LOTtype = 2;
00604     SIT_LOT     = true;
00605 
00606     // JACOB: changed this to fixed values instead of calling
00607     // a pointer that may or may not be assigned to something
00608     SIT_centerX = SIT_x_center;
00609     SIT_centerY = SIT_y_center;
00610   }
00611 }
00612 
00613 /*********************************************************************/
00614 // PUBLIC ACCESS METHODS
00615 /*********************************************************************/
00616 
00617 // When called at the start, this will resize all the vectors we use
00618 // We only call this once since it is expensive to call.
00619 template SIT_TEMPLATE_CLASS
00620 segmentImageTrackMC<SIT_TEMPLATE>::segmentImageTrackMC(INT maxBlobCount)
00621 {
00622   SIT_LOTcount            = 0;
00623   SIT_frameNumber         = 0;
00624   SIT_useLog              = false;
00625   SIT_drawTargetImage     = true;
00626   SIT_drawColorAdaptImage = true;
00627   SIT_useColorAdaptation  = true;
00628   SIT_editBlobs           = true;
00629   SIT_useHardBounds       = false;
00630 
00631   time_t t       = time(0);
00632   std::string theTime = asctime(localtime(&t));
00633 
00634   std::ofstream outfile(SIT_LOG_FILE,std::ios::out);
00635   outfile << theTime << "\n";
00636   outfile.close();
00637 
00638   SIT_draw           = false;
00639   SIT_didCircleColor = false;
00640   SIT_didBoxColor    = false;
00641   SIT_didTrackColor  = false;
00642 
00643   // resize a bunch of std contaner vectors
00644 
00645   SIT_chMean1.resize( SIT_channels,0);
00646   SIT_chMean2.resize( SIT_channels,0);
00647   SIT_chStd1.resize(  SIT_channels,0);
00648   SIT_chStd2.resize(  SIT_channels,0);
00649   SIT_chLB.resize(    SIT_channels,0);
00650   SIT_chUB.resize(    SIT_channels,0);
00651   SIT_chNSTD.resize(  SIT_channels,0);
00652   SIT_chAdapt.resize( SIT_channels,0);
00653   SIT_chSkew.resize(  SIT_channels,0);
00654   SIT_initMean.resize(SIT_channels,0);
00655   SIT_initStd.resize( SIT_channels,0);
00656 
00657   SIT_softCandidateBlob.resize(maxBlobCount,false);
00658   SIT_candidateBlob.resize(    maxBlobCount,false);
00659   SIT_killedByTrack.resize(    maxBlobCount,false);
00660   SIT_blobList.resize(         maxBlobCount,0);
00661   SIT_reasonForKill.resize(    maxBlobCount,"no reason");
00662   SIT_reasonForKillCode.resize(maxBlobCount,0);
00663 
00664   SIT_barWidth    = BARWIDTH;
00665   SIT_barSpace    = BARSPACE;
00666   SIT_histoHeight = HISTOHEIGHT;
00667 
00668 
00669   // Load the config file and set a whole bunch of parameters from it
00670 
00671   blobConf.openFile("blob.conf",true);
00672 
00673   SIT_blobProp.BP_LOTbound     = (int)blobConf.getItemValueF("BP_LOTbound");
00674   SIT_blobProp.BP_bound        = (int)blobConf.getItemValueF("BP_bound");
00675   SIT_blobProp.BP_softBound    = (int)blobConf.getItemValueF("BP_softBound");
00676   SIT_blobProp.BP_lowBound     = (int)blobConf.getItemValueF("BP_lowBound");
00677   SIT_blobProp.BP_traj         = (int)blobConf.getItemValueF("BP_traj");
00678   SIT_blobProp.BP_sampleStart  = (int)blobConf.getItemValueF("BP_sampleStart");
00679   SIT_blobProp.BP_maxTraj      = (int)blobConf.getItemValueF("BP_maxTraj");
00680   SIT_blobProp.BP_maxSize      = (int)blobConf.getItemValueF("BP_maxSize");
00681   SIT_blobProp.BP_minSize      = (int)blobConf.getItemValueF("BP_minSize");
00682   SIT_blobProp.BP_maxFrameSize = blobConf.getItemValueF("BP_maxFrameSize");
00683   SIT_blobProp.BP_minMass      = (int)blobConf.getItemValueF("BP_minMass");
00684   SIT_blobProp.BP_maxMass      = (int)blobConf.getItemValueF("BP_maxMass");
00685   SIT_blobProp.BP_ratioMin     = blobConf.getItemValueF("BP_ratioMin");
00686   SIT_blobProp.BP_softRatioMin = blobConf.getItemValueF("BP_softRatioMin");
00687   SIT_blobProp.BP_ratioMax     = blobConf.getItemValueF("BP_ratioMax");
00688   SIT_blobProp.BP_softRatioMax = blobConf.getItemValueF("BP_softRatioMax");
00689   SIT_blobProp.BP_checkMass    = blobConf.getItemValueB("BP_checkMass");
00690   SIT_blobProp.BP_checkFrameX  = blobConf.getItemValueB("BP_checkFrameX");
00691   SIT_blobProp.BP_checkFrameY  = blobConf.getItemValueB("BP_checkFrameY");
00692   SIT_blobProp.BP_checkSizeRatios =
00693     blobConf.getItemValueB("BP_checkSizeRatios");
00694 
00695 }
00696 
00697 /*********************************************************************/
00698 
00699 template SIT_TEMPLATE_CLASS
00700 segmentImageTrackMC<SIT_TEMPLATE>::~segmentImageTrackMC()
00701 {}
00702 
00703 /*********************************************************************/
00704 
00705 template SIT_TEMPLATE_CLASS
00706 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetCircleColor(unsigned char r,
00707                                                           unsigned char g,
00708                                                           unsigned char b)
00709 {
00710   SIT_circleRed      = r;
00711   SIT_circleBlue     = g;
00712   SIT_circleGreen    = b;
00713   SIT_didCircleColor = true;
00714 }
00715 
00716 /*********************************************************************/
00717 
00718 template SIT_TEMPLATE_CLASS
00719 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetBoxColor(unsigned char r,
00720                                                        unsigned char g,
00721                                                        unsigned char b,
00722                                                        unsigned char bigr,
00723                                                        unsigned char bigg,
00724                                                        unsigned char bigb)
00725 {
00726   SIT_boxRed      = r;
00727   SIT_boxGreen    = g;
00728   SIT_boxBlue     = b;
00729   SIT_bigBoxRed   = bigr;
00730   SIT_bigBoxGreen = bigg;
00731   SIT_bigBoxBlue  = bigb;
00732   SIT_didBoxColor = true;
00733 }
00734 
00735 
00736 /*********************************************************************/
00737 
00738 template SIT_TEMPLATE_CLASS
00739 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetTrackSignature(
00740                                     const covHolder<double> *cov,
00741                                     segHolder<FLOAT,INT,SIT_channels>  *seg)
00742 {
00743   std::vector<unsigned short>::iterator channelMap = seg->channelMap.begin();
00744   typename std::vector<FLOAT>::iterator initMean = SIT_initMean.begin();
00745   typename std::vector<FLOAT>::iterator initStd  = SIT_initStd.begin();
00746   typename std::vector<FLOAT>::iterator chUB     = SIT_chUB.begin();
00747   typename std::vector<FLOAT>::iterator chLB     = SIT_chLB.begin();
00748   typename std::vector<FLOAT>::iterator norm     = SIT_chNorm.begin();
00749   typename std::vector<FLOAT>::iterator STDmod   = seg->STDmod.begin();
00750   typename std::vector<FLOAT>::iterator UBMod    = seg->upperBoundMod.begin();
00751   typename std::vector<FLOAT>::iterator LBMod    = seg->lowerBoundMod.begin();
00752 
00753   std::ofstream outfile1(SIT_LOG_FILE,std::ios::app);
00754 
00755   for(unsigned int i = 0; i < seg->dim; i++, ++channelMap,
00756         ++initMean, ++initStd, ++chUB, ++chLB, ++norm,
00757         ++STDmod, ++UBMod, ++LBMod)
00758   {
00759     const unsigned int cmap = *channelMap;
00760     const FLOAT covMean     = cov->mean[cmap];
00761     const FLOAT covBias     = cov->bias[cmap];
00762 
00763     // Set mean value on this channel from covHolder
00764     *initMean = covMean / covBias;
00765     // Set standard deviation on this channel from covHolder
00766     *initStd  = (cov->STD[cmap] * (1/covBias)) * (*STDmod);
00767     // Set upperBound on this channel from covHolder
00768     *chUB     = covMean / covBias + (*UBMod);
00769     // Set lowerBount on this channel from covHolder
00770     *chLB     = covMean / covBias - (*LBMod);
00771     // set the norm from this channel from covHolder (in feature.conf)
00772     *norm     = cov->norm[cmap];
00773     if(SIT_useLog == true)
00774     {
00775       outfile1 << "Setting channel segHolder " << seg->baseID
00776                << " via covHolder " << cov->baseID
00777                << " - Matching "    << seg->featureName[i]
00778                << " To "            << cov->featureName[cmap]
00779                << "\t- Value: "      << covMean
00780                << "  STD: "         << cov->STD[cmap]
00781                << "  Bias: "        << covBias
00782                << "\n";
00783     }
00784   }
00785 
00786   outfile1.close();
00787 
00788 
00789   SIT_chAdapt = seg->channelAdapt;
00790   // reset the frame to the center
00791   SITsetFrame(&seg->imageSizeX,&seg->imageSizeY);
00792   // where should the target appear?
00793   seg->expectedX    = cov->posX; seg->expectedY    = cov->posY;
00794   seg->expectedXmin = cov->minX; seg->expectedYmin = cov->minY;
00795   seg->expectedXmax = cov->maxX; seg->expectedYmax = cov->maxY;
00796 
00797   SITsetExpectedTargetPosition(cov->posX, cov->posY, cov->maxX,
00798                                cov->maxY, cov->minX, cov->minY);
00799 
00800   // reset some values we need to reset when uploading new sig.
00801   SIT_thresh         = 1;
00802   SIT_didTrackColor  = true;
00803   SIT_resetColor     = true;
00804   SIT_LOTcount       = 0;
00805   SIT_totalLifeSpan  = 0;
00806   SIT_lifeSpan       = 0;
00807   seg->LOTcount      = SIT_LOTcount;
00808   seg->totalLifeSpan = SIT_totalLifeSpan;
00809   seg->lifeSpan      = SIT_lifeSpan;
00810 
00811   SIT_segment.SIsetAvg(ERRINTERVAL);
00812   SIT_segment.SIresetAvg();
00813   SIT_segment.SIsetVal(SIT_initMean,SIT_initStd);
00814   if(SIT_useLog == true)
00815   {
00816     std::ofstream outfile(SIT_LOG_FILE,std::ios::app);
00817     outfile << "FRAME " << SIT_frameNumber << " INIT " << "\t";
00818     typename std::vector<FLOAT>::iterator imean = SIT_initMean.begin();
00819     typename std::vector<FLOAT>::iterator istd  = SIT_initStd.begin();
00820     while(imean != SIT_initMean.end())
00821     {
00822       outfile <<  *imean << " +/- (" << *istd << ")\t";
00823       ++imean; ++istd;
00824     }
00825     outfile << "\n";
00826     outfile.close();
00827   }
00828 }
00829 
00830 /*********************************************************************/
00831 
00832 template SIT_TEMPLATE_CLASS
00833 void segmentImageTrackMC<SIT_TEMPLATE>::SITgetTrackSignature(
00834                                     segHolder<FLOAT,INT,SIT_channels>  *seg)
00835 {
00836   SITgetBlobPosition(&(seg->posX),&(seg->posY));
00837   SITgetMinMaxBoundry(&(seg->minX),&(seg->maxX),&(seg->minY),&(seg->maxY));
00838   SITgetAdaptiveChannelVals(&(seg->mean),&(seg->STD));
00839   SITgetBlobAttrition(&(seg->blobNumber),&(seg->killedBlobs));
00840   SITgetLifeSpans(&(seg->totalLifeSpan),&(seg->lifeSpan));
00841   seg->mass        = (unsigned int)ceil(SITgetMass());
00842   seg->LOT         = SITreturnLOT();
00843   seg->LOTtype     = SITreturnLOTtype();
00844   seg->LOTtypeName = SITreturnLOTtypeName();
00845   seg->LOTcount    = SITgetLOTcount();
00846   seg->LOTandReset = SIT_LOTandRESET;
00847   seg->boundaryX   = SIT_xBound * SIT_GLOBAL_DEC;
00848   seg->boundaryY   = SIT_yBound * SIT_GLOBAL_DEC;
00849 }
00850 
00851 /*********************************************************************/
00852 template SIT_TEMPLATE_CLASS
00853 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetTrackColor(
00854                                     typename std::vector<FLOAT> color,
00855                                     typename std::vector<FLOAT> std,
00856                                     typename std::vector<FLOAT> norm,
00857                                     typename std::vector<FLOAT> adapt,
00858                                     typename std::vector<FLOAT> upperBound,
00859                                     typename std::vector<FLOAT> lowerBound,
00860                                     bool resetColor,
00861                                     bool resetCandidates)
00862 {
00863   // make sure that all our contaners are the same size
00864   ASSERT(color.size()      == std.size());
00865   ASSERT(std.size()        == norm.size());
00866   ASSERT(norm.size()       == adapt.size());
00867   ASSERT(adapt.size()      == upperBound.size());
00868   ASSERT(upperBound.size() == lowerBound.size());
00869 
00870   // set initial tracking parameters
00871   SIT_thresh        = 1;
00872   SIT_initMean      = color;
00873   SIT_initStd       = std;
00874   SIT_chNorm        = norm;
00875   SIT_chAdapt       = adapt;
00876   SIT_chUB          = upperBound;
00877   SIT_chLB          = lowerBound;
00878   SIT_didTrackColor = true;
00879   SIT_totalLifeSpan = 0;
00880   SIT_lifeSpan      = 0;
00881   SIT_LOTcount      = 0;
00882   SIT_segment.SIsetAvg(ERRINTERVAL);
00883   SIT_segment.SIresetAvg();
00884   SIT_segment.SIsetVal(SIT_initMean,SIT_initStd);
00885 
00886   if(SIT_useLog == true)
00887   {
00888     std::ofstream outfile(SIT_LOG_FILE,std::ios::app);
00889     outfile << "FRAME " << SIT_frameNumber << " INIT " << "\t";
00890     typename std::vector<FLOAT>::iterator imean = SIT_initMean.begin();
00891     typename std::vector<FLOAT>::iterator istd  = SIT_initStd.begin();
00892     while(imean != SIT_initMean.end())
00893     {
00894       outfile <<  *imean << " +/- (" << *istd << ")\t";
00895       ++imean; ++istd;
00896     }
00897     outfile << "\n";
00898     outfile.close();
00899   }
00900 
00901 
00902   SIT_resetColor = resetColor;
00903   if(resetCandidates == true)
00904     SIT_segment.SIresetCandidates(true);
00905 }
00906 
00907 
00908 /*********************************************************************/
00909 
00910 template SIT_TEMPLATE_CLASS
00911 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetFrame(unsigned short *x,
00912                                                     unsigned short *y)
00913 {
00914   int xx = *x / SIT_GLOBAL_DEC; int yy = *y / SIT_GLOBAL_DEC;
00915   SIT_segment.SIsetFrame(&xx,&yy);
00916   SIT_x_center = xx/2;
00917   SIT_y_center = yy/2;
00918   SIT_centerX = SIT_x_center;
00919   SIT_centerY = SIT_y_center;
00920 }
00921 
00922 /*********************************************************************/
00923 
00924 template SIT_TEMPLATE_CLASS
00925 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetUseSmoothing(bool smoothing, FLOAT alpha)
00926 {
00927   SIT_useSmoothing   = smoothing;
00928   SIT_smoothingAlpha = alpha;
00929   SIT_didSmoothing   = false;
00930 }
00931 
00932 /*********************************************************************/
00933 template SIT_TEMPLATE_CLASS
00934 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetExpectedTargetPosition(
00935                                               const unsigned short posX,
00936                                               const unsigned short posY,
00937                                               const unsigned short maxX,
00938                                               const unsigned short maxY,
00939                                               const unsigned short minX,
00940                                               const unsigned short minY)
00941 {
00942   SIT_expectedX           = posX / SIT_GLOBAL_DEC;
00943   SIT_expectedY           = posY / SIT_GLOBAL_DEC;
00944   SIT_expectedXmax        = maxX / SIT_GLOBAL_DEC;
00945   SIT_expectedYmax        = maxY / SIT_GLOBAL_DEC;
00946   SIT_expectedXmin        = minX / SIT_GLOBAL_DEC;
00947   SIT_expectedYmin        = minY / SIT_GLOBAL_DEC;
00948   SIT_useExpectedLocation = true;
00949 }
00950 
00951 /*********************************************************************/
00952 template SIT_TEMPLATE_CLASS
00953 void segmentImageTrackMC<SIT_TEMPLATE>::SITgetExpectedTargetPosition(
00954                                               unsigned short *posX,
00955                                               unsigned short *posY,
00956                                               unsigned short *maxX,
00957                                               unsigned short *maxY,
00958                                               unsigned short *minX,
00959                                               unsigned short *minY,
00960                                               bool *isSet) const
00961 {
00962   unsigned short pX  = SIT_expectedX    * SIT_GLOBAL_DEC;
00963   unsigned short pY  = SIT_expectedY    * SIT_GLOBAL_DEC;
00964   unsigned short XM  = SIT_expectedXmax * SIT_GLOBAL_DEC;
00965   unsigned short YM  = SIT_expectedYmax * SIT_GLOBAL_DEC;
00966   unsigned short xM  = SIT_expectedXmin * SIT_GLOBAL_DEC;
00967   unsigned short yM  = SIT_expectedYmin * SIT_GLOBAL_DEC;
00968   bool is            = SIT_useExpectedLocation;
00969 
00970   *posX  = pX; *posY  = pY;
00971   *maxX  = XM; *maxY  = YM;
00972   *minX  = xM; *minY  = yM;
00973 
00974   *isSet = is;
00975 }
00976 
00977 /*********************************************************************/
00978 template SIT_TEMPLATE_CLASS
00979 void segmentImageTrackMC<SIT_TEMPLATE>::SITunsetExpectedTargetPosition()
00980 {
00981   SIT_useExpectedLocation = false;
00982 }
00983 
00984 /*********************************************************************/
00985 template SIT_TEMPLATE_CLASS
00986 bool segmentImageTrackMC<SIT_TEMPLATE>::SITintersection(
00987                                               const covHolder<double> *cov,
00988                                               const int boundX,
00989                                               const int boundY) const
00990 {
00991   int maxX,maxY,minX,minY;
00992   bool Xok = false;
00993   bool Yok = false;
00994 
00995   // what are the bounds of this object?
00996   // store and multiply by decimation reduction factor
00997   if(SIT_lifeSpan > 1)
00998   {
00999     minX = (signed)SIT_minX*SIT_GLOBAL_DEC;
01000     maxX = (signed)SIT_maxX*SIT_GLOBAL_DEC;
01001     minY = (signed)SIT_minY*SIT_GLOBAL_DEC;
01002     maxY = (signed)SIT_maxY*SIT_GLOBAL_DEC;
01003   }
01004   else
01005   {
01006     minX = (signed)SIT_expectedXmin*SIT_GLOBAL_DEC;
01007     maxX = (signed)SIT_expectedXmax*SIT_GLOBAL_DEC;
01008     minY = (signed)SIT_expectedYmin*SIT_GLOBAL_DEC;
01009     maxY = (signed)SIT_expectedYmax*SIT_GLOBAL_DEC;
01010   }
01011 
01012   // check for intersection with other objects
01013   if((((signed)cov->minX < minX-boundX) &&
01014       ((signed)cov->maxX < minX-boundX)) ||
01015      (((signed)cov->minX > maxX+boundX) &&
01016       ((signed)cov->maxX > maxX+boundX)))
01017   {
01018     Xok = true;
01019   }
01020 
01021   if((((signed)cov->minY < minY-boundY) &&
01022       ((signed)cov->maxY < minY-boundY)) ||
01023      (((signed)cov->minY > maxY+boundY) &&
01024       ((signed)cov->maxY > maxY+boundY)))
01025   {
01026     Yok = true;
01027   }
01028 
01029   if((Xok == false) && (Yok == false))
01030   {
01031     return false;
01032   }
01033   // else
01034   return true;
01035 }
01036 
01037 /*********************************************************************/
01038 template SIT_TEMPLATE_CLASS
01039 void segmentImageTrackMC<SIT_TEMPLATE>::SITpercentOverlap(
01040                            const segHolder<FLOAT,INT,SIT_channels>  *seg,
01041                            FLOAT *overlap,
01042                            FLOAT *thisArea,
01043                            FLOAT *otherArea) const
01044 {
01045   const int minX = (signed)SIT_minX*SIT_GLOBAL_DEC;
01046   const int maxX = (signed)SIT_maxX*SIT_GLOBAL_DEC;
01047   const int minY = (signed)SIT_minY*SIT_GLOBAL_DEC;
01048   const int maxY = (signed)SIT_maxY*SIT_GLOBAL_DEC;
01049 
01050   // Find which parts overlap, if any
01051   bool olapX = false;
01052   bool olapY = false;
01053   bool sMinX = false;  bool sMaxX = false;
01054   bool sMinY = false;  bool sMaxY = false;
01055 
01056   // What are the intersections?
01057   if((seg->minX > minX) && (seg->minX < maxX))
01058     { sMinX = true; olapX = true;}
01059   if((seg->maxX > minX) && (seg->maxX < maxX))
01060     { sMaxX = true; olapX = true;}
01061   if((seg->minY > minY) && (seg->minY < maxY))
01062     { sMinY = true; olapY = true;}
01063   if((seg->maxY > minY) && (seg->maxY < maxY))
01064     { sMaxY = true; olapY = true;}
01065 
01066   // If intersection, computer percent overlap
01067   // else no intersection, return 0
01068   if(olapX && olapY)
01069   {
01070     // else find the area of the overlap, then the percentage
01071 
01072     const FLOAT slenX = seg->maxX - seg->minX;
01073     const FLOAT slenY = seg->maxY - seg->minY;
01074     *otherArea = slenX*slenY;
01075 
01076     const FLOAT lenX = maxX - minX;
01077     const FLOAT lenY = maxY - minY;
01078     *thisArea = lenX*lenY;
01079 
01080     // average the area. This forces the overlap to be a function
01081     // of the similarity if the two targets sizes.
01082 
01083     const FLOAT avgArea = ((*thisArea)+(*otherArea))/2;
01084 
01085     FLOAT diffX = 0.0F; FLOAT diffY = 0.0F;
01086     if(     (sMinX == true)  && (sMaxX == false))
01087       diffX = maxX      - seg->minX;
01088     else if((sMinX == false) && (sMaxX == true))
01089       diffX = seg->maxX - minX;
01090     else
01091       diffX = slenX;
01092 
01093     if(     (sMinY == true)  && (sMaxY == false))
01094       diffY = maxY      - seg->minY;
01095     else if((sMinY == false) && (sMaxY == true))
01096       diffY = seg->maxY - minY;
01097     else
01098       diffY = slenY;
01099 
01100     const FLOAT oarea = diffX*diffY;
01101     *overlap = oarea/avgArea;
01102     return;
01103   }
01104 
01105   *overlap = 0.0F;
01106   return;
01107 }
01108 
01109 
01110 
01111 /*********************************************************************/
01112 template SIT_TEMPLATE_CLASS
01113 void segmentImageTrackMC<SIT_TEMPLATE>::SITtoggleCandidateBandPass(bool toggle)
01114 {
01115   SIT_segment.SItoggleCandidateBandPass(toggle);
01116 }
01117 /*********************************************************************/
01118 template SIT_TEMPLATE_CLASS
01119 void segmentImageTrackMC<SIT_TEMPLATE>::SITtoggleColorAdaptation(bool toggle)
01120 {
01121   SIT_useColorAdaptation = toggle;
01122 }
01123 
01124 /*********************************************************************/
01125 template SIT_TEMPLATE_CLASS
01126 void segmentImageTrackMC<SIT_TEMPLATE>::SITtoggleHardBounds(bool toggle)
01127 {
01128   SIT_useHardBounds = toggle;
01129 }
01130 
01131 /*********************************************************************/
01132 template SIT_TEMPLATE_CLASS
01133 void segmentImageTrackMC<SIT_TEMPLATE>::SITsetFrameNumber(unsigned long frame)
01134 {
01135   SIT_frameNumber = frame;
01136 }
01137 
01138 /*********************************************************************/
01139 template SIT_TEMPLATE_CLASS
01140 void segmentImageTrackMC<SIT_TEMPLATE>::SITeditBlobs(bool toggle)
01141 {
01142   SIT_editBlobs = toggle;
01143 }
01144 
01145 /*********************************************************************/
01146 // MAIN METHOD
01147 /*********************************************************************/
01148 
01149 /* This is a basic tracker access method that tracks on one image at a time */
01150 /* this one is designed to work with any Pixels pixel */
01151 
01152 template SIT_TEMPLATE_CLASS
01153 void segmentImageTrackMC<SIT_TEMPLATE>::SITtrackImage
01154                                (Image<PixH2SV2<FLOAT> > &input,
01155                                 Image<PixRGB<byte> > *output)
01156 {
01157   // Assert that parameters have been set up before starting
01158   ASSERT(SIT_didCircleColor == true);
01159   ASSERT(SIT_didBoxColor    == true);
01160   ASSERT(SIT_didTrackColor  == true);
01161 
01162   SIT_imageHold = output;
01163 
01164   // decimate input image twice to speed things up
01165   if(SIT_GLOBAL_DEC >= 2)
01166     input         = decXY(input);
01167   if(SIT_GLOBAL_DEC >= 4)
01168     input         = decXY(input);
01169   if(SIT_GLOBAL_DEC >= 8)
01170     input         = decXY(input);
01171 
01172   Image<FLOAT> timage;
01173   timage.resize(input.getWidth(),input.getHeight(),true);
01174   SIT_chans.resize(SIT_channels,timage);
01175   for(unsigned int i = 0; i < SIT_channels; i++)
01176   {
01177     typename Image<FLOAT>::iterator iSIT_chans = SIT_chans[i].beginw();
01178     for(typename Image<PixH2SV2<FLOAT> >::iterator
01179         iinput = input.beginw();
01180         iinput != input.endw(); ++iinput, ++iSIT_chans)
01181     {
01182       *iSIT_chans = iinput->p[i];
01183     }
01184   }
01185 
01186   if(SIT_useSmoothing)
01187     SITsmoothImage(&SIT_chans);
01188 
01189   SITrunTrack(SIT_imageHold,&SIT_chans);
01190 }
01191 
01192 /*********************************************************************/
01193 
01194 template SIT_TEMPLATE_CLASS
01195 void segmentImageTrackMC<SIT_TEMPLATE>::SITsmoothImage(typename
01196                                              std::vector<Image<FLOAT> > *input)
01197 {
01198   if(SIT_didSmoothing == false)
01199   {
01200     Image<FLOAT> timage;
01201     timage.resize(input->at(0).getWidth(),input->at(0).getHeight(),true);
01202     SIT_fimaLast.resize(input->size(),timage);
01203   }
01204 
01205   typename std::vector<Image<FLOAT> >::iterator iinput = input->begin();
01206   typename std::vector<Image<FLOAT> >::iterator ifima  = SIT_fimaLast.begin();
01207   while(iinput != input->end())
01208   {
01209     if(SIT_didSmoothing)
01210     {
01211       *ifima = (*iinput + ((*ifima) * SIT_smoothingAlpha))/
01212         (1+SIT_smoothingAlpha);
01213     }
01214     else
01215     {
01216       *ifima = *iinput;
01217       SIT_didSmoothing = true;
01218     }
01219     ++iinput; ++ifima;
01220   }
01221   input = &SIT_fimaLast;
01222 }
01223 
01224 /*********************************************************************/
01225 
01226 template SIT_TEMPLATE_CLASS
01227 void segmentImageTrackMC<SIT_TEMPLATE>::SITuseLog(bool useLog)
01228 {
01229   SIT_useLog = useLog;
01230 }
01231 
01232 /*********************************************************************/
01233 
01234 template SIT_TEMPLATE_CLASS
01235 void segmentImageTrackMC<SIT_TEMPLATE>::SITtoggleDrawing(bool targetImage,
01236                                                          bool colorAdaptImage)
01237 {
01238   SIT_drawTargetImage     = targetImage;
01239   SIT_drawColorAdaptImage = colorAdaptImage;
01240 }
01241 
01242 /*********************************************************************/
01243 
01244 template SIT_TEMPLATE_CLASS
01245 void segmentImageTrackMC<SIT_TEMPLATE>::SITrunTrack(
01246                                         Image<PixRGB<byte> > *image,
01247                                         typename
01248                                         std::vector<Image<FLOAT> > *input)
01249 {
01250   SIT_LOTandRESET  = false;
01251   SIT_didColorBars = false;
01252   // (1) segment the decimated image
01253   SIT_segment.SIsegment(image,input);
01254   LDEBUG("SEGMENTED");
01255   // (2) get center of mass for blobs
01256   SIT_segment.SIcalcMassCenter();
01257   LDEBUG("CALCULATED MASS CENTER");
01258   // (3) edit blobs, weed out all the non-hackers who are not
01259   // fit to carry a rifle
01260   if(SIT_editBlobs)
01261     SITanalyzeBlobs();
01262   LDEBUG("BLOBS ANALYZED");
01263   // (4) merge all remaining blobs
01264   SITmergeBlobs();
01265   LDEBUG("BLOBS MERGED");
01266   // (5) apply adaptive color thesholding
01267   SITcolorAdaptation();
01268   LDEBUG("COLORS ADAPTED");
01269 }
01270 
01271 /*********************************************************************/
01272 // DATA RETURN METHODS
01273 /*********************************************************************/
01274 
01275 template SIT_TEMPLATE_CLASS
01276 bool segmentImageTrackMC<SIT_TEMPLATE>::SITreturnLOT()
01277 {
01278   return SIT_LOT;
01279 }
01280 
01281 /*********************************************************************/
01282 
01283 template SIT_TEMPLATE_CLASS
01284 unsigned int segmentImageTrackMC<SIT_TEMPLATE>::SITreturnLOTtype()
01285 {
01286   return SIT_LOTtype;
01287 }
01288 
01289 /*********************************************************************/
01290 
01291 template SIT_TEMPLATE_CLASS
01292 std::string segmentImageTrackMC<SIT_TEMPLATE>::SITreturnLOTtypeName()
01293 {
01294   return SIT_LOTtypeName;
01295 }
01296 
01297 /*********************************************************************/
01298 
01299 template SIT_TEMPLATE_CLASS
01300 Image<long> segmentImageTrackMC<SIT_TEMPLATE>::SITreturnBlobMap()
01301 {
01302   return SIT_segment.SIreturnBlobs();
01303 }
01304 
01305 /*********************************************************************/
01306 
01307 template SIT_TEMPLATE_CLASS
01308 Image<byte> segmentImageTrackMC<SIT_TEMPLATE>::SITreturnCandidateImage()
01309 {
01310   return SIT_segment.SIreturnNormalizedCandidates();
01311 }
01312 
01313 /*********************************************************************/
01314 
01315 template SIT_TEMPLATE_CLASS
01316 void segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobPosition(unsigned short *x,
01317                                                            unsigned short *y)
01318 {
01319        SIT_centerXmod = SIT_centerX*SIT_GLOBAL_DEC;
01320        SIT_centerYmod = SIT_centerY*SIT_GLOBAL_DEC;
01321   *x = SIT_centerXmod;
01322   *y = SIT_centerYmod;
01323 }
01324 /*********************************************************************/
01325 
01326 template SIT_TEMPLATE_CLASS
01327 void segmentImageTrackMC<SIT_TEMPLATE>::SITgetMinMaxBoundry(
01328                                                         unsigned short *minX,
01329                                                         unsigned short *maxX,
01330                                                         unsigned short *minY,
01331                                                         unsigned short *maxY)
01332 {
01333           SIT_minXmod = SIT_minX*SIT_GLOBAL_DEC;
01334           SIT_maxXmod = SIT_maxX*SIT_GLOBAL_DEC;
01335           SIT_minYmod = SIT_minY*SIT_GLOBAL_DEC;
01336           SIT_maxYmod = SIT_maxY*SIT_GLOBAL_DEC;
01337   *minX = SIT_minXmod;
01338   *maxX = SIT_maxXmod;
01339   *minY = SIT_minYmod;
01340   *maxY = SIT_maxYmod;
01341 }
01342 
01343 /*********************************************************************/
01344 
01345 template SIT_TEMPLATE_CLASS
01346 Image<PixRGB<byte> > segmentImageTrackMC<SIT_TEMPLATE>::SITgetColorBars()
01347 {
01348   return SIT_auxHold;
01349 }
01350 
01351 /********************************************************************/
01352 
01353 /* commented this out because SIT_MASS is not defined (or even declared)
01354    anywhere, so we get an error with g++ 3.4.1 */
01355 template SIT_TEMPLATE_CLASS
01356 FLOAT segmentImageTrackMC<SIT_TEMPLATE>::SITgetMass()
01357 {
01358   return SIT_mass;
01359 }
01360 
01361 /********************************************************************/
01362 
01363 template SIT_TEMPLATE_CLASS
01364 void segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobAttrition(
01365                                                     INT *totalBlobs,
01366                                                     INT *killedBlobs)
01367 {
01368   *totalBlobs  = SIT_totalBlobs;
01369   *killedBlobs = SIT_killedBlobs;
01370 }
01371 /********************************************************************/
01372 
01373 template SIT_TEMPLATE_CLASS
01374 void segmentImageTrackMC<SIT_TEMPLATE>::SITgetLifeSpans(
01375                                         unsigned long *totalLifeSpan,
01376                                         unsigned long *lifeSpan)
01377 {
01378   *totalLifeSpan = SIT_totalLifeSpan;
01379   *lifeSpan      = SIT_lifeSpan;
01380 }
01381 
01382 /********************************************************************/
01383 
01384 template SIT_TEMPLATE_CLASS
01385 void segmentImageTrackMC<SIT_TEMPLATE>::SITgetAdaptiveChannelVals(
01386                                         typename std::vector<FLOAT> *mean,
01387                                         typename std::vector<FLOAT> *std)
01388 {
01389   *mean = SIT_chMean1;
01390   *std  = SIT_chStd1;
01391 }
01392 
01393 /********************************************************************/
01394 
01395 template SIT_TEMPLATE_CLASS
01396 unsigned int segmentImageTrackMC<SIT_TEMPLATE>::SITgetLOTcount()
01397 {
01398   return SIT_LOTcount;
01399 }
01400 
01401 /********************************************************************/
01402 
01403 template SIT_TEMPLATE_CLASS
01404 INT segmentImageTrackMC<SIT_TEMPLATE>::SITnumberBlobs()
01405 {
01406   return SIT_segment.SInumberBlobs();
01407 }
01408 
01409 /********************************************************************/
01410 
01411 template SIT_TEMPLATE_CLASS
01412 unsigned short
01413 segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobReasonForKillCode(INT blob)
01414 {
01415   return SIT_reasonForKillCode[blob];
01416 }
01417 
01418 /********************************************************************/
01419 
01420 template SIT_TEMPLATE_CLASS
01421 std::string segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobReasonForKill(INT blob)
01422 {
01423   return SIT_reasonForKill[blob];
01424 }
01425 
01426 /********************************************************************/
01427 
01428 template SIT_TEMPLATE_CLASS
01429 INT segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobMass(INT blob)
01430 {
01431   return SIT_segment.SIgetMass(blob);
01432 }
01433 
01434 /********************************************************************/
01435 
01436 template SIT_TEMPLATE_CLASS
01437 INT segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobPosX(INT blob)
01438 {
01439   return (INT)floor(SIT_segment.SIgetCenterX(blob)) * SIT_GLOBAL_DEC;
01440 }
01441 
01442 /********************************************************************/
01443 
01444 template SIT_TEMPLATE_CLASS
01445 INT segmentImageTrackMC<SIT_TEMPLATE>::SITgetBlobPosY(INT blob)
01446 {
01447   return (INT)floor(SIT_segment.SIgetCenterY(blob)) * SIT_GLOBAL_DEC;
01448 }
01449 
01450 
01451 /*********************************************************************/
01452 // DRAWING METHODS
01453 /*********************************************************************/
01454 
01455 template SIT_TEMPLATE_CLASS
01456 void segmentImageTrackMC<SIT_TEMPLATE>::SITdrawBlobTrack(INT i)
01457 {
01458   // find boundaries of this blob
01459   unsigned int tt = SIT_segment.SIgetYmin(i);
01460   unsigned int bb = SIT_segment.SIgetYmax(i);
01461   unsigned int ll = SIT_segment.SIgetXmin(i);
01462   unsigned int rr = SIT_segment.SIgetXmax(i);
01463 
01464   // draw bounding box for this blob
01465   // Note: box must be of height > 1 and width > 1
01466   if((bb != tt) && (ll != rr))
01467     drawRectEZ(*SIT_imageHold, Rectangle::tlbrI(tt*SIT_GLOBAL_DEC,
01468                                          ll*SIT_GLOBAL_DEC,
01469                                          bb*SIT_GLOBAL_DEC,
01470                                          rr*SIT_GLOBAL_DEC),
01471                PixRGB<byte>(SIT_boxRed,
01472                             SIT_boxGreen,
01473                             SIT_boxBlue),1);
01474 
01475   // draw target circle for this blob
01476   drawCircle(*SIT_imageHold, Point2D<int>((int)SIT_segment.SIgetCenterX(i)
01477                                      *SIT_GLOBAL_DEC
01478                                      ,(int)SIT_segment.SIgetCenterY(i)
01479                                      *SIT_GLOBAL_DEC)
01480              ,(int)sqrt((float)SIT_segment.SIgetMass(i)),
01481              PixRGB<byte>(SIT_boxRed,
01482                           SIT_boxGreen,
01483                           SIT_boxBlue),2);
01484 
01485   drawCircle(*SIT_imageHold, Point2D<int>((int)SIT_segment.SIgetCenterX(i)
01486                                      *SIT_GLOBAL_DEC
01487                                      ,(int)SIT_segment.SIgetCenterY(i)
01488                                      *SIT_GLOBAL_DEC)
01489              ,2,PixRGB<byte>(255,0,0),2);
01490 }
01491 
01492 /*********************************************************************/
01493 
01494 template SIT_TEMPLATE_CLASS
01495 void segmentImageTrackMC<SIT_TEMPLATE>::SITdrawBlobTrackMerged()
01496 {
01497 
01498   if((SIT_minY != SIT_maxY) && (SIT_minX != SIT_maxX))
01499     drawRectEZ(*SIT_imageHold, Rectangle::tlbrI(SIT_minY*SIT_GLOBAL_DEC,
01500                                          SIT_minX*SIT_GLOBAL_DEC,
01501                                          SIT_maxY*SIT_GLOBAL_DEC,
01502                                          SIT_maxX*SIT_GLOBAL_DEC),
01503                PixRGB<byte>(SIT_bigBoxRed,
01504                             SIT_bigBoxGreen,
01505                             SIT_bigBoxBlue),2);
01506 
01507   // draw target circle for this blob
01508   drawCircle(*SIT_imageHold, Point2D<int>((int)SIT_centerX*SIT_GLOBAL_DEC,
01509                                      (int)SIT_centerY*SIT_GLOBAL_DEC),
01510              (int)sqrt(SIT_mass),
01511              PixRGB<byte>(SIT_bigBoxRed,
01512                           SIT_bigBoxGreen,
01513                           SIT_bigBoxBlue),2);
01514 
01515   drawCircle(*SIT_imageHold, Point2D<int>((int)SIT_centerX*SIT_GLOBAL_DEC,(int)SIT_centerY*SIT_GLOBAL_DEC)
01516              ,2,PixRGB<byte>(255,0,0),2);
01517 }
01518 
01519 
01520 
01521 /*********************************************************************/
01522 template SIT_TEMPLATE_CLASS
01523 void segmentImageTrackMC<SIT_TEMPLATE>::SITdrawBlobBox(INT i)
01524 {
01525               // find boundaries of this blob
01526   unsigned int tt = SIT_segment.SIgetYmin(i);
01527   unsigned int bb = SIT_segment.SIgetYmax(i);
01528   unsigned int ll = SIT_segment.SIgetXmin(i);
01529   unsigned int rr = SIT_segment.SIgetXmax(i);
01530 
01531 
01532   // draw bounding box for this blob
01533   // Note: box must be of height > 1 and width > 1
01534   if((bb != tt) && (ll != rr))
01535     drawRectEZ(*SIT_imageHold, Rectangle::tlbrI(tt*SIT_GLOBAL_DEC,
01536                                          ll*SIT_GLOBAL_DEC,
01537                                          bb*SIT_GLOBAL_DEC,
01538                                          rr*SIT_GLOBAL_DEC),
01539                PixRGB<byte>(SIT_circleRed,
01540                             SIT_circleGreen,
01541                             SIT_circleBlue),1);
01542 }
01543 
01544 /*********************************************************************/
01545 template SIT_TEMPLATE_CLASS
01546 void segmentImageTrackMC<SIT_TEMPLATE>::SITdrawHistoValues(
01547                                            typename std::vector<FLOAT> *mean,
01548                                            typename std::vector<FLOAT> *std,
01549                                            typename std::vector<FLOAT> *lb,
01550                                            typename std::vector<FLOAT> *ub,
01551                                            typename std::vector<FLOAT> *norm,
01552                                            bool LOT)
01553 {
01554   SIT_didColorBars = true;
01555 
01556   unsigned int minWidth = SIT_barWidth+SIT_barSpace*mean->size();
01557   if((unsigned)SIT_auxHold.getWidth() < minWidth)
01558     SIT_auxHold.resize(minWidth,(int)SIT_histoHeight,true);
01559   // draw background grid in HSV bar graph
01560   if(LOT == false)
01561     drawGrid(SIT_auxHold, 25,25,1,1,PixRGB<byte>(100,100,100));
01562   else
01563     drawGrid(SIT_auxHold, 25,25,1,1,PixRGB<byte>(200,100,100));
01564 
01565 /*  typename std::vector<FLOAT>::iterator imean = mean->begin();
01566   typename std::vector<FLOAT>::iterator istd  = std->begin();
01567   typename std::vector<FLOAT>::iterator ilb   = lb->begin();
01568   typename std::vector<FLOAT>::iterator iub   = ub->begin();
01569   typename std::vector<FLOAT>::iterator inorm = norm->begin();
01570 */
01571   //unsigned int start = SIT_barSpace;
01572   //unsigned int end   = SIT_barWidth + start;
01573 
01574   /*
01575   while(imean != mean->end())
01576   {
01577     if(*inorm != 0)
01578     {
01579       FLOAT mean = (*imean/(*inorm));
01580       FLOAT std  = (*istd/(*inorm));
01581       FLOAT ub   = (*iub/(*inorm));
01582       FLOAT lb   = (*ilb/(*inorm));
01583 
01584       // draw HSV mean value bars as a bunch of rectangles
01585       drawRectEZ(SIT_auxHold, Rectangle::tlbrI(0,start,(int)(mean*
01586                                                       SIT_histoHeight),end),
01587                  PixRGB<byte>(0,0,255),1);
01588 
01589       // draw standard deviation bars
01590 
01591       if((((mean-std)*SIT_histoHeight) > 0)
01592          && (((mean+std)*SIT_histoHeight) < SIT_auxHold.getHeight()))
01593         drawRectEZ(SIT_auxHold, Rectangle::tlbrI((int)((mean-std)*SIT_histoHeight)
01594                                         ,start+2,
01595                                           (int)((mean+std)*SIT_histoHeight)
01596                                           ,end-2),
01597                    PixRGB<byte>(255,255,0),1);
01598 
01599 
01600       drawRectEZ(SIT_auxHold, Rectangle::tlbrI((int)(lb*(SIT_histoHeight-1))
01601                                         ,(signed)start-3,
01602                                         (int)(ub*(SIT_histoHeight-1))
01603                                         ,(signed)start-1),
01604                  PixRGB<byte>(255,0,0),1);
01605 
01606 
01607       ++imean, ++istd, ++ilb, ++iub, ++inorm;
01608       start = end   + SIT_barSpace;
01609       end   = start + SIT_barWidth;
01610     }
01611   }
01612   */
01613 }
01614 
01615 #undef SIT_TEMPLATE_CLASS
01616 #undef SIT_TEMPLATE
01617 
01618 template class segmentImageTrackMC<float, unsigned int, 3>;
01619 template class segmentImageTrackMC<float, unsigned int, 4>;
01620 
01621 #endif
Generated on Sun May 8 08:07:04 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3