locust_videoAndLaser.C

00001 /*!@file AppDevices/locust_videoAndLaser.H record from high speed camera XC and
00002 Hokuyo Laser Range finder and save to disk*/
00003 
00004 // //////////////////////////////////////////////////////////////////// //
00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00006 // University of Southern California (USC) and the iLab at USC.         //
00007 // See http://iLab.usc.edu for information about this project.          //
00008 // //////////////////////////////////////////////////////////////////// //
00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00011 // in Visual Environments, and Applications'' by Christof Koch and      //
00012 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00013 // pending; application number 09/912,225 filed July 23, 2001; see      //
00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00015 // //////////////////////////////////////////////////////////////////// //
00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00017 //                                                                      //
00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00019 // redistribute it and/or modify it under the terms of the GNU General  //
00020 // Public License as published by the Free Software Foundation; either  //
00021 // version 2 of the License, or (at your option) any later version.     //
00022 //                                                                      //
00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00026 // PURPOSE.  See the GNU General Public License for more details.       //
00027 //                                                                      //
00028 // You should have received a copy of the GNU General Public License    //
00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00031 // Boston, MA 02111-1307 USA.                                           //
00032 // //////////////////////////////////////////////////////////////////// //
00033 //
00034 // Primary maintainer for this file: farhan
00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppDevices/locust_videoAndLaser.C $
00036 // $Id: locust_videoAndLaser.C 12962 2010-03-06 02:13:53Z irock $
00037 //
00038 #include "Component/ModelManager.H"
00039 #include "Devices/RangeFinder.H"
00040 #include "Component/OptionManager.H"
00041 #include "Devices/Serial.H"
00042 #include "Devices/FrameGrabberConfigurator.H"
00043 #include "Devices/DeviceOpts.H"
00044 #include "Image/DrawOps.H"
00045 #include "Image/Image.H"
00046 #include "Image/ShapeOps.H"
00047 #include "Image/CutPaste.H"
00048 #include "Image/ImageCache.H"
00049 #include "Image/Pixels.H"
00050 #include "Image/MathOps.H"
00051 #include "Image/IO.H"
00052 #include "Image/Layout.H"
00053 #include "GUI/SDLdisplay.H"
00054 #include "GUI/GUIOpts.H"
00055 #include "Raster/Raster.H"
00056 #include "Media/FrameSeries.H"
00057 #include "Transport/FrameIstream.H"
00058 #include "Transport/FrameInfo.H"
00059 #include "Util/Timer.H"
00060 #include "Util/log.H"
00061 #include "Util/sformat.H"
00062 #include "Video/RgbConversion.H" // for toVideoYUV422()
00063 #include "Raster/DeBayer.H" // for debayer()
00064 #include "Raster/PlaintextWriter.H"
00065 #include "Robots/LoBot/io/LoLaserRangeFinder.H"
00066 #include <pthread.h>
00067 #include <algorithm>
00068 #include <iterator>
00069 #include <queue>
00070 #include <fstream>
00071 #include <iostream>
00072 
00073 using namespace std;
00074 
00075 #define MAXSAVETHREAD 4
00076 std::vector<std::string> base;
00077 ImageCache<byte> cacheVideo;
00078 ImageCache<PixRGB<byte> > cacheLaserVid;
00079 std::queue<Image<int> > cacheLaser;
00080 pthread_mutex_t qmutex_cache,qmutex_timer, qmutex_laser;
00081 lobot::LaserRangeFinder* lrf = new lobot::LaserRangeFinder();
00082 bool haveLaser = false, haveFrames = false;
00083 uint frameNum = 0,laserNum=0;
00084 std::ofstream laserData, metaVideo, metaLaser;
00085 Timer tim;
00086 
00087 
00088 static void* saveLaser(void *arg)
00089 {
00090 
00091   while(1)
00092     {
00093       Image<int> dists;
00094       Image<int>::iterator aptr, stop;
00095       float rad;
00096       int  min,max;
00097       long int startAng;
00098       Image<PixRGB<byte> > laserImg(512,512,ZEROS);
00099       uint64 t;
00100 
00101       lrf->update();
00102       dists = lrf->get_distances();
00103       pthread_mutex_lock(&qmutex_laser);
00104       cacheLaser.push(dists);
00105       haveLaser = true;
00106       laserNum++;
00107 
00108       pthread_mutex_unlock(&qmutex_laser);
00109 
00110       //write to file
00111       const int w = dists.getWidth();
00112       const int h = dists.getHeight();
00113 
00114       Image<int>::const_iterator itr = dists.begin();
00115       for (int y = 0; y < h; ++y)
00116         {
00117           for (int x = 0; x < w; ++x)
00118             {
00119               laserData<<" "<<*itr;
00120               ++itr;
00121             }
00122           laserData<<"\n";
00123         }
00124 
00125       laserData<<"\n";
00126 
00127       t = tim.get();
00128       metaLaser<<t<<" \t"<<laserNum<<std::endl;
00129 
00130       //try drawing here to see if its faster that way
00131 
00132       if(!cacheLaser.empty())
00133         {
00134           dists = cacheLaser.front();
00135           cacheLaser.pop();
00136           haveLaser = false;
00137           aptr = dists.beginw();
00138           stop = dists.endw();
00139           startAng = -141;
00140 
00141           while(aptr!=stop)
00142             {
00143               rad = *aptr++;
00144               //some scaling
00145               getMinMax(dists, min, max);
00146               rad = ((rad - min)/(max-min))*256;
00147 
00148               if (rad < 0)
00149                 rad =1;
00150 
00151               Point2D<int> pt;
00152               pt.i = 256 - (int) (rad*sin(startAng*M_PI/180.0));
00153               pt.j = 256 - (int) (rad*cos(startAng*M_PI/180.0));
00154 
00155               drawCircle(laserImg, pt, 3, PixRGB<byte>(255,0,0));
00156               drawLine(laserImg, Point2D<int>(256,256),pt,
00157                        PixRGB<byte>(0,255,0));
00158               startAng = startAng+1;
00159               if(startAng > 140)
00160                 startAng = -140;
00161             }
00162           pthread_mutex_lock(&qmutex_laser);
00163           cacheLaserVid.push_back(laserImg);
00164           pthread_mutex_unlock(&qmutex_laser);
00165         }
00166     }
00167 
00168   return NULL;
00169 }
00170 
00171 static void* saveFrames(void *arg)
00172 {
00173 
00174   while(1)
00175   {
00176 
00177     Image<byte> savImg;
00178     uint64 t;
00179     haveFrames = false;
00180     pthread_mutex_lock(&qmutex_cache);
00181     if(cacheVideo.size())
00182       {
00183         savImg = cacheVideo.pop_front();
00184         frameNum++;
00185 
00186         if(cacheVideo.size()) haveFrames = true;
00187 
00188         if (savImg.initialized())
00189           {
00190             const char *b = base[frameNum % (base.size()-3)].c_str();
00191             Raster::WriteGray(savImg, sformat("%s%06u.pgm", b, frameNum));
00192           }
00193         t = tim.get();
00194         metaVideo<<t<<"\t"<<frameNum<<std::endl;
00195       }
00196     pthread_mutex_unlock(&qmutex_cache);
00197     if(haveFrames == false) usleep(1000);
00198   }
00199 
00200   return NULL;
00201 }
00202 
00203 static int submain(const int argc, char** argv)
00204 {
00205   // Image<PixRGB<byte> > dispImg(640,1024,ZEROS);
00206   Image<byte> ima(640,480,ZEROS);
00207   pthread_t frameStreams[MAXSAVETHREAD], laserStream;
00208   uint64 t;
00209 
00210   // instantiate a model manager:
00211   ModelManager manager("locust recording camera + laser");
00212 
00213   nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00214   manager.addSubComponent(ofs);
00215 
00216   nub::soft_ref<FrameGrabberConfigurator>
00217   gbc(new FrameGrabberConfigurator(manager));
00218   manager.addSubComponent(gbc);
00219 
00220   manager.setOptionValString(&OPT_FrameGrabberType, "XC");
00221   manager.setOptionValString(&OPT_FrameGrabberDims, "640x478");
00222 
00223   // Parse command-line:
00224   if (manager.parseCommandLine(argc, argv, "<basename1> <basename2> <basename3> <basename 4>..<laserdatafile> <metaDataVideo> <metaDataLaser>",4, MAXSAVETHREAD+3) == false)
00225     return(1);
00226 
00227  // do post-command-line configs:
00228   nub::soft_ref<FrameIstream> gb = gbc->getFrameGrabber();
00229 
00230   if (gb.isInvalid())
00231     LFATAL("You need to have XC camera and XClibrary");
00232 
00233   // get the basename:
00234   for (uint i = 0; i < manager.numExtraArgs(); i ++)
00235     base.push_back(manager.getExtraArg(i));
00236 
00237   manager.start();
00238 
00239   //start streaming camera
00240   gb->startStream();
00241 
00242   laserData.open(base[4].c_str(), ios::out | ios::ate);
00243   metaVideo.open(base[5].c_str(), ios::out | ios::ate);
00244   metaLaser.open(base[6].c_str(), ios::out | ios::ate);
00245 
00246   for(int ii = 0; ii<(int)base.size()-3; ii++)
00247     pthread_create(frameStreams+ii, NULL, &saveFrames, (void *)NULL);
00248 
00249   //Laser Range finder setup
00250   //declare a new laserRangeFinder object
00251   int rc2 = pthread_create(&laserStream, NULL, &saveLaser, NULL);
00252   if(rc2)
00253     {
00254       LFATAL("cannot create thread");
00255       exit(-1);
00256     }
00257 
00258   Image<PixRGB<byte> > laserImg(512,512,ZEROS);
00259 
00260   while(1)
00261   {
00262       //read from grabber
00263       ima = gb->readGray();
00264       laserImg.clear();
00265 
00266       pthread_mutex_lock(&qmutex_cache);
00267       cacheVideo.push_back(ima);
00268       pthread_mutex_unlock(&qmutex_cache);
00269 
00270       pthread_mutex_lock(&qmutex_laser);
00271       if(cacheLaserVid.size())
00272         laserImg = cacheLaserVid.pop_front();
00273       pthread_mutex_unlock(&qmutex_laser);
00274 
00275       Image<PixRGB<byte> > imgByte = ima;
00276       Layout<PixRGB<byte> >  dispLayout(imgByte);
00277       dispLayout = vcat(dispLayout,laserImg);
00278       //inplacePaste(dispImg, imgByte, Point2D<int>(0,0));
00279       //inplacePaste(dispImg, laserImg, Point2D<int>(0,490));
00280 
00281       ofs->writeRgbLayout(dispLayout,"Output",FrameInfo("output",SRC_POS));
00282 
00283       t = tim.get();
00284       if(t >5000)
00285         {
00286           laserData.close();
00287           metaVideo.close();
00288           metaLaser.close();
00289           manager.stop();
00290           exit(1);
00291         }
00292   }
00293 
00294         laserData.close();
00295         metaVideo.close();
00296         metaLaser.close();
00297         manager.stop();
00298 }
00299 
00300 
00301 
00302 extern "C" int main(const int argc, char** argv)
00303 {
00304   try
00305     {
00306       return submain(argc, argv);
00307     }
00308   catch (...)
00309     {
00310       REPORT_CURRENT_EXCEPTION;
00311     }
00312 
00313   return 1;
00314 }
00315 
00316 // ######################################################################
00317 /* So things look consistent in everyone's emacs... */
00318 /* Local Variables: */
00319 /* indent-tabs-mode: nil */
00320 /* End: */
00321 
00322 
Generated on Sun May 8 08:04:10 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3