test-SaliencyMT.C

Go to the documentation of this file.
00001 /*!@file Demo/test-SaliencyMT.C tests the multi-threaded salincy code */
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: Zack Gossman <gossman@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Demo/test-SaliencyMT.C $
00035 // $Id: test-SaliencyMT.C 12074 2009-11-24 07:51:51Z itti $
00036 //
00037 
00038 #ifndef TESTSALIENCYMT_H_DEFINED
00039 #define TESTSALIENCYMT_H_DEFINED
00040 
00041 #include "Component/ModelManager.H"
00042 #include "Demo/SaliencyMT.H"
00043 #include "Devices/DeviceOpts.H"
00044 #include "Devices/FrameGrabberConfigurator.H"
00045 #include "GUI/XWindow.H"
00046 #include "Image/CutPaste.H"     // for inplacePaste()
00047 #include "Image/Image.H"
00048 #include "Image/Pixels.H"
00049 #include "Neuro/NeuroOpts.H"
00050 #include "Neuro/SaccadeController.H"
00051 #include "Neuro/SaccadeControllerConfigurator.H"
00052 #include "Raster/Raster.H"
00053 #include "Simulation/SimEventQueue.H"
00054 #include "Simulation/SimEventQueueConfigurator.H"
00055 #include "Transport/FrameIstream.H"
00056 #include "Util/Timer.H"
00057 
00058 #include <arpa/inet.h>
00059 #include <fcntl.h>
00060 #include <netdb.h>
00061 #include <signal.h>
00062 #include <cstdio>
00063 #include <unistd.h>
00064 
00065 //! Number of frames over which average framerate is computed
00066 #define NAVG 20
00067 
00068 //! Factor to display the sm values as greyscale:
00069 #define SMFAC 0.05F
00070 
00071 // UDP communications:
00072 #define UDPHOST "192.168.0.8"
00073 #define UDPPORT 5003
00074 
00075 static bool goforever = true;  //!< Will turn false on interrupt signal
00076 
00077 //! Signal handler (e.g., for control-C)
00078 void terminate(int s)
00079 { LERROR("*** INTERRUPT ***"); goforever = false; exit(1); }
00080 
00081 // ######################################################################
00082 int main(const int argc, const char **argv)
00083 {
00084   MYLOGVERB = LOG_INFO;
00085 
00086   // instantiate a model manager (for camera input):
00087   ModelManager manager("SaliencyMT Tester");
00088 
00089   // Instantiate our various ModelComponents:
00090   nub::soft_ref<SimEventQueueConfigurator>
00091     seqc(new SimEventQueueConfigurator(manager));
00092   manager.addSubComponent(seqc);
00093 
00094   nub::ref<FrameGrabberConfigurator>
00095     gbc(new FrameGrabberConfigurator(manager));
00096   manager.addSubComponent(gbc);
00097 
00098   nub::ref<SaliencyMT> smt(new SaliencyMT(manager));
00099   manager.addSubComponent(smt);
00100 
00101   nub::ref<SaccadeControllerEyeConfigurator>
00102     scc(new SaccadeControllerEyeConfigurator(manager));
00103   manager.addSubComponent(scc);
00104 
00105   // Set the appropriate defaults for our machine that is connected to
00106   // Stefan's robot head:
00107   manager.exportOptions(MC_RECURSE);
00108   manager.setOptionValString(&OPT_FrameGrabberType, "V4L");
00109   manager.setOptionValString(&OPT_FrameGrabberChannel, "1");
00110   manager.setOptionValString(&OPT_FrameGrabberHue, "0");
00111   manager.setOptionValString(&OPT_FrameGrabberContrast, "16384");
00112   manager.setOptionValString(&OPT_FrameGrabberDims, "320x240");
00113   manager.setOptionValString(&OPT_SaccadeControllerEyeType, "Threshfric");
00114   manager.setOptionValString(&OPT_SCeyeMaxIdleSecs, "1000.0");
00115   manager.setOptionValString(&OPT_SCeyeThreshMinOvert, "4.0");
00116   manager.setOptionValString(&OPT_SCeyeThreshMaxCovert, "3.0");
00117   manager.setOptionValString(&OPT_SCeyeThreshMinNum, "2");
00118   //  manager.setOptionValString(&OPT_SCeyeSpringK, "1000000.0");
00119 
00120   // Parse command-line:
00121   if (manager.parseCommandLine(argc, argv, "", 0, 0) == false) return(1);
00122 
00123   // do post-command-line configs:
00124   nub::soft_ref<SimEventQueue> seq = seqc->getQ();
00125 
00126   nub::soft_ref<FrameIstream> gb = gbc->getFrameGrabber();
00127   if (gb.isInvalid())
00128     LFATAL("You need to select a frame grabber type via the "
00129            "--fg-type=XX command-line option for this program "
00130            "to be useful");
00131   const int w = gb->getWidth(), h = gb->getHeight();
00132 
00133   nub::ref<SaccadeController> sc = scc->getSC();
00134 
00135   const int foa_size = std::min(w, h) / 12;
00136   manager.setModelParamVal("InputFrameDims", Dims(w, h),
00137                            MC_RECURSE | MC_IGNORE_MISSING);
00138   manager.setModelParamVal("SCeyeStartAtIP", true,
00139                            MC_RECURSE | MC_IGNORE_MISSING);
00140   manager.setModelParamVal("SCeyeInitialPosition", Point2D<int>(w/2,h/2),
00141                            MC_RECURSE | MC_IGNORE_MISSING);
00142   manager.setModelParamVal("FOAradius", foa_size,
00143                            MC_RECURSE | MC_IGNORE_MISSING);
00144   manager.setModelParamVal("FoveaRadius", foa_size,
00145                            MC_RECURSE | MC_IGNORE_MISSING);
00146 
00147   // catch signals and redirect them to terminate for clean exit:
00148   signal(SIGHUP, terminate); signal(SIGINT, terminate);
00149   signal(SIGQUIT, terminate); signal(SIGTERM, terminate);
00150   signal(SIGALRM, terminate);
00151 
00152   // setup socket:
00153   int sock = socket(AF_INET, SOCK_DGRAM, 0);
00154   if (sock == -1) PLFATAL("Cannot create server socket");
00155 
00156   // figure out destination address:
00157   struct hostent *he = gethostbyname(UDPHOST);
00158   if (he == NULL) LFATAL("Cannot gethostbyname on %s", UDPHOST);
00159 
00160   struct sockaddr_in destaddr;
00161   destaddr.sin_family = AF_INET;
00162   destaddr.sin_addr.s_addr =
00163     inet_addr(inet_ntoa(*((in_addr *)(he->h_addr_list[0]))));
00164   destaddr.sin_port = htons(UDPPORT);
00165 
00166   // get prepared to grab, communicate, display, etc:
00167   uint frame = 0U;                  // count the frames
00168   uint lastframesent = 0U;          // last frame sent for processing
00169 
00170   uint64 avgtime = 0; int avgn = 0; // for average framerate
00171   float fps = 0.0F;                 // to display framerate
00172   Timer tim;                        // for computation of framerate
00173   Timer masterclock;                // master clock for simulations
00174 
00175   int sml = 3;                      // pyramid level of saliency map
00176   Image<float> sm(w >> sml, h >> sml, ZEROS); // saliency map
00177   Point2D<int> fixation(-1, -1);         // coordinates of eye fixation
00178 
00179   // image buffer for display:
00180   Image<PixRGB<byte> > disp(w * 2, h + 20, ZEROS);
00181   disp += PixRGB<byte>(128);
00182   XWindow xwin(disp.getDims(), -1, -1, "USC Robot Demo");
00183 
00184   ///  int ovlyoff = (w * 2) * ((dh - disp.getHeight()) / 2);
00185   ///int ovluvoff = ovlyoff / 4;
00186 
00187   char info[1000];  // general text buffer for various info messages
00188 
00189   Point2D<int> lastpointsent(w/2, h/2);
00190 
00191   // ######################################################################
00192   try {
00193     // let's do it!
00194     manager.start();
00195 
00196     // get the frame grabber to start streaming:
00197     gb->startStream();
00198 
00199     // initialize the timers:
00200     tim.reset(); masterclock.reset();
00201 
00202     while(goforever)
00203       {
00204         // grab image:
00205         Image< PixRGB<byte> > ima = gb->readRGB();
00206 
00207         // display image:
00208         inplacePaste(disp, ima, Point2D<int>(0, 0));
00209         Image<float> dispsm = sm * SMFAC;
00210         inplacePaste(disp, Image<PixRGB<byte> >
00211                      (toRGB(quickInterpolate(dispsm, 1 << sml))),
00212                      Point2D<int>(w, 0));
00213 
00214         sc->evolve(*seq);
00215         Point2D<int> eye = sc->getDecision(*seq);
00216         if (eye.i >= 0) fixation = eye;
00217         Point2D<int> fix2(fixation); fix2.i += w;
00218         if (fixation.i >= 0)
00219           {
00220             drawDisk(disp, fixation, foa_size/6+2, PixRGB<byte>(20, 50, 255));
00221             drawDisk(disp, fixation, foa_size/6, PixRGB<byte>(255, 255, 20));
00222             drawDisk(disp, fix2, foa_size/6+2, PixRGB<byte>(20, 50, 255));
00223             drawDisk(disp, fix2, foa_size/6, PixRGB<byte>(255, 255, 20));
00224           }
00225 
00226         xwin.drawImage(disp);
00227 
00228         // are we ready to process a new frame? if so, send our new one:
00229         if (smt->outputReady())
00230           {
00231             // let's get the previous results, if any:
00232             Image<float> out = smt->getOutput();
00233             if (out.initialized()) sm = out;
00234 
00235             // find most salient location and feed saccade controller:
00236             float maxval; Point2D<int> currwin; findMax(sm, currwin, maxval);
00237             WTAwinner newwin =
00238               WTAwinner::buildFromSMcoords(currwin, sml, true,
00239                                            masterclock.getSimTime(),
00240                                            maxval, false);
00241             if (newwin.isValid()) sc->setPercept(newwin, *seq);
00242 
00243             // feed our current image as next one to process:
00244             smt->newInput(decXY(ima));
00245             lastframesent = frame;
00246             //LINFO("Processing frame %u", frame);
00247 
00248             // send UDP packet:
00249             lastpointsent.i = newwin.p.i * 2; lastpointsent.j = newwin.p.j * 2;
00250 
00251             const size_t buflen = 4;
00252             int buf[buflen];
00253             buf[0] = htonl(1234);            buf[1] = htonl(lastpointsent.i);
00254             buf[2] = htonl(lastpointsent.j); buf[3] = htonl(5678);
00255 
00256             // send message:
00257             size_t ret = sendto(sock, buf, buflen * sizeof(int), 0,
00258                                 (sockaddr*)(&destaddr), sizeof(destaddr));
00259             if (ret != buflen * sizeof(int))
00260               LERROR("Only %"ZU"/%"ZU" bytes sent to %s:%d", ret, buflen*sizeof(int),
00261                      inet_ntoa(destaddr.sin_addr),
00262                      ntohs(destaddr.sin_port));
00263           }
00264 
00265         // compute and show framerate and stats over the last NAVG frames:
00266         avgtime += tim.getReset(); avgn ++;
00267         if (avgn == NAVG)
00268           {
00269             fps = 1000.0F / float(avgtime) * float(avgn);
00270             avgtime = 0; avgn = 0;
00271           }
00272 
00273         // create an info string:
00274         sprintf(info, "USC - %06u / %06u - [%03d %03d] to %s:%d - %.1ffps    ",
00275                 frame, lastframesent, lastpointsent.i, lastpointsent.j,
00276                 inet_ntoa(destaddr.sin_addr), ntohs(destaddr.sin_port), fps);
00277 
00278         writeText(disp, Point2D<int>(0, h), info,
00279                   PixRGB<byte>(255), PixRGB<byte>(127));
00280 
00281         // ready for next frame:
00282         ++ frame;
00283         while(seq->now() < masterclock.getSimTime()) seq->evolve();
00284       }
00285 
00286     // get ready to terminate:
00287     manager.stop();
00288     close(sock);
00289 
00290   } catch ( ... ) { };
00291 
00292   return 0;
00293 }
00294 
00295 #endif
00296 // ######################################################################
00297 /* So things look consistent in everyone's emacs... */
00298 /* Local Variables: */
00299 /* indent-tabs-mode: nil */
00300 /* End: */
Generated on Sun May 8 08:40:37 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3