beobot-collectFrames-master.C

Go to the documentation of this file.
00001 /*!@file Beobot/beobot-collectFrames-master.C
00002   Run beobot-collectFrames-master at A to collect frames
00003   Run beobot-collectFrames at B to remote control motion */
00004 
00005 // //////////////////////////////////////////////////////////////////// //
00006 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00007 // University of Southern California (USC) and the iLab at USC.         //
00008 // See http://iLab.usc.edu for information about this project.          //
00009 // //////////////////////////////////////////////////////////////////// //
00010 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00011 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00012 // in Visual Environments, and Applications'' by Christof Koch and      //
00013 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00014 // pending; application number 09/912,225 filed July 23, 2001; see      //
00015 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00016 // //////////////////////////////////////////////////////////////////// //
00017 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00018 //                                                                      //
00019 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00020 // redistribute it and/or modify it under the terms of the GNU General  //
00021 // Public License as published by the Free Software Foundation; either  //
00022 // version 2 of the License, or (at your option) any later version.     //
00023 //                                                                      //
00024 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00025 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00026 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00027 // PURPOSE.  See the GNU General Public License for more details.       //
00028 //                                                                      //
00029 // You should have received a copy of the GNU General Public License    //
00030 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00031 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00032 // Boston, MA 02111-1307 USA.                                           //
00033 // //////////////////////////////////////////////////////////////////// //
00034 //
00035 // Primary maintainer for this file: Christian Siagian <siagian@usc.edu>
00036 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Beobot/beobot-collectFrames-master.C $
00037 // $Id: beobot-collectFrames-master.C 9412 2008-03-10 23:10:15Z farhan $
00038 //
00039 
00040 #include "Beowulf/Beowulf.H"
00041 #include "Component/ModelManager.H"
00042 #include "Util/Types.H"
00043 #include "Util/log.H"
00044 
00045 #include <cstdio>
00046 #include <cstdlib>
00047 #include <signal.h>
00048 #include <unistd.h>
00049 
00050 #include "Devices/FrameGrabberConfigurator.H"
00051 #include "Image/DrawOps.H"
00052 #include "Transport/FrameIstream.H"
00053 //#include "Image/Image.H"
00054 #include "Image/ImageCache.H"
00055 #include "Image/Pixels.H"
00056 #include "Raster/Raster.H"
00057 #include "Util/Timer.H"
00058 // #include <pthread.h>
00059 
00060 #include "GUI/XWinManaged.H"
00061 #include "GUI/XWindow.H"
00062 
00063 //! number of frames over which frame rate is computed
00064 #define NAVG 20
00065 
00066 //! Maximum number of frames in queue
00067 #define MAXQLEN 1000
00068 
00069 
00070 pthread_mutex_t qmutex;
00071 pthread_mutex_t smutex;
00072 ImageCache< PixRGB<byte> > cache;
00073 std::string base;
00074 int sessionNum = 0;
00075 
00076 static bool goforever = true;
00077 
00078 // ######################################################################
00079 void* saveframes(void *)
00080 {
00081   int fnb = 0; int sNum= -1;
00082   while(1) {
00083     Image< PixRGB<byte> > ima; bool havemore = false;
00084 
00085     // do we have images ready to go?
00086     pthread_mutex_lock(&qmutex);
00087     if (cache.size()) ima = cache.pop_front();
00088     if (cache.size()) havemore = true;
00089     pthread_mutex_unlock(&qmutex);
00090 
00091     int tNum;
00092     pthread_mutex_lock(&smutex);
00093     tNum = sessionNum-1;
00094     pthread_mutex_unlock(&smutex);
00095 
00096     if(sNum < tNum)
00097       {
00098         sNum = tNum;
00099         fnb = 0;
00100       }
00101 
00102     // if we got an image, save it:
00103     if (ima.initialized())
00104       {
00105         Raster::WriteRGB(ima, sformat("%s%03d_%06d.ppm",
00106                                       base.c_str(), sNum, fnb));
00107         LINFO("saving %s%03d_%06d", base.c_str(), sNum, fnb);
00108         fnb++;
00109       }
00110     if (havemore == false) usleep(1000);
00111   }
00112   return NULL;
00113 }
00114 
00115 // ######################################################################
00116 void terminate(int s)
00117 { LERROR("*** INTERRUPT ***"); goforever = false; exit(1); }
00118 
00119 // ######################################################################
00120 /*! Displays and grabs video feeds to disk.  Selection of  grabber type
00121     is made via the --fg-type=XX command-line option.
00122     Frames are pushed into a queue and a second thread then
00123     tries to empty the queue as quickly as possible by writing the
00124     frames to disk. In testing, PPM format actually gave better frame
00125     rates than PNG, which is what is used.
00126 
00127     The starting command is supplied from the beoChip keyboard
00128 */
00129 int main(const int argc, const char **argv)
00130 {
00131   // instantiate a model manager:
00132   ModelManager manager("Beobot: collect frames - Master");
00133 
00134   // Instantiate our various ModelComponents:
00135   nub::soft_ref<Beowulf>
00136     beo(new Beowulf(manager, "Beowulf Master", "BeowulfMaster", true));
00137   manager.addSubComponent(beo);
00138 
00139   nub::soft_ref<FrameGrabberConfigurator>
00140     gbc(new FrameGrabberConfigurator(manager));
00141   manager.addSubComponent(gbc);
00142 
00143   // Parse command-line:
00144   if (manager.parseCommandLine(argc, argv, "<base>", 1, 1) == false) return(1);
00145 
00146   // do post-command-line configs:
00147   nub::soft_ref<FrameIstream> gb = gbc->getFrameGrabber();
00148   if (gb.isInvalid())
00149     LFATAL("You need to select a frame grabber type via the "
00150             "--fg-type=XX command-line option for this program "
00151            "to be useful -- ABORT");
00152   //int w = gb->getWidth(), h = gb->getHeight();
00153 
00154   // display window
00155   XWindow win(gb->peekDims(), -1, -1, "grab window");
00156 
00157   TCPmessage rmsg;      // buffer to receive messages from nodes
00158   TCPmessage smsg;      // buffer to send messages to nodes
00159 
00160   // get the basename:
00161   base = manager.getExtraArg(0);//"../data/beobotCF_";
00162 
00163   // let's get all our ModelComponent instances started:
00164   manager.start();
00165 
00166   // catch signals and redirect them to terminate for clean exit:
00167   signal(SIGHUP, terminate); signal(SIGINT, terminate);
00168   signal(SIGQUIT, terminate); signal(SIGTERM, terminate);
00169   signal(SIGALRM, terminate);
00170 
00171   // get ready for main loop:
00172   int32 rframe = 0, raction = 0, rnode = 0;
00173   // this code is just for one slave for now
00174   //const int nbnode = beo->getNbSlaves(); // number of slave nodes
00175 
00176   // activate the saving thread
00177   Timer tim; uint64 t[NAVG]; float frate = 0.0f;
00178   pthread_t saver;
00179   pthread_create(&saver, NULL, &saveframes, (void *)NULL);
00180   bool saving = false;
00181 
00182   // get the frame grabber to start streaming:
00183   gb->startStream();
00184 
00185   // send image to slave node to initialize contact:
00186   smsg.reset(rframe, 1);
00187   smsg.addFloat(2.3434);
00188   beo->send(rnode, smsg);
00189 
00190   // grab, display and save:
00191   int fNum = 0;
00192   while(goforever)
00193   {
00194     tim.reset();
00195 
00196     // grab a frame
00197     Image< PixRGB<byte> > ima = gb->readRGB();
00198 
00199     // to measure display time:
00200     uint64 t0 = tim.get();
00201 
00202     // check if we need to start(1) or stop(0) saving
00203     if(beo->receive(rnode, rmsg, rframe, raction, 5))
00204       {
00205         LINFO("receiving");
00206         const int32 val = rmsg.getElementInt32();
00207         bool msg = bool(val);
00208         rmsg.reset(rframe, raction);
00209         if(msg)
00210           LINFO("start capturing");
00211         else
00212           LINFO("stop capturing");
00213 
00214         // if we are start saving
00215         if(!saving & msg)
00216           {
00217             pthread_mutex_lock(&smutex);
00218             sessionNum++;
00219             pthread_mutex_unlock(&smutex);
00220             saving = true;
00221           }
00222         else if(saving & !msg)
00223           {
00224             saving = false;
00225           }
00226       }
00227 
00228     // if saving, push image into queue:
00229     if (saving)
00230       {
00231         pthread_mutex_lock(&qmutex);
00232         cache.push_back(ima);
00233         pthread_mutex_unlock(&qmutex);
00234         char msg[30]; sprintf(msg, " %.1ffps [%04d] ", frate, cache.size());
00235         writeText(ima,Point2D<int>(0, 0), msg, PixRGB<byte>(255), PixRGB<byte>(0));
00236       }
00237     else // tell user we are ready to save
00238       {
00239         char msg[30]; sprintf(msg, " [SPC] to save [%04d] ", cache.size());
00240         writeText(ima,Point2D<int>(0, 0), msg, PixRGB<byte>(255), PixRGB<byte>(0));
00241       }
00242 
00243     // show the frame:
00244     win.drawImage(ima);
00245 
00246     t[fNum % NAVG] = tim.get();
00247     t0 = t[fNum % NAVG] - t0;
00248     if (t0 > 20000ULL) LINFO("Display took %lluus", t0);
00249 
00250     // compute and show framerate over the last NAVG frames:
00251     if (fNum % NAVG == 0 && fNum > 0)
00252       {
00253         uint64 avg = 0ULL; for (int i = 0; i < NAVG; i ++) avg += t[i];
00254         frate = 1000.0F / float(avg) * float(NAVG);
00255       }
00256 
00257       fNum++;
00258     }
00259 
00260   // stop all our ModelComponents
00261   manager.stop();
00262 
00263   // all done!
00264   return 0;
00265 }
00266 
00267 // ######################################################################
00268 /* So things look consistent in everyone's emacs... */
00269 /* Local Variables: */
00270 /* indent-tabs-mode: nil */
00271 /* End: */
Generated on Sun May 8 08:40:11 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3