00001 /*!@file CMapDemo/test-SaliencyCMapMT.C tests the multi-threaded salincy code with 00002 a cmap corba object 00003 */ 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: Zack Gossman <gossman@usc.edu> 00036 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/CMapDemo/test-SaliencyCMapMT.C $ 00037 // $Id: test-SaliencyCMapMT.C 9412 2008-03-10 23:10:15Z farhan $ 00038 // 00039 00040 #ifndef TESTSALIENCYMT_H_DEFINED 00041 #define TESTSALIENCYMT_H_DEFINED 00042 00043 #include "CMapDemo/SaliencyCMapMT.H" 00044 #include "Component/ModelManager.H" 00045 #include "Devices/DeviceOpts.H" 00046 #include "Devices/FrameGrabberConfigurator.H" 00047 #include "GUI/XWinManaged.H" 00048 #include "Image/Convolver.H" 00049 #include "Image/CutPaste.H" // for inplacePaste() 00050 #include "Image/Image.H" 00051 #include "Image/Pixels.H" 00052 #include "Neuro/NeuroOpts.H" 00053 #include "Neuro/SaccadeControllers.H" 00054 #include "Neuro/WTAwinner.H" 00055 #include "Raster/Raster.H" 00056 #include "Transport/FrameIstream.H" 00057 #include "Util/Timer.H" 00058 00059 #include <arpa/inet.h> 00060 #include <fcntl.h> 00061 #include <netdb.h> 00062 #include <signal.h> 00063 #include <stdlib.h> 00064 #include <unistd.h> 00065 00066 #define MAXFLOAT 3.40282347e+38F 00067 #define sml 0 00068 00069 //! Number of frames over which average framerate is computed 00070 #define NAVG 20 00071 00072 //! Factor to display the sm values as greyscale: 00073 #define SMFAC 1.00F 00074 00075 #define WINSIZE 51 00076 static bool goforever = true; //!< Will turn false on interrupt signal 00077 00078 //! Signal handler (e.g., for control-C) 00079 void terminate(int s) 00080 { LERROR("*** INTERRUPT ***"); goforever = false; exit(1); } 00081 00082 ImageSet<float> bias(14); 00083 ImageSet<float> newBias(14); 00084 00085 00086 00087 // ###################################################################### 00088 int main(int argc, char **argv) 00089 { 00090 MYLOGVERB = LOG_INFO; 00091 00092 CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB4"); 00093 00094 // instantiate a model manager (for camera input): 00095 ModelManager manager("SaliencyMT Tester"); 00096 00097 // Instantiate our various ModelComponents: 00098 nub::ref<FrameGrabberConfigurator> 00099 gbc(new FrameGrabberConfigurator(manager)); 00100 manager.addSubComponent(gbc); 00101 00102 nub::ref<SaliencyMT> smt(new SaliencyMT(manager, orb, sml)); 00103 manager.addSubComponent(smt); 00104 00105 00106 // Set the appropriate defaults for our machine that is connected to 00107 // Stefan's robot head: 00108 manager.exportOptions(MC_RECURSE); 00109 manager.setOptionValString(&OPT_FrameGrabberType, "V4L"); 00110 manager.setOptionValString(&OPT_FrameGrabberMode, "YUV420P"); 00111 manager.setOptionValString(&OPT_FrameGrabberDevice, "/dev/video1"); 00112 manager.setOptionValString(&OPT_FrameGrabberChannel, "1"); 00113 manager.setOptionValString(&OPT_FrameGrabberHue, "0"); 00114 manager.setOptionValString(&OPT_FrameGrabberContrast, "16384"); 00115 // manager.setOptionValString(&OPT_FrameGrabberDims, "320x240"); 00116 manager.setOptionValString(&OPT_FrameGrabberDims, "160x120"); 00117 manager.setOptionValString(&OPT_SaccadeControllerEyeType, "Threshfric"); 00118 manager.setOptionValString(&OPT_SCeyeMaxIdleSecs, "1000.0"); 00119 manager.setOptionValString(&OPT_SCeyeThreshMinOvert, "4.0"); 00120 manager.setOptionValString(&OPT_SCeyeThreshMaxCovert, "3.0"); 00121 manager.setOptionValString(&OPT_SCeyeThreshMinNum, "2"); 00122 // manager.setOptionValString(&OPT_SCeyeSpringK, "1000000.0"); 00123 00124 //manager.setOptionValString(&OPT_SaccadeControllerType, "Trivial"); 00125 00126 // Parse command-line: 00127 if (manager.parseCommandLine((const int)argc, (const char**)argv, "", 0, 0) == false) return(1); 00128 00129 // do post-command-line configs: 00130 nub::soft_ref<FrameIstream> gb = gbc->getFrameGrabber(); 00131 if (gb.isInvalid()) 00132 LFATAL("You need to select a frame grabber type via the " 00133 "--fg-type=XX command-line option for this program " 00134 "to be useful"); 00135 const int w = gb->getWidth(), h = gb->getHeight(); 00136 00137 const int foa_size = std::min(w, h) / 12; 00138 manager.setModelParamVal("InputFrameDims", Dims(w, h), 00139 MC_RECURSE | MC_IGNORE_MISSING); 00140 manager.setModelParamVal("SCeyeStartAtIP", true, 00141 MC_RECURSE | MC_IGNORE_MISSING); 00142 manager.setModelParamVal("SCeyeInitialPosition",Point2D<int>(w/2,h/2), 00143 MC_RECURSE | MC_IGNORE_MISSING); 00144 manager.setModelParamVal("FOAradius", foa_size, 00145 MC_RECURSE | MC_IGNORE_MISSING); 00146 manager.setModelParamVal("FoveaRadius", foa_size, 00147 MC_RECURSE | MC_IGNORE_MISSING); 00148 00149 // catch signals and redirect them to terminate for clean exit: 00150 signal(SIGHUP, terminate); signal(SIGINT, terminate); 00151 signal(SIGQUIT, terminate); signal(SIGTERM, terminate); 00152 signal(SIGALRM, terminate); 00153 00154 // setup socket: 00155 int sock = socket(AF_INET, SOCK_DGRAM, 0); 00156 if (sock == -1) PLFATAL("Cannot create server socket"); 00157 00158 // get prepared to grab, communicate, display, etc: 00159 uint frame = 0U; // count the frames 00160 uint lastframesent = 0U; // last frame sent for processing 00161 00162 uint64 avgtime = 0; int avgn = 0; // for average framerate 00163 float fps = 0.0F; // to display framerate 00164 uint64 p_avgtime = 0; int p_avgn = 0; // for average framerate 00165 float p_fps = 0.0F; // to display framerate 00166 Timer tim; // for computation of framerate 00167 Timer p_tim; // for computation of framerate 00168 Timer masterclock; // master clock for simulations 00169 00170 Image<float> sm(w >> sml, h >> sml, ZEROS); // saliency map 00171 Point2D<int> fixation(-1, -1); // coordinates of eye fixation 00172 00173 // image buffer for display: 00174 Image<PixRGB<byte> > disp(w * 2, h + 20, ZEROS); 00175 disp += PixRGB<byte>(128); 00176 XWinManaged xwin(disp.getDims(), -1, -1, "RCBot"); 00177 XWinManaged xwin2(Dims(w,h), -1, -1, "RCBot"); 00178 XWinManaged xwin3(Dims(256,256), -1, -1, "RCBot"); 00179 00180 /// int ovlyoff = (w * 2) * ((dh - disp.getHeight()) / 2); 00181 ///int ovluvoff = ovlyoff / 4; 00182 00183 char info[1000]; // general text buffer for various info messages 00184 00185 Point2D<int> lastpointsent(w/2, h/2); 00186 00187 00188 // ###################################################################### 00189 try { 00190 // let's do it! 00191 manager.start(); 00192 00193 // get the frame grabber to start streaming: 00194 gb->startStream(); 00195 00196 // initialize the timers: 00197 tim.reset(); masterclock.reset(); 00198 p_tim.reset(); 00199 00200 Point2D<int> loc(84, 33); 00201 00202 while(goforever) 00203 { 00204 // grab image: 00205 //Image< PixRGB<byte> > ima = gb->readRGB(); 00206 char filename[255]; 00207 00208 sprintf(filename, "/usr/home/elazary/images/backyard/2/dframe%06d.ppm", frame+1); 00209 Image< PixRGB<byte> > ima = rescale(Raster::ReadRGB(filename), w, h); 00210 usleep(10000); 00211 00212 // display image: 00213 inplacePaste(disp, ima, Point2D<int>(0, 0)); 00214 Image<float> dispsm = rescale(sm, w,h) * SMFAC; 00215 inplaceNormalize(dispsm, 0.0F, 255.0F); 00216 00217 //inplacePaste(disp, Image<PixRGB<byte> > 00218 // (toRGB(quickInterpolate(dispsm, 1 << sml))), 00219 // Point2D<int>(w, 0)); 00220 00221 00222 inplacePaste(disp, Image<PixRGB<byte> >(toRGB(dispsm)), Point2D<int>(w, 0)); 00223 00224 00225 /*sc->evolve(masterclock.getSimTime(), (Retina*) 0); 00226 Point2D<int> eye = sc->getDecision(masterclock.getSimTime()); 00227 if (eye.i >= 0) fixation = eye; */ 00228 00229 Point2D<int> fix2(fixation); fix2.i += w; 00230 if (fixation.i >= 0) 00231 { 00232 drawDisk(disp, fixation, foa_size/6+2, PixRGB<byte>(20, 50, 255)); 00233 drawDisk(disp, fixation, foa_size/6, PixRGB<byte>(255, 255, 20)); 00234 drawDisk(disp, fix2, foa_size/6+2, PixRGB<byte>(20, 50, 255)); 00235 drawDisk(disp, fix2, foa_size/6, PixRGB<byte>(255, 255, 20)); 00236 } 00237 00238 00239 00240 xwin.drawImage(disp); 00241 00242 //get the location of the mouse click, find the highst local value, and set that as the bias 00243 // point 00244 //Point2D<int> loc = xwin.getLastMouseClick(); 00245 if (loc.isValid()){ 00246 LINFO("Loc: %i %i\n", loc.i, loc.j); 00247 00248 //descard the currently processed saliency map 00249 //build a new unbised saliency map, and find the highest local value within it 00250 while(!smt->outputReady()){ //wait for any processing to finish 00251 usleep(100); 00252 } 00253 00254 smt->setBiasSM(false); //let the system know we dont want a biased smap 00255 smt->setSaliencyMapLevel(0); //set the saliency map level to 0 00256 smt->newInput(ima); //set the image 00257 00258 while(!smt->outputReady()){ //wait for salieny map 00259 usleep(100); 00260 } 00261 00262 Image<float> tmpSM = smt->getOutput(); 00263 00264 00265 Image<float> smp; 00266 00267 for(int i=0; i<14; i++){ 00268 if (smt->cmaps[i].initialized()){ 00269 //inplaceNormalize(smt->cmaps[i], 0.0F, 255.0F); 00270 //xwin2.drawImage(smt->cmaps[i]); 00271 Point2D<int> center_loc(loc.i-((WINSIZE-1)/2), loc.j-((WINSIZE-1)/2)); 00272 00273 Image<float> target = crop(smt->cmaps[i],center_loc, Dims(WINSIZE,WINSIZE)); 00274 bias[i] = target; 00275 xwin3.drawImage(target); 00276 00277 LINFO("Convol"); 00278 for(int y=0; y<target.getHeight()/2; y++){ 00279 for(int x=0; x<target.getWidth()/2; x++){ 00280 float tmp = target.getVal(x,y); 00281 target.setVal(x,y,target.getVal(target.getWidth()-1-x,target.getHeight()-1-y)); 00282 target.setVal(target.getWidth()-1-x,target.getHeight()-1-y,tmp); 00283 00284 } 00285 } 00286 00287 /* 00288 for(int x=0; x<target.getHeight()/2; x++){ 00289 for(int y=0; y<target.getWidth()/2; y++){ 00290 float tmp = target.getVal(x,y); 00291 target.setVal(x,y,target.getVal(x,target.getHeight()-1-y)); 00292 target.setVal(x,target.getHeight()-1-y,tmp); 00293 } 00294 }*/ 00295 xwin2.drawImage(target); 00296 getchar(); 00297 00298 Convolver fc(target, smt->cmaps[i].getDims()); 00299 Image<float> conv1 = fc.fftConvolve(smt->cmaps[i]); 00300 float maxval; Point2D<int> currwin; findMin(conv1, currwin, maxval); 00301 LINFO("Min at %ix%i", currwin.i, currwin.j); 00302 xwin3.drawImage(conv1); 00303 getchar(); 00304 00305 } 00306 } 00307 00308 smt->setSMBias(bias); 00309 00310 smt->setBiasSM(true); //let the system know we want a biased smap 00311 00312 smt->newInput(ima); //set the image to be processed 00313 loc.i = -1; loc.j = -1; 00314 00315 } 00316 00317 00318 // are we ready to process a new frame? if so, send our new one: 00319 if (smt->outputReady()) 00320 { 00321 // let's get the previous results, if any: 00322 Image<float> out = smt->getOutput(); 00323 if (out.initialized()) 00324 sm = out; 00325 00326 // find most salient location and feed saccade controller: 00327 float maxval; Point2D<int> currwin; findMin(sm, currwin, maxval); 00328 //since the saliency map is smaller by the winsize, remap the winner point 00329 currwin.i = currwin.i + (WINSIZE-1)/2; 00330 currwin.j = currwin.j + (WINSIZE-1)/2; 00331 00332 if (currwin.isValid()) fixation = currwin; 00333 00334 LINFO("Winner:%ix%i", fixation.i, fixation.j); 00335 // getchar(); 00336 00337 double dist = 0; 00338 for(int i=0; i<14; i++){ 00339 if (smt->cmaps[i].initialized()){ 00340 if (bias[i].initialized() && newBias[i].initialized()){ 00341 Point2D<int> center_fixation(fixation.i-((WINSIZE-1)/2), 00342 fixation.j-((WINSIZE-1)/2)); 00343 Image<float> target = crop(smt->cmaps[i], 00344 center_fixation, 00345 Dims(WINSIZE,WINSIZE)); 00346 newBias[i] = target; 00347 dist += distance(bias[i], newBias[i]); 00348 bias[i] = newBias[i]; 00349 } 00350 } 00351 } 00352 LINFO("Distance: %f", dist); 00353 if (dist < 2000) 00354 smt->setSMBias(newBias); 00355 //drawDisk(ima, newwin.p, 10, PixRGB<byte>(255, 0, 0)); 00356 00357 // feed our current image as next one to process: 00358 //smt->newInput(decXY(ima)); 00359 smt->newInput(ima); 00360 lastframesent = frame; 00361 //LINFO("Processing frame %u", frame); 00362 00363 // compute and show framerate and stats for the frame we have processed 00364 //over the last NAVG frames: 00365 p_avgtime += p_tim.getReset(); p_avgn ++; 00366 if (p_avgn == NAVG) 00367 { 00368 p_fps = 1000.0F / float(p_avgtime) * float(p_avgn); 00369 p_avgtime = 0; p_avgn = 0; 00370 } 00371 00372 } 00373 00374 // compute and show framerate and stats over the last NAVG frames: 00375 avgtime += tim.getReset(); avgn ++; 00376 if (avgn == NAVG) 00377 { 00378 fps = 1000.0F / float(avgtime) * float(avgn); 00379 avgtime = 0; avgn = 0; 00380 } 00381 00382 // create an info string: 00383 sprintf(info, "%06u/%06u %.1ffps/%.5ffps ", 00384 frame, lastframesent, fps, p_fps); 00385 00386 writeText(disp, Point2D<int>(0, h), info, 00387 PixRGB<byte>(255), PixRGB<byte>(127)); 00388 00389 // ready for next frame: 00390 ++ frame; 00391 } 00392 00393 // get ready to terminate: 00394 manager.stop(); 00395 close(sock); 00396 00397 } catch ( ... ) { }; 00398 00399 return 0; 00400 } 00401 00402 #endif 00403 // ###################################################################### 00404 /* So things look consistent in everyone's emacs... */ 00405 /* Local Variables: */ 00406 /* indent-tabs-mode: nil */ 00407 /* End: */