IT.C

Go to the documentation of this file.
00001 /*!@file SceneUnderstanding/IT.C  */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the 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: Lior Elazary <elazary@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/plugins/SceneUnderstanding/IT.C $
00035 // $Id: IT.C 13765 2010-08-06 18:56:17Z lior $
00036 //
00037 
00038 #ifndef IT_C_DEFINED
00039 #define IT_C_DEFINED
00040 
00041 #include "Image/DrawOps.H"
00042 #include "Image/MathOps.H"
00043 //#include "Image/OpenCVUtil.H"
00044 #include "Image/Kernels.H"
00045 #include "Image/FilterOps.H"
00046 #include "Image/Convolutions.H"
00047 #include "Image/fancynorm.H"
00048 #include "Image/Point3D.H"
00049 #include "plugins/SceneUnderstanding/IT.H"
00050 #include "Neuro/EnvVisualCortex.H"
00051 #include "GUI/DebugWin.H"
00052 #include "Util/CpuTimer.H"
00053 #include <math.h>
00054 #include <fcntl.h>
00055 #include <limits>
00056 #include <string>
00057 #include <queue>
00058 
00059 const ModelOptionCateg MOC_IT = {
00060   MOC_SORTPRI_3,   "IT-Related Options" };
00061 
00062 const ModelOptionDef OPT_ITShowDebug =
00063   { MODOPT_ARG(bool), "ITShowDebug", &MOC_IT, OPTEXP_CORE,
00064     "Show debug img",
00065     "it-debug", '\0', "<true|false>", "false" };
00066 
00067 // ######################################################################
00068 IT::IT(OptionManager& mgr, const std::string& descrName,
00069     const std::string& tagName) :
00070   SimModule(mgr, descrName, tagName),
00071   SIMCALLBACK_INIT(SimEventV4Output),
00072   SIMCALLBACK_INIT(SimEventSaveOutput),
00073   itsShowDebug(&OPT_ITShowDebug, this),
00074   itsObjectsDist(370.00)
00075 {
00076 
00077   //Camera parameters
00078   itsCamera = Camera(Point3D<float>(0,0,0.0),
00079                      Point3D<float>(0, 0,0),
00080                      450, //Focal length
00081                      320, //width
00082                      240); //height
00083 
00084   itsHashedGeonsState.set_empty_key(-1);
00085 
00086   itsObjects.resize(4);
00087 
00088 
00089   //Add objects
00090   //House object
00091   Object houseObject;
00092   V4::GeonState geon;
00093   geon.pos = Point3D<float>(0, -15, 0);
00094   geon.rot = 0.75*M_PI;
00095   geon.geonType = V4::TRIANGLE;
00096   geon.posSigma = Point3D<float>(2, 2, 2);
00097   geon.rotSigma = 10*M_PI/180;
00098   houseObject.geons.push_back(geon);
00099 
00100   geon.pos = Point3D<float>(0, 15, 0);
00101   geon.rot = 0;
00102   geon.geonType = V4::SQUARE;
00103   geon.posSigma = Point3D<float>(2, 2, 2);
00104   geon.rotSigma = 10*M_PI/180;
00105   houseObject.geons.push_back(geon);
00106   houseObject.objectType = HOUSE;
00107   itsObjects[HOUSE] = houseObject;
00108 
00109   //Woman object
00110   Object womanObject;
00111 
00112   geon.pos = Point3D<float>(0, -15, 0);
00113   geon.rot = 0;
00114   geon.geonType = V4::CIRCLE;
00115   geon.posSigma = Point3D<float>(2, 2, 2);
00116   geon.rotSigma = 10*M_PI/180;
00117   womanObject.geons.push_back(geon);
00118 
00119   geon.pos = Point3D<float>(0, 15, 0);
00120   geon.rot = 0.75*M_PI;
00121   geon.geonType = V4::TRIANGLE;
00122   geon.posSigma = Point3D<float>(2, 2, 2);
00123   geon.rotSigma = 10*M_PI/180;
00124   womanObject.geons.push_back(geon);
00125   womanObject.objectType = WOMAN;
00126   itsObjects[WOMAN] = womanObject;
00127 
00128 
00129   //Hat object
00130   Object hatObject;
00131   geon.pos = Point3D<float>(0, -15, 0);
00132   geon.rot = 0.75*M_PI;
00133   geon.geonType = V4::TRIANGLE;
00134   geon.posSigma = Point3D<float>(2, 2, 2);
00135   geon.rotSigma = 10*M_PI/180;
00136   hatObject.geons.push_back(geon);
00137 
00138   geon.pos = Point3D<float>(0, 15, 0);
00139   geon.rot = 0;
00140   geon.geonType = V4::CIRCLE;
00141   geon.posSigma = Point3D<float>(2, 2, 2);
00142   geon.rotSigma = 10*M_PI/180;
00143   hatObject.geons.push_back(geon);
00144   hatObject.objectType = HAT;
00145   itsObjects[HAT] = hatObject;
00146 
00147   //Man object
00148   Object manObject;
00149 
00150   geon.pos = Point3D<float>(0, -15, 0);
00151   geon.rot = 0;
00152   geon.geonType = V4::CIRCLE;
00153   geon.posSigma = Point3D<float>(2, 2, 2);
00154   geon.rotSigma = 10*M_PI/180;
00155   manObject.geons.push_back(geon);
00156 
00157   geon.pos = Point3D<float>(0, 15, 0);
00158   geon.rot = 0;
00159   geon.geonType = V4::SQUARE;
00160   geon.posSigma = Point3D<float>(2, 2, 2);
00161   geon.rotSigma = 10*M_PI/180;
00162   manObject.geons.push_back(geon);
00163   manObject.objectType = MAN;
00164   itsObjects[MAN] = manObject;
00165 
00166   buildRTables();
00167 
00168   itsObjectsParticles.resize(1000);
00169   for(uint i=0; i<itsObjectsParticles.size(); i++)
00170   {
00171     itsObjectsParticles[i].objectType = HOUSE;
00172     itsObjectsParticles[i].weight = 1.0/100.0;
00173   }
00174 
00175 
00176 
00177 }
00178 
00179 // ######################################################################
00180 IT::~IT()
00181 {
00182 
00183 }
00184 
00185 // ######################################################################
00186 void IT::buildRTables()
00187 {
00188   //Position relative to the camera
00189   for(uint objId=0; objId<itsObjects.size(); objId++)
00190   {
00191                 Point3D<float> pos(0,0,itsObjectsDist);
00192                 float rot = 0;
00193 
00194                 for(uint gid = 0; gid < itsObjects[objId].geons.size(); gid++)
00195                 {
00196                         V4::GeonState geonState = itsObjects[objId].geons[gid];
00197 
00198                         geonState.rot += rot;
00199                         float x = geonState.pos.x;
00200                         float y = geonState.pos.y;
00201                         float z = geonState.pos.z;
00202                         geonState.pos.x = (cos(rot)*x - sin(rot)*y) + pos.x;
00203                         geonState.pos.y = (sin(rot)*x + cos(rot)*y) + pos.y;
00204                         geonState.pos.z = z + pos.z;
00205 
00206                         Point2D<int> loc = (Point2D<int>)itsCamera.project(geonState.pos);
00207 
00208                         RTableEntry rTableEntry;
00209                         rTableEntry.geonType = geonState.geonType;
00210                         rTableEntry.loc.i = loc.i - 320/2;
00211                         rTableEntry.loc.j = loc.j - 240/2;
00212                         rTableEntry.rot = geonState.rot;
00213 
00214                         itsObjects[objId].rTable.push_back(rTableEntry);
00215                 }
00216                 //Image<PixRGB<byte> > img(320,240,ZEROS);
00217                 //showObject(img, itsObjects[objId], pos, rot);
00218                 //SHOWIMG(img);
00219         }
00220 }
00221 
00222 // ######################################################################
00223 void IT::init(Dims numCells)
00224 {
00225 
00226 }
00227 
00228 // ######################################################################
00229 void IT::onSimEventV4Output(SimEventQueue& q,
00230                                   rutz::shared_ptr<SimEventV4Output>& e)
00231 {
00232   std::vector<V4::GeonState> geonsState = e->getCells();
00233 
00234 
00235   itsHashedGeonsState.clear();
00236 
00237         itsGeonsState.clear();
00238   for(uint i=0; i<geonsState.size(); i++)
00239   {
00240                 if (geonsState[i].prob > 0)
00241                 {
00242                         itsGeonsState.push_back(geonsState[i]);
00243                         //TODO use a 3D hash key
00244                         int key = i; //(int)(geonsState[i].pos.x + 1000.0*geonsState[i].pos.y);
00245                         itsHashedGeonsState[key] = geonsState[i];
00246                 }
00247   }
00248 
00249   evolve();
00250 
00251   //q.post(rutz::make_shared(new SimEventITOutput(this, itsFeaturesParticles)));
00252 
00253 
00254 }
00255 
00256 // ######################################################################
00257 void IT::onSimEventSaveOutput(SimEventQueue& q, rutz::shared_ptr<SimEventSaveOutput>& e)
00258 {
00259   if (itsShowDebug.getVal())
00260     {
00261       // get the OFS to save to, assuming sinfo is of type
00262       // SimModuleSaveInfo (will throw a fatal exception otherwise):
00263       nub::ref<FrameOstream> ofs =
00264         dynamic_cast<const SimModuleSaveInfo&>(e->sinfo()).ofs;
00265       Layout<PixRGB<byte> > disp = getDebugImage();
00266       ofs->writeRgbLayout(disp, "IT", FrameInfo("IT", SRC_POS));
00267     }
00268 }
00269 
00270 // ######################################################################
00271 void IT::setInput(const std::vector<V4::GeonState> &geonsState)
00272 {
00273   itsHashedGeonsState.clear();
00274   for(uint i=0; i<geonsState.size(); i++)
00275   {
00276     //TODO use a 3D hash key
00277     int key = i; //(int)(geonsState[i].pos.x + 1000.0*geonsState[i].pos.y);
00278     itsHashedGeonsState[key] = geonsState[i];
00279   }
00280 
00281   evolve();
00282 }
00283 
00284 // ######################################################################
00285 void IT::showObject(Image<PixRGB<byte> > &img, Object& object, Point3D<float>& pos, float rot)
00286 {
00287 
00288         PixRGB<byte> col;
00289         switch (object.objectType)
00290         {
00291                 case HOUSE: col = PixRGB<byte>(255,0,0); break;
00292                 case WOMAN: col = PixRGB<byte>(0,255,0); break;
00293                 case HAT: col = PixRGB<byte>(0,255,255); break;
00294                 case MAN: col = PixRGB<byte>(0,0,255);  break;
00295                 default: break;
00296         }
00297   //Position relative to the camera
00298   for(uint geonId=0; geonId<object.geons.size(); geonId++)
00299   {
00300     //Transform the object relative to the camera;
00301     V4::GeonState geonState = object.geons[geonId];
00302 
00303     geonState.rot += rot;
00304     float x = geonState.pos.x;
00305     float y = geonState.pos.y;
00306     float z = geonState.pos.z;
00307     geonState.pos.x = (cos(rot)*x - sin(rot)*y) + pos.x;
00308     geonState.pos.y = (sin(rot)*x + cos(rot)*y) + pos.y;
00309     geonState.pos.z = z + pos.z;
00310 
00311     Point2D<int> loc = (Point2D<int>)itsCamera.project(geonState.pos);
00312 
00313                         switch(geonState.geonType)
00314                         {
00315                                 case V4::SQUARE:
00316                                         drawRectOR(img, Rectangle(loc - Point2D<int>(20,20), Dims((int)40,(int)40)),
00317                                                         col, 1, geonState.rot);
00318                                         break;
00319                                 case V4::CIRCLE:
00320                                         if (object.objectType != HAT)
00321                                                 drawCircle(img, loc, 20, col);
00322                                         break;
00323                                 case V4::TRIANGLE:
00324                                         {
00325                                                 std::vector<Point3D<float> > outline;
00326                                                 outline.push_back(Point3D<float>(0.0,0, 0.0));
00327                                                 outline.push_back(Point3D<float>(0.0,-40.0, 0.0));
00328                                                 outline.push_back(Point3D<float>(40.0, 0.0, 0.0));
00329 
00330                                                 //get the center of the object;
00331                                                 float centerX = 0, centerY = 0, centerZ = 0;
00332                                                 for(uint i=0; i<outline.size(); i++)
00333                                                 {
00334                                                         centerX += outline[i].x;
00335                                                         centerY += outline[i].y;
00336                                                         centerZ += outline[i].z;
00337                                                 }
00338                                                 centerX /= outline.size();
00339                                                 centerY /= outline.size();
00340                                                 centerZ /= outline.size();
00341 
00342                                                 for(uint i=0; i<outline.size(); i++)
00343                                                         outline[i] -= Point3D<float>(centerX, centerY, centerZ);
00344 
00345                                                 for(uint i=0; i<outline.size(); i++)
00346                                                 {
00347                                                         float x = outline[i].x;
00348                                                         float y = outline[i].y;
00349                                                         float z = outline[i].z;
00350                                                         outline[i].x = (cos(geonState.rot)*x - sin(geonState.rot)*y) + geonState.pos.x;
00351                                                         outline[i].y = (sin(geonState.rot)*x + cos(geonState.rot)*y) + geonState.pos.y;
00352                                                         outline[i].z = z + geonState.pos.z;
00353                                                 }
00354 
00355                                                 //Project the object to camera cordinats
00356                                                 std::vector<Point2D<int> > points;
00357 
00358                                                 for(uint i=0; i<outline.size(); i++)
00359                                                 {
00360                                                         Point2D<float> loc = itsCamera.project(outline[i]);
00361                                                         points.push_back(Point2D<int>(loc));
00362                                                 }
00363 
00364                                                 for(uint i=0; i<points.size(); i++)
00365                                                         drawLine(img, points[i], points[(i+1)%points.size()], col, 1);
00366 
00367                                         }
00368                                         break;
00369                         }
00370   }
00371 
00372 }
00373 
00374 // ######################################################################
00375 void IT::evolve()
00376 {
00377 
00378   ////Resample
00379   //resampleParticles(itsObjectsParticles);
00380   proposeParticles(itsObjectsParticles, 0.0F);
00381 
00382   ////Evaluate the particles;
00383   evaluateObjectParticles(itsObjectsParticles);
00384 
00385 }
00386 
00387 // ######################################################################
00388 float IT::evaluateObjectParticles(std::vector<ObjectState>& objectParticles)
00389 {
00390 
00391   for(uint p=0; p<objectParticles.size(); p++)
00392     getObjectLikelihood(objectParticles[p]);
00393 
00394   //Normalize the particles;
00395   double sum = 0;
00396   double Neff = 0; //Number of efictive particles
00397   for(uint i=0; i<objectParticles.size(); i++)
00398     sum += objectParticles[i].prob;
00399 
00400   for(uint i=0; i<objectParticles.size(); i++)
00401   {
00402     objectParticles[i].weight = objectParticles[i].prob/sum;
00403     Neff += squareOf(objectParticles[i].weight);
00404   }
00405 
00406   Neff = 1/Neff;
00407 
00408 
00409   return Neff;
00410 
00411 }
00412 
00413 void IT::GHT(std::vector<GHTAcc>& accRet, OBJECT_TYPE objectType)
00414 {
00415   ImageSet<float> acc(360, Dims(320,240), ZEROS);
00416 
00417   CpuTimer timer;
00418   timer.reset();
00419         //for(int angIdx = 0; angIdx < 360; angIdx++)
00420         //{
00421   ////  jobs.push_back(rutz::make_shared(new GHTJob(this, acc[angIdx], angIdx, geonOutline.rTable)));
00422   ////  itsThreadServer->enqueueJob(jobs.back());
00423         //        //voteForFeature(acc[angIdx], angIdx, geonOutline.rTable);
00424         //}
00425 
00426         int angIdx = 0;
00427         voteForFeature(acc[angIdx], angIdx, itsObjects[objectType].rTable);
00428 
00429   timer.mark();
00430   LINFO("Total time %0.2f sec", timer.real_secs());
00431 
00432 
00433 //  Image<float> tmp(320, 240, ZEROS);
00434 //  for(uint angIdx=0; angIdx<acc.size(); angIdx++)
00435 //  {
00436 //    for(uint i=0; i<acc[angIdx].size(); i++)
00437 //    {
00438 //      if (acc[angIdx].getVal(i) > tmp.getVal(i))
00439 //        tmp.setVal(i, acc[angIdx].getVal(i));
00440 //    }
00441 //  }
00442 //  SHOWIMG(tmp);
00443 
00444 
00445         for(uint rot=0; rot<acc.size(); rot++)
00446                 for(int y=0; y<acc[rot].getHeight(); y++)
00447                         for(int x=0; x<acc[rot].getWidth(); x++)
00448                                 if (acc[rot].getVal(x,y) > 0)
00449                                 {
00450                                         GHTAcc ghtAcc;
00451                                         ghtAcc.objectType = objectType;
00452                                         ghtAcc.pos = Point2D<int>(x,y);
00453                                         ghtAcc.ang = rot;
00454                                         ghtAcc.scale = -1;
00455                                         ghtAcc.sum = acc[rot].getVal(x,y);
00456                                         accRet.push_back(ghtAcc);
00457                                 }
00458 
00459 }
00460 
00461 void IT::voteForFeature(Image<float>& acc, int angIdx, std::vector<RTableEntry>& rTable)
00462 {
00463 
00464         for(uint g=0; g < itsGeonsState.size(); g++)
00465         {
00466                 V4::GeonState geonState = itsGeonsState[g];
00467                 if (geonState.prob > 0)
00468                 {
00469                         Point2D<int> loc = (Point2D<int>)itsCamera.project(geonState.pos);
00470 
00471 
00472                         for(uint rIdx = 0; rIdx < rTable.size(); rIdx++)
00473                         {
00474                                 if (rTable[rIdx].geonType == geonState.geonType)
00475                                 {
00476                                         float ang = angIdx * M_PI/180;
00477 
00478                                         float featureAng = rTable[rIdx].rot + ang;
00479                                         if (featureAng < 0)
00480                                                 featureAng += M_PI*2;
00481                                         if (featureAng > M_PI*2)
00482                                                 featureAng -= M_PI*2;
00483 
00484                                         float diffRot = acos(cos(geonState.rot - featureAng));
00485 
00486                                         float stddevRot = 1.5;
00487                                         int sizeRot = int(ceil(stddevRot * sqrt(-2.0F * log(exp(-5.0F)))));
00488 
00489                                         if (fabs(diffRot) < sizeRot*M_PI/180) //TODO change to a for loop with hash
00490                                         {
00491                                                 float rRot = exp(-((diffRot*diffRot)/(stddevRot*stddevRot)));
00492 
00493                                                 //Apply a variance over position and angle
00494                                                 //TODO change to a veriance in feature position, not its endpoint
00495                                                 float stddevX = 1.5;
00496                                                 float stddevY = 1.5;
00497                                                 int sizeX = int(ceil(stddevX * sqrt(-2.0F * log(exp(-5.0F)))));
00498                                                 int sizeY = int(ceil(stddevY * sqrt(-2.0F * log(exp(-5.0F)))));
00499 
00500                                                 for(int y=loc.j-sizeY; y<loc.j+sizeY; y++)
00501                                                 {
00502                                                         float diffY = y-loc.j;
00503                                                         float ry = exp(-((diffY*diffY)/(stddevY*stddevY)));
00504                                                         for(int x=loc.i-sizeX; x<loc.i+sizeX; x++)
00505                                                         {
00506                                                                 float diffX = x-loc.i;
00507                                                                 float rx = exp(-((diffX*diffX)/(stddevX*stddevX)));
00508                                                                 //float weight = nafState.prob + rRot*rx*ry;
00509                                                                 float weight = rRot*rx*ry;
00510 
00511                                                                 int a0 = x - int(rTable[rIdx].loc.i*cos(ang) - rTable[rIdx].loc.j*sin(ang));
00512                                                                 int b0 = y - int(rTable[rIdx].loc.i*sin(ang) + rTable[rIdx].loc.j*cos(ang));
00513                                                                 if (acc.coordsOk(a0, b0))
00514                                                                 {
00515                                                                         float val = acc.getVal(a0, b0);
00516                                                                         val += weight;
00517                                                                         acc.setVal(a0, b0, val);
00518                                                                 }
00519                                                         }
00520                                                 }
00521                                         }
00522                                 }
00523                         }
00524                 }
00525         }
00526 }
00527 
00528 void IT::normalizeAcc(std::vector<GHTAcc>& acc)
00529 {
00530 
00531   double sum = 0;
00532   for(uint i=0; i<acc.size(); i++)
00533     sum += acc[i].sum;
00534 
00535   for(uint i=0; i<acc.size(); i++)
00536     acc[i].sum /= sum;
00537 }
00538 
00539 // ######################################################################
00540 Image<float> IT::showParticles(const std::vector<ObjectState>& objectParticles)
00541 {
00542   Image<float> probImg(320,240, ZEROS);
00543 
00544   for(uint i=0; i<objectParticles.size(); i++)
00545   {
00546     Point2D<int> loc = (Point2D<int>)itsCamera.project(objectParticles[i].pos);
00547     if (probImg.coordsOk(loc))
00548       probImg.setVal(loc, probImg.getVal(loc) + objectParticles[i].weight);
00549   }
00550   inplaceNormalize(probImg, 0.0F, 255.0F);
00551 
00552   return probImg;
00553 
00554 }
00555 
00556 // ######################################################################
00557 void IT::proposeParticles(std::vector<ObjectState>& objectParticles, const double Neff)
00558 {
00559   LINFO("Propose Particles");
00560 
00561   float probThresh = 1.0e-2;
00562 
00563   //If we have good hypothisis then just adjest them
00564   uint objectsAboveProb = 0;
00565 
00566   for(uint i=0; i<objectParticles.size(); i++)
00567   {
00568     if (objectParticles[i].prob > probThresh)
00569     {
00570       objectParticles[i].pos.x +=  randomDoubleFromNormal(1.0);
00571       objectParticles[i].pos.y +=  randomDoubleFromNormal(1.0);
00572       objectParticles[i].pos.z =  itsObjectsDist + randomDoubleFromNormal(0.05);
00573       objectParticles[i].rot   +=  randomDoubleFromNormal(1.0)*M_PI/180;
00574       objectParticles[i].weight = 1.0/(float)objectParticles.size();
00575       objectsAboveProb++;
00576     }
00577   }
00578 
00579   //LINFO("Objects Above prob %i/%lu",
00580   //    objectsAboveProb, objectParticles.size());
00581 
00582   if (objectsAboveProb < objectParticles.size())
00583   {
00584 
00585     LINFO("GHT sampleing");
00586     std::vector<GHTAcc> acc;
00587     GHT(acc, HOUSE);
00588     GHT(acc, WOMAN);
00589     GHT(acc, HAT);
00590     GHT(acc, MAN);
00591                 //LINFO("Acc size %lu", acc.size());
00592     LINFO("GHT Done ");
00593 
00594     if (acc.size() == 0)
00595             return;
00596                 normalizeAcc(acc);
00597 
00598     std::priority_queue <GHTAcc> pAcc;
00599     for(uint i=0; i<acc.size(); i++)
00600        pAcc.push(acc[i]);
00601 
00602     ////Sample from acc
00603     for(uint i=0; i<objectParticles.size(); i++)
00604     {
00605       if (objectParticles[i].prob <= probThresh)
00606       {
00607         //add this point to the list
00608         if (pAcc.empty())
00609           break;
00610         GHTAcc p = pAcc.top(); pAcc.pop();
00611 
00612         Point3D<float>  iPoint = itsCamera.inverseProjection(Point2D<float>(p.pos), itsObjectsDist);
00613         objectParticles[i].pos.x = iPoint.x + randomDoubleFromNormal(1);
00614         objectParticles[i].pos.y = iPoint.y + randomDoubleFromNormal(1);
00615         objectParticles[i].pos.z =  itsObjectsDist + randomDoubleFromNormal(0.05);
00616         objectParticles[i].rot =  (p.ang + randomDoubleFromNormal(1))*M_PI/180;
00617         objectParticles[i].objectType = p.objectType;
00618         objectParticles[i].weight = 1.0/(float)objectParticles.size();
00619         objectParticles[i].prob = 1.0e-50;
00620       }
00621     }
00622   }
00623 }
00624 
00625 // ######################################################################
00626 void IT::resampleParticles(std::vector<ObjectState>& objectParticles)
00627 {
00628   LINFO("Resample");
00629 
00630   std::vector<ObjectState> newParticles;
00631 
00632   //Calculate a Cumulative Distribution Function for our particle weights
00633   std::vector<double> CDF;
00634   CDF.resize(objectParticles.size());
00635 
00636   CDF.at(0) = objectParticles.at(0).weight;
00637   for(uint i=1; i<CDF.size(); i++)
00638     CDF.at(i) = CDF.at(i-1) + objectParticles.at(i).weight;
00639 
00640   uint i = 0;
00641   double u = randomDouble()* 1.0/double(objectParticles.size());
00642 
00643   for(uint j=0; j < objectParticles.size(); j++)
00644   {
00645     while(u > CDF.at(i))
00646       i++;
00647 
00648     ObjectState p = objectParticles.at(i);
00649     p.weight     = 1.0/double(objectParticles.size());
00650     newParticles.push_back(p);
00651 
00652     u += 1.0/double(objectParticles.size());
00653   }
00654 
00655   objectParticles = newParticles;
00656 
00657 }
00658 
00659 // ######################################################################
00660 void IT::getObjectLikelihood(ObjectState& objectState)
00661 {
00662 
00663   Object object = itsObjects[objectState.objectType];
00664   Point2D<int> loc = (Point2D<int>)itsCamera.project(objectState.pos);
00665   float rot = objectState.rot + M_PI;
00666 
00667 
00668   double totalProb = 1;
00669 
00670   for(uint rIdx=0; rIdx<object.rTable.size(); rIdx++)
00671   {
00672           float ang = rot;
00673           float a0 = loc.i - (object.rTable[rIdx].loc.i*cos(ang) - object.rTable[rIdx].loc.j*sin(ang));
00674           float b0 = loc.j - (object.rTable[rIdx].loc.i*sin(ang) + object.rTable[rIdx].loc.j*cos(ang));
00675 
00676     //Get the expected geon
00677     V4::GeonState geonState;
00678           geonState.pos = itsCamera.inverseProjection(Point2D<float>(a0,b0), itsObjectsDist);
00679           geonState.rot = rot + object.rTable[rIdx].rot + M_PI;
00680           geonState.geonType = object.rTable[rIdx].geonType;
00681           geonState.prob = -1;
00682 
00683           while (geonState.rot < 0)
00684                   geonState.rot += M_PI*2;
00685           while(geonState.rot > M_PI*2)
00686                   geonState.rot -= M_PI*2;
00687 
00688 
00689                 //Find the closest naf
00690                 int nearPart = 0;
00691                 float partDist = 1.0e100;
00692                 for(uint i=0; i<itsGeonsState.size(); i++)
00693                 {
00694                         if (itsGeonsState[i].prob > 0)
00695                         {
00696                                 float distance = geonState.distance(itsGeonsState[i]);
00697                                 if (distance < partDist)
00698                                 {
00699                                                 partDist = distance;
00700                                                 nearPart = i;
00701                                 }
00702                         }
00703                 }
00704 
00705                 float sig = 0.75F;
00706                 float prob  = (1.0F/(sig*sqrt(2*M_PI))*exp(-0.5*squareOf(partDist)/squareOf(sig)));
00707 //                LINFO("Dist %f %e", partDist, prob);
00708                 totalProb *= prob;
00709   }
00710 
00711 //        LINFO("Total prob : %e", totalProb);
00712 
00713   objectState.prob = totalProb;
00714 
00715 
00716 }
00717 // ######################################################################
00718 void IT::fixAngle(float& ang)
00719 {
00720   if (ang > M_PI)
00721     ang -= 2*M_PI;
00722 
00723   if (ang < M_PI)
00724     ang += 2*M_PI;
00725 }
00726 
00727 
00728 // ######################################################################
00729 V4::GeonState IT::findNearestGeon(const V4::GeonState& geonState)
00730 {
00731 
00732   V4::GeonState nearestGeon;
00733   nearestGeon.prob = -1;
00734   float minDistance = 1.0e100;
00735 
00736   dense_hash_map<int, V4::GeonState>::const_iterator iter;
00737   for(iter = itsHashedGeonsState.begin(); iter != itsHashedGeonsState.end(); iter++)
00738   {
00739     if (geonState.geonType == iter->second.geonType && iter->second.prob > 0.5)
00740     {
00741 
00742       //geon distance
00743       float dist = getGeonDistance(geonState, iter->second);
00744       if (dist < minDistance)
00745       {
00746         minDistance = dist;
00747         nearestGeon = iter->second;
00748       }
00749     }
00750   }
00751 
00752   return nearestGeon;
00753 }
00754 
00755 // ######################################################################
00756 double IT::getGeonDistance(const V4::GeonState& g1, const V4::GeonState& g2)
00757 {
00758 
00759   double posDist = g1.pos.squdist(g2.pos);
00760   double rotDist = 0;
00761 
00762   return sqrt(posDist + rotDist);
00763 
00764 }
00765 
00766 // ######################################################################
00767 Layout<PixRGB<byte> > IT::getDebugImage()
00768 {
00769   Layout<PixRGB<byte> > outDisp;
00770 
00771   //Show the gabor states
00772   Image<float> perc(320,240, ZEROS);
00773 
00774   Image<PixRGB<byte> > objectDisp = toRGB(Image<byte>(perc));
00775 
00776   //for(uint i=0; i<itsObjectsParticles.size(); i++)
00777   //{
00778   //  if (itsObjectsParticles[i].weight > 0)
00779   //  {
00780   //    Object object=itsObjects[itsObjectsParticles[i].objectType];
00781   //    ObjectState objectState = itsObjectsParticles[i];
00782         //                showObject(objectDisp, object, objectState.pos, objectState.rot);
00783 
00784         //                Point2D<int> textLoc = (Point2D<int>)itsCamera.project(objectState.pos);
00785         //
00786         //                char msg[255];
00787         //                msg[0] = NULL;
00788         //                switch (itsObjectsParticles[i].objectType)
00789         //                {
00790         //                        case HOUSE: sprintf(msg, "HOUSE"); break;
00791         //                        case WOMAN: sprintf(msg, "WOMAN"); break;
00792         //                        case HAT: sprintf(msg, "HAT"); textLoc.j -= 15; break;
00793         //                        case MAN: sprintf(msg, "MAN"); break;
00794         //                        default:
00795         //                                break;
00796         //                }
00797         //                writeText(objectDisp, textLoc, msg, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0));
00798         //
00799   //  }
00800   //}
00801 
00802 
00803         //Show only the max object from each type
00804         for(uint obj = 0; obj < itsObjects.size(); obj++)
00805         {
00806                 int maxObj = -1;
00807                 float max = 0;
00808 
00809                 for(uint i=0; i<itsObjectsParticles.size(); i++)
00810                 {
00811                         if (itsObjectsParticles[i].weight > 0 && itsObjectsParticles[i].objectType == itsObjects[obj].objectType)
00812                         {
00813                                 if (itsObjectsParticles[i].weight > max)
00814                                 {
00815                                         max = itsObjectsParticles[i].weight;
00816                                         maxObj = i;
00817                                 }
00818                         }
00819                 }
00820 
00821                 //Show the max object
00822                 if (maxObj != -1)
00823                 {
00824                         Object object=itsObjects[itsObjectsParticles[maxObj].objectType];
00825                         ObjectState objectState = itsObjectsParticles[maxObj];
00826                         showObject(objectDisp, object, objectState.pos, objectState.rot);
00827 
00828                         Point2D<int> textLoc = (Point2D<int>)itsCamera.project(objectState.pos);
00829                         textLoc.i -= 10;
00830 
00831                         char msg[255];
00832                         msg[0] = 0;
00833                         switch (itsObjectsParticles[maxObj].objectType)
00834                         {
00835                                 case HOUSE: sprintf(msg, "HOUSE"); break;
00836                                 case WOMAN: sprintf(msg, "WOMAN"); break;
00837                                 case HAT: sprintf(msg, "HAT"); textLoc.j -= 20; break;
00838                                 case MAN: sprintf(msg, "MAN"); break;
00839                                 default:
00840                                                                         break;
00841                         }
00842                         writeText(objectDisp, textLoc, msg, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0));
00843 
00844                 }
00845 
00846         }
00847 
00848 
00849   Image<float> particles = showParticles(itsObjectsParticles);
00850 
00851   char msg[255];
00852   sprintf(msg, "IT");
00853   writeText(objectDisp, Point2D<int>(0,0), msg, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0));
00854 
00855   outDisp = hcat(objectDisp, toRGB(Image<byte>(particles)));
00856 
00857   return outDisp;
00858 
00859 }
00860 
00861 // ######################################################################
00862 /* So things look consistent in everyone's emacs... */
00863 /* Local Variables: */
00864 /* indent-tabs-mode: nil */
00865 /* End: */
00866 
00867 #endif
00868 
Generated on Sun May 8 08:41:09 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3