Beobot2GistSalMaster.C

Go to the documentation of this file.
00001 /*!@file                                                                */
00002 // //////////////////////////////////////////////////////////////////// //
00003 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00004 // University of Southern California (USC) and the iLab at USC.         //
00005 // See http://iLab.usc.edu for information about this project.          //
00006 // //////////////////////////////////////////////////////////////////// //
00007 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00008 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00009 // in Visual Environments, and Applications'' by Christof Koch and      //
00010 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00011 // pending; application number 09/912,225 filed July 23, 2001; see      //
00012 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00013 // //////////////////////////////////////////////////////////////////// //
00014 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00015 //                                                                      //
00016 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00017 // redistribute it and/or modify it under the terms of the GNU General  //
00018 // Public License as published by the Free Software Foundation; either  //
00019 // version 2 of the License, or (at your option) any later version.     //
00020 //                                                                      //
00021 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00022 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00023 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00024 // PURPOSE.  See the GNU General Public License for more details.       //
00025 //                                                                      //
00026 // You should have received a copy of the GNU General Public License    //
00027 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00028 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00029 // Boston, MA 02111-1307 USA.                                           //
00030 // //////////////////////////////////////////////////////////////////// //
00031 //
00032 // Primary maintainer for this file: Christian Siagian <siagian@usc.edu>
00033 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/Beobot2/Localization/Beobot2GistSalMaster.C $
00034 // $Id: Beobot2GistSalMaster.C 13085 2010-03-30 03:21:24Z siagian $
00035 //
00036 
00037 #include "Robots/Beobot2/Localization/Beobot2GistSalMaster.H"
00038 
00039 #include "Image/MathOps.H"      // for findMax
00040 #include "Image/CutPaste.H"     // for inplacePaste()
00041 #include "Image/DrawOps.H"
00042 #include "Image/FilterOps.H"
00043 #include "Image/PyramidOps.H"
00044 #include "Image/ShapeOps.H"
00045 #include "Image/Transforms.H"
00046 
00047 
00048 #ifndef BEOBOT2GISTSALMASTERI_C
00049 #define BEOBOT2GISTSALMASTERI_C
00050 
00051 #define ERR_INTERVAL 5000
00052 
00053 //! get all the necessary information from the visual cortex
00054 void getBbmtResults
00055 ( nub::soft_ref<BeobotBrainMT> bbmt,
00056   Image<PixRGB<byte> > &currIma, Image<double> &cgist,
00057   Image<float> &currSalMap, ImageSet<float> &cmap,
00058   std::vector<Point2D<int> > &salpt, std::vector<std::vector<double> > &feat,
00059   std::vector<Rectangle> &objRect,
00060   BeobotEvents::GistSalMessagePtr msg);
00061 
00062 //! display results
00063 void dispResults
00064 ( Image< PixRGB<byte> > disp, rutz::shared_ptr<XWinManaged> win,
00065   Image< PixRGB<byte> > ima, Image< PixRGB<byte> > prevIma,
00066   std::vector<Point2D<int> > clmpt, std::vector<Point2D<int> > nlmpt,
00067   Image<float> currSalMap,
00068   std::vector<Point2D<int> > salpt, std::vector<Rectangle> objRect);
00069 
00070 // ######################################################################
00071 Beobot2GistSalMasterI::Beobot2GistSalMasterI(OptionManager& mgr,
00072     const std::string& descrName, const std::string& tagName) :
00073   RobotBrainComponent(mgr, descrName, tagName),
00074   itsIfs(new InputFrameSeries(mgr)),
00075   itsBbmt(new BeobotBrainMT(mgr)),
00076   itsCurrMessageID(-1),
00077   itsInputFrameRate(0),
00078   itsInputTimer(1000000)
00079 {
00080   addSubComponent(itsIfs);
00081   addSubComponent(itsBbmt);
00082 
00083   itsCmap.reset(NUM_CHANNELS);
00084 }
00085 
00086 // ######################################################################
00087 void Beobot2GistSalMasterI::start1()
00088 {
00089 
00090   int w = itsIfs->getWidth(),
00091       h = itsIfs->getHeight();
00092   std::string dims = convertToString(Dims(w, h));
00093   LINFO("image size: [%4dx%4d]", w, h);
00094 
00095   // image buffer and window for display:
00096   //itsDisp = Image<PixRGB<byte> >(w * 5, h, ZEROS);
00097   // //itsDisp = Image<PixRGB<byte> >(w, h, ZEROS);
00098   //itsMwin.reset
00099   //  (new XWinManaged(itsDisp.getDims(), 0, 0, "Master window"));
00100 
00101   itsNextFrameFlag = true;
00102   itsInputTimer.reset();
00103   itsTimes.clear();
00104 }
00105 
00106 // ######################################################################
00107 Beobot2GistSalMasterI::~Beobot2GistSalMasterI()
00108 { }
00109 
00110 // ######################################################################
00111 void Beobot2GistSalMasterI::registerTopics()
00112 {
00113   this->registerPublisher("GistSalMessageTopic");
00114   this->registerPublisher("AbortMessageTopic");
00115 
00116   this->registerSubscription("NextFrameMessageTopic");
00117 }
00118 
00119 // ######################################################################
00120 void Beobot2GistSalMasterI::evolve()
00121 {
00122   // check if we can go to next frame
00123   if((itsInputFrameRate == 0 && itsNextFrameFlag) ||
00124      (itsInputFrameRate != 0 &&
00125       itsInputTimer.get() > (itsInputFrameRate - ERR_INTERVAL)))
00126     {
00127       if(itsCurrMessageID != -1)
00128         {
00129           float loopTime = itsInputTimer.get()/1000.0F;
00130           itsTimes.push_back(loopTime);
00131           LINFO("[%5d] Time: %f", itsCurrMessageID, loopTime);
00132         }
00133       itsInputTimer.reset();
00134       itsNextFrameFlag = false;
00135       itsCurrMessageID++;
00136 
00137       // get the next frame and start processing
00138       std::vector<float> procTime;
00139       Image<PixRGB<byte> > ima; //int32 fNum = itsCurrMessageID;//fstart;
00140       Image<PixRGB<byte> > prevIma;
00141       itsIfs->updateNext(); ima = itsIfs->readRGB();
00142       if(ima.initialized())
00143         {
00144           itsBbmt->input(ima);
00145 
00146           // wait until the saliency and gist computation is ready
00147           Timer bbmtTimer(1000000);
00148           // this takes 40 ms or so
00149           while(!itsBbmt->outputReady()) usleep(100);
00150           float bbmtTime = bbmtTimer.get()/1000.0F;
00151           LINFO("BBMT Time: %f", bbmtTime);
00152 
00153           // prepare the Sal Regions and Gist features message
00154           BeobotEvents::GistSalMessagePtr msg =
00155             new BeobotEvents::GistSalMessage;
00156 
00157           // get all the necesary information from V1:
00158           Image<PixRGB<byte> > currIma; Image<float> currSalMap;
00159           Image<double> cgist;
00160           std::vector<Point2D<int> > salpt;
00161           std::vector<std::vector<double> >feat;
00162           std::vector<Rectangle> objRect;
00163           getBbmtResults(itsBbmt, currIma, cgist, currSalMap,
00164                          itsCmap, salpt, feat, objRect, msg);
00165 
00166           // display the results
00167           // //itsMwin->drawImage(currIma,0,0);
00168           //itsMwin->setTitle(sformat("fNum: %d",fNum).c_str());      
00169           //dispResults(itsDisp, itsMwin, currIma, prevIma, 
00170           //            itsClmpt, itsNlmpt,
00171           //            currSalMap, salpt, objRect);
00172 
00173           msg->RequestID = itsCurrMessageID;
00174 
00175           // publish the message
00176           LINFO("Publishing Message with ID: %d", itsCurrMessageID);
00177           publish("GistSalMessageTopic", msg);
00178         }
00179 
00180       // we are done
00181       else
00182         {
00183           // display the loop statistics
00184           double meanTime, minTime, maxTime, stdevTime;
00185           Image<double> t1(1, itsTimes.size(),NO_INIT);
00186           for(uint i = 0; i < itsTimes.size(); i++)
00187             t1.setVal(0, i, double(itsTimes[i]));
00188 
00189           meanTime = mean(t1);
00190           getMinMax(t1, minTime, maxTime);
00191           stdevTime = stdev(t1);
00192 
00193           LINFO("Time: %f (%f - %f) std: %f",
00194                 meanTime, minTime, maxTime, stdevTime);
00195 
00196           // send an abort message
00197           BeobotEvents::AbortMessagePtr msg =
00198             new BeobotEvents::AbortMessage;
00199 
00200           LINFO("Publishing AbortMessage");
00201           publish("AbortMessageTopic", msg);
00202 
00203           sleep(5);
00204           exit(0);
00205         }
00206     }
00207 }
00208 
00209 // ######################################################################
00210 void Beobot2GistSalMasterI::updateMessage
00211 (const RobotSimEvents::EventMessagePtr& eMsg, const Ice::Current&)
00212 {
00213   //Get a retina message
00214   if(eMsg->ice_isA("::BeobotEvents::NextFrameMessage"))
00215     {
00216       LINFO("NextFrameMessage - go to the next frame");
00217       if(itsInputFrameRate == 0)
00218         {
00219           //Raster::waitForKey();
00220           itsNextFrameFlag = true;
00221         }
00222     }
00223 }
00224 
00225 // ######################################################################
00226 bool checkInput(int opMode, bool resetNextLandmark, uint64 inputFrameRate,
00227                 uint64 inputTime)
00228 {
00229   // if train mode: need to have a ventral reset signal
00230   if(opMode == TRAIN_MODE && resetNextLandmark) return true;
00231 
00232   // if test mode and using infinite time: need reset signal
00233   if(opMode == TEST_MODE && inputFrameRate == 0 &&
00234      resetNextLandmark) return true;
00235 
00236   // else test mode and need to get in after time is up
00237   if(opMode == TEST_MODE && inputFrameRate != 0 &&
00238      (inputFrameRate - ERR_INTERVAL) < inputTime) return true;
00239 
00240   return false;
00241 }
00242 
00243 // ######################################################################
00244 void getBbmtResults
00245 ( nub::soft_ref<BeobotBrainMT> bbmt,
00246   Image<PixRGB<byte> > &currIma, Image<double> &cgist,
00247   Image<float> &currSalMap, ImageSet<float> &cmap,
00248   std::vector<Point2D<int> > &salpt,  std::vector<std::vector<double> > &feat,
00249   std::vector<Rectangle> &objRect,
00250   BeobotEvents::GistSalMessagePtr msg)
00251 {
00252   // current image, gist vector, and saliency map
00253   currIma    = bbmt->getCurrImage();
00254   cgist      = bbmt->getGist();
00255   currSalMap = bbmt->getSalMap();
00256 
00257   // current conspicuity maps
00258   for(uint i = 0; i < NUM_CHANNELS; i++) cmap[i] = bbmt->getCurrCMap(i);
00259 
00260   salpt.clear(); objRect.clear();
00261   uint numpt = bbmt->getNumSalPoint();
00262   for(uint i = 0; i < numpt; i++)
00263     {
00264       salpt.push_back(bbmt->getSalPoint(i));
00265       objRect.push_back(bbmt->getObjRect(i));
00266 
00267       // store the salient point location
00268       BeobotEvents::SalientRegion salReg;
00269       salReg.salpt.i = salpt[i].i;
00270       salReg.salpt.j = salpt[i].j;
00271       salReg.objRect.tl.i = objRect[i].topLeft().i;
00272       salReg.objRect.tl.j = objRect[i].topLeft().j;
00273       salReg.objRect.br.i = objRect[i].bottomRight().i;
00274       salReg.objRect.br.j = objRect[i].bottomRight().j;
00275       LDEBUG("[%4d] sp[%4d,%4d] rect[%4d,%4d,%4d,%4d]",
00276              i, salpt[i].i, salpt[i].j,
00277              objRect[i].topLeft().i,objRect[i].topLeft().j,
00278              objRect[i].bottomRight().i,objRect[i].bottomRight().j);
00279 
00280       std::vector<double> features; bbmt->getSalientFeatures(i, features);
00281       feat.push_back(features);
00282 
00283       // store the salient feature vector
00284       for(uint j = 0; j < features.size(); j++)
00285         {
00286           salReg.salFeatures.push_back(feat[i][j]);
00287           LDEBUG("[%4d]:%7f", j, feat[i][j]);
00288         }
00289       msg->salientRegions.push_back(salReg);
00290     }
00291 
00292   // store the input image
00293   msg->currIma = Image2Ice(currIma);
00294 
00295   // store the conspicuity maps
00296   for(uint i = 0; i < NUM_CHANNELS; i++)
00297     msg->conspicuityMaps.push_back(Image2Ice(cmap[i]));
00298 
00299   // store the gist in the message
00300   for(uint i = 0; i < cgist.size(); i++)
00301     msg->gistFeatures.push_back(cgist[i]);
00302 }
00303 
00304 // ######################################################################
00305 void dispResults
00306 ( Image< PixRGB<byte> > disp, rutz::shared_ptr<XWinManaged> win,
00307   Image< PixRGB<byte> > ima, Image< PixRGB<byte> > prevIma,
00308   std::vector<Point2D<int> > clmpt, std::vector<Point2D<int> > nlmpt,
00309   Image<float> currSalMap,
00310   std::vector<Point2D<int> > salpt, std::vector<Rectangle> objRect)
00311 {
00312   int w = ima.getWidth();
00313   int h = ima.getHeight();
00314   const int foa_size = std::min(w, h) / 12;
00315 
00316   // display input image:
00317   inplacePaste(disp, ima, Point2D<int>(0, 0));
00318 
00319   // display the saliency map
00320   Image<float> dispsm = quickInterpolate(currSalMap * SMFAC, 1 << sml);
00321   inplaceNormalize(dispsm, 0.0f, 255.0f);
00322   Image<PixRGB<byte> > sacImg = Image<PixRGB<byte> >(toRGB(dispsm));
00323   for(uint i = 0; i < objRect.size(); i++)
00324     drawRect(sacImg,objRect[i],PixRGB<byte>(255,0,0));
00325   inplacePaste(disp, sacImg, Point2D<int>(w, 0));
00326 
00327   // draw coordinates of fixation for both input and sal image
00328   for(uint i = 0; i < salpt.size(); i++)
00329     {
00330       Point2D<int> salpt2(salpt[i].i + w, salpt[i].j);
00331       drawDisk(disp, salpt[i], foa_size/6+2, PixRGB<byte>(20, 50, 255));
00332       drawDisk(disp, salpt[i], foa_size/6,   PixRGB<byte>(255, 255, 20));
00333       drawDisk(disp, salpt2,   foa_size/6+2, PixRGB<byte>(20, 50, 255));
00334       drawDisk(disp, salpt2,   foa_size/6,   PixRGB<byte>(255, 255, 20));
00335     }
00336 
00337   // draw the SE bounding box
00338   Image< PixRGB<byte> > roiImg = ima;
00339   for(uint i = 0; i < objRect.size(); i++)
00340     {
00341       drawRect(roiImg, objRect[i], PixRGB<byte>(255,255,0));
00342       drawDisk(roiImg, salpt[i], 3, PixRGB<byte>(255,0,0));
00343       std::string ntext(sformat("%d", i));
00344       writeText(roiImg, salpt[i], ntext.c_str());
00345     }
00346   inplacePaste(disp, roiImg, Point2D<int>(w*2, 0));
00347 
00348   // if there is a previous image
00349   if(prevIma.initialized())
00350     {
00351       // display the current landmark tracked
00352       Image< PixRGB<byte> > clmDisp = prevIma;
00353         for(uint i = 0; i < clmpt.size(); i++)
00354           {
00355             if(clmpt[i].isValid())
00356               {
00357                 drawDisk(clmDisp, clmpt[i], 3, PixRGB<byte>(0,255,0));
00358                 std::string ntext(sformat("%d", i));
00359                 writeText(clmDisp, clmpt[i], ntext.c_str());
00360               }
00361           }
00362         inplacePaste(disp, clmDisp, Point2D<int>(w*3, 0));
00363 
00364         // display the next landmark tracked
00365         Image< PixRGB<byte> > nlmDisp = prevIma;
00366         for(uint i = 0; i < nlmpt.size(); i++)
00367           {
00368             if(nlmpt[i].isValid())
00369               {
00370                 drawDisk(nlmDisp, nlmpt[i], 3, PixRGB<byte>(0,255,255));
00371                 std::string ntext(sformat("%d", i));
00372                 writeText(nlmDisp, nlmpt[i], ntext.c_str());
00373               }
00374           }
00375         inplacePaste(disp, nlmDisp, Point2D<int>(w*4, 0));
00376     }
00377 
00378   // display the image
00379   //win->drawImage(disp,0,0);
00380 }
00381 
00382 #endif
00383 
00384 // ######################################################################
00385 /* So things look consistent in everyone's emacs... */
00386 /* Local Variables: */
00387 /* indent-tabs-mode: nil */
00388 /* End: */
Generated on Sun May 8 08:41:18 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3