DotStimuli.C

00001 /*!@file Transport/RandomInput.C A FrameIstream subclass for
00002   generating random images */
00003 
00004 // //////////////////////////////////////////////////////////////////// //
00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00006 // by the 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: Rob Peters <rjpeters at usc dot edu>
00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Transport/RandomInput.C $
00036 // $Id: RandomInput.C 8602 2007-07-20 23:10:44Z rjpeters $
00037 //
00038 
00039 #ifndef TRANSPORT_DOTSTIMULI_C_DEFINED
00040 #define TRANSPORT_DOTSTIMULI_C_DEFINED
00041 
00042 #define DOT_NUM          500           // 200  1000 --> Shuo: 640x480: 2000 dots
00043 
00044 #define FOE_X            2*WIDTH/4     // W/4 
00045 #define FOE_Y            3*HEIGHT/4    // 2H/4 +4 
00046 
00047 #define DOT_VEL          2.0/80.0      // Shuo: .035
00048 
00049 // Shuo: in PsychToolbox: size refers to diameter, in our code radius
00050 // Shuo: Abs max: 21, ave DS is 9.767 across all dots in each frames
00051 #define DOT_ORG_DSIZE    .02    // .04
00052 #define DOT_DSIZE        .07    // .035
00053 #define MIN_DOT_SIZE     1   
00054 #define MAX_DOT_SIZE     5   
00055 #define ABS_MAX_DSIZE    50
00056 #define NFRAME           60
00057 
00058 #define HAVE_MOTION      1
00059 #define HAVE_TEMP_SGRAD  1
00060 #define HAVE_SPAT_SGRAD  1
00061 
00062 #define NUM_PYR_LEVEL    3 // 3 for 640x480
00063 #define NUM_DIRS         8
00064 #define NUM_SPEEDS       3
00065 
00066 #define SIDE_LENGTH      20  
00067 
00068 #include "Transport/DotStimuli.H"
00069 
00070 #include "Image/Image.H"
00071 #include "Image/ColorOps.H"
00072 #include "Image/MathOps.H"
00073 #include "Raster/Raster.H"
00074 #include "Image/Pixels.H"
00075 #include "Raster/GenericFrame.H"
00076 #include "Image/DrawOps.H"
00077 
00078 // ######################################################################
00079 DotStimuli::DotStimuli(OptionManager& mgr)
00080   :
00081   FrameIstream(mgr, "Random Input", "RandomInput"),
00082   itsDims(320,240), // if you change this default value, also update
00083                     // the documentation of OPT_InputFrameSource in
00084                     // Media/MediaOpts.C
00085 
00086   itsGenerator(0),
00087   itsIsFoe(false),
00088   itsFoe(Point2D<int>(-1,-1))
00089 {
00090   itsStep = 0;
00091   itsAsymmetryMode = 0;
00092 }
00093 
00094 // ######################################################################
00095 DotStimuli::~DotStimuli()
00096 {}
00097 
00098 // ######################################################################
00099 void DotStimuli::setConfigInfo(const std::string& options)
00100 {
00101   // NOTE: if you modify any behavior here, then please update the
00102   // corresponding documentation for the global "--in" option inside
00103   // the OPT_InputFrameSource definition in Media/MediaOpts.C
00104 
00105   LINFO("options: %s", options.c_str());
00106   if (options.size() == 0) return;
00107 
00108   // parse the options
00109 
00110   // compounds are separated by commas ','  
00111   std::string rops = options;
00112   std::string::size_type fcpos = rops.find_first_of(',');
00113 
00114   // check for resizing first option 
00115   // (has to be in first position)
00116   // --in=dots:WxH,
00117   std::string op1   = rops.substr(0, fcpos);
00118   LDEBUG("op1: %s", op1.c_str());
00119 
00120   std::string::size_type fxpos = rops.find_first_of('x');
00121   if(fcpos != std::string::npos && 
00122      fxpos != std::string::npos && 
00123      fxpos <  fcpos)
00124     {
00125       Dims d; convertFromString(op1, d);
00126       this->setDims(d);
00127 
00128       std::string temp = rops.substr(fcpos+1); rops = temp;
00129 
00130       LDEBUG("new stimuli dimension: %dx%d", d.w(), d.h());
00131     }
00132 
00133   // subsequent commands 
00134   // NOTE: the shared config parameters will be set to
00135   //       what the last command specifies
00136   while(rops.size() != 0)
00137     {
00138       fcpos = rops.find_first_of(',');
00139       std::string op   = rops.substr(0, fcpos);
00140       if(fcpos != std::string::npos)
00141         {
00142           std::string temp = rops.substr(fcpos+1); rops = temp;
00143         }
00144       else rops = std::string("");
00145       LDEBUG("op:%s rest:%s", op.c_str(), rops.c_str());
00146 
00147       // for the next iteration
00148       fcpos = rops.find_first_of(',');
00149       
00150       // paramaters for this option is between "[ ]"
00151       std::string::size_type fbpos = op.find_first_of('[');
00152       std::string::size_type bbpos = op.find_first_of(']');
00153       std::string params; 
00154       if(fbpos != std::string::npos)
00155         {
00156           params = op.substr(fbpos+1,bbpos - fbpos - 1);
00157           LDEBUG("params: %s", params.c_str());
00158 
00159           std::string temp = op.substr(0,fbpos); op = temp;
00160         }
00161       
00162       // go through all the different motion
00163       if(!op.compare("Random"))     setConfigRandom(params);
00164       else 
00165         if(!op.compare("Single"))   setConfigSingle(params);
00166         else 
00167           if(!op.compare("Planar"))   setConfigPlanar(params);
00168           else 
00169             if(!op.compare("AsymmetryFast")) 
00170               //setConfigAsymmetry(params, 0);              
00171               setConfigAsymmetry(params, 2);
00172             else 
00173               if(!op.compare("AsymmetrySlow")) 
00174                 //setConfigAsymmetry(params, 1);
00175                 setConfigAsymmetry(params, 3);
00176               else 
00177                 if(!op.compare("Foe"))      setConfigFoe(params);
00178                 else 
00179                   if(!op.compare("Rotation")) setConfigRotation(params);
00180                   else LFATAL("unknown DotStimuli option: %s", op.c_str());
00181     }
00182 }
00183 
00184 // ######################################################################
00185 void DotStimuli::setDims(const Dims& s)
00186 {
00187   itsDims = s;
00188 }
00189 
00190 // ######################################################################
00191 void DotStimuli::setConfigRandom(const std::string& params)
00192 {
00193   itsIsRandom = true;
00194   LINFO("Random Motion");
00195 
00196   if(params.size() == 0) return;
00197 }
00198 
00199 // ######################################################################
00200 void DotStimuli::setConfigSingle(const std::string& params)
00201 {
00202   itsIsSingleDot = true;
00203 
00204   itsSingleDotDx = 2.0;
00205   itsSingleDotDy = 0.0;
00206 
00207   float orgDotSize = 2.0;
00208   itsSingleDotSize = orgDotSize;
00209 
00210   LINFO("Single Dot Motion");
00211 
00212   if(params.size() == 0) return;
00213 }
00214 
00215 // ######################################################################
00216 void DotStimuli::setConfigPlanar(const std::string& params)
00217 {              
00218   itsIsPlanar = true;
00219   itsPlanarDx = 2.0;
00220   itsPlanarDy = 0.0;
00221   LINFO("Planar Motion");
00222 
00223   if(params.size() == 0) return;
00224 }
00225 
00226 // ######################################################################
00227 void DotStimuli::setConfigAsymmetry(const std::string& params, uint mode)
00228 {              
00229   itsIsPlanar = true;
00230   itsIsSingleDot = true;
00231   itsPlanarDx = 2.0;
00232   itsPlanarDy = 0.0;
00233 
00234   float orgDotSize = 1.0;
00235   itsSingleDotSize = orgDotSize;
00236 
00237   itsAsymmetryMode = mode;
00238   if(mode == 0 || mode == 2)
00239     {
00240       itsSingleDotDx = 4.0;
00241       itsSingleDotDy = 0.0;
00242       LINFO("Asymmetry Motion Fast");
00243 
00244       //if(mode == 2) itsIsSingleDot = false;
00245     }
00246   else if(mode == 1 || mode == 3)
00247     {
00248       itsSingleDotDx = 1.0;
00249       itsSingleDotDy = 0.0;
00250       LINFO("Asymmetry Motion Slow");
00251 
00252       //if(mode == 3) itsIsSingleDot = false;
00253     }
00254   
00255 
00256   if(params.size() == 0) return;
00257 }
00258 
00259 // ######################################################################
00260 void DotStimuli::setConfigFoe(const std::string& params)
00261 {              
00262   itsIsFoe = true;
00263 
00264   itsFoe = Point2D<int>(160,120);
00265   LINFO("Focus of Expansion");
00266 
00267   if(params.size() == 0) 
00268     {
00269       itsFoeHaveMotion    = HAVE_MOTION;
00270       itsFoeHaveTempSGrad = HAVE_TEMP_SGRAD;
00271       itsFoeHaveSpatSGrad = HAVE_SPAT_SGRAD;      
00272       return;
00273     }
00274 
00275   // parse the parameters
00276   std::string rops = params;
00277   std::string::size_type fcmpos = rops.find_first_of('/');
00278   while(rops.size() != 0)
00279     {
00280       std::string op   = rops.substr(0, fcmpos);
00281       if(fcmpos != std::string::npos)
00282         {
00283           std::string temp = rops.substr(fcmpos+1); rops = temp;
00284         }
00285       else rops = std::string("");
00286 
00287       LINFO("op:%s rest:%s", op.c_str(), rops.c_str());
00288       
00289       // for the next iteration
00290       fcmpos = rops.find_first_of(',');
00291       
00292       // paramaters for this option is after colon :
00293       std::string::size_type fclpos = op.find_first_of(':');
00294       std::string params; 
00295       if(fclpos != std::string::npos)
00296         {
00297           params = op.substr(fclpos+1);
00298           LINFO("params: %s", params.c_str());
00299 
00300           std::string temp = op.substr(0,fclpos); op = temp;
00301         }
00302       
00303       // go through all the different motion
00304       if(!op.compare("Shuo"))
00305         {
00306           LINFO("Shuo Stimuli");
00307         }
00308       else if(!op.compare("flags"))
00309         {
00310           int flag = atoi(params.c_str());
00311           itsFoeHaveMotion    = (flag & 4);
00312           itsFoeHaveTempSGrad = (flag & 2);
00313           itsFoeHaveSpatSGrad = (flag & 1);
00314 
00315           LINFO("flag is: %d: (%d %d %d)", flag,  
00316                 itsFoeHaveMotion, 
00317                 itsFoeHaveTempSGrad, 
00318                 itsFoeHaveSpatSGrad);
00319         }
00320 
00321       else LFATAL("unknown Foe param: %s", op.c_str());
00322     }  
00323 }
00324 
00325 // ######################################################################
00326 void DotStimuli::setConfigRotation(const std::string& params)
00327 {              
00328   itsIsRotation = true;
00329   LINFO("Rotation Motion");
00330 
00331   if(params.size() == 0) return;
00332 }
00333 
00334 // ######################################################################
00335 GenericFrameSpec DotStimuli::peekFrameSpec()
00336 {
00337   GenericFrameSpec result;
00338 
00339   result.nativeType = GenericFrame::RGB_U8;
00340   result.videoFormat = VIDFMT_AUTO;
00341   result.videoByteSwap = false;
00342   result.dims = itsDims;
00343   result.floatFlags = 0;
00344 
00345   return result;
00346 }
00347 
00348 // ######################################################################
00349 GenericFrame DotStimuli::readFrame()
00350 {
00351   Image<float> result(itsDims, ZEROS);
00352 
00353   // add dots
00354   if(itsIsRandom)
00355     {
00356       result += getRandomDotStimuli(itsStep);
00357     }
00358   if(itsIsSingleDot)
00359     {
00360       result += getSingleDotStimuli(itsStep);
00361     }
00362   if(itsIsPlanar)
00363     {
00364       result += getPlanarDotStimuli(itsStep); 
00365     }
00366   if(itsIsFoe)
00367     {
00368       result += getFoeStimuli(itsStep);
00369     }
00370   if(itsIsRotation)
00371     {
00372       result += getRotationDotStimuli(itsStep); 
00373     }
00374 
00375   itsStep++;
00376  
00377   inplaceNormalize(result, 0.0F, 255.0F);  
00378   Image<PixRGB<byte> > temp = makeRGB(result,result,result);
00379   return GenericFrame(temp);
00380 }
00381 
00382 // ######################################################################
00383 Image<float> DotStimuli::getRandomDotStimuli(uint step)
00384 {
00385   Image<byte> temp(itsDims, ZEROS);
00386   //uint width  = itsDims.w();
00387   //uint height = itsDims.h();
00388 
00389   return temp;
00390 }
00391 
00392 // ######################################################################
00393 Image<float> DotStimuli::getSingleDotStimuli(uint step)
00394 {
00395   //LINFO("SINGLE DOT\n\n\n");
00396 
00397   Image<float> temp(itsDims, ZEROS);
00398   uint width  = itsDims.w();
00399   uint height = itsDims.h();
00400 
00401   uint sideLength = SIDE_LENGTH;
00402   float nHorz = width/sideLength;
00403   float nVert = height/sideLength;
00404 
00405   if(step == 0)
00406     {
00407       if(itsAsymmetryMode > 1)
00408         {
00409           uint i = uint((nHorz*rand())/(RAND_MAX + 1.0));
00410           uint j = uint((nVert*rand())/(RAND_MAX + 1.0));
00411           itsSingleDotLocation = Point2D<float>
00412             (sideLength/2 + i * sideLength,
00413              sideLength/2 + j * sideLength ); 
00414         }
00415       else
00416         itsSingleDotLocation = Point2D<float>
00417           (width  * .1,// * double(rand())/(RAND_MAX + 1.0),
00418            height * double(rand())/(RAND_MAX + 1.0));        
00419     }
00420 
00421   // planar motion
00422   if(itsSingleDotDx != 0.0 || itsSingleDotDy != 0.0)
00423     itsSingleDotLocation = 
00424       Point2D<float>(fmod(itsSingleDotLocation.i + itsSingleDotDx, width), 
00425                      fmod(itsSingleDotLocation.j + itsSingleDotDy, height));
00426 
00427   drawDisk(temp,
00428            Point2D<int>(itsSingleDotLocation.i, 
00429                         itsSingleDotLocation.j),
00430            itsSingleDotSize, 1.0F);
00431   //LINFO("(%f %f)", itsSingleDotLocation.i, itsSingleDotLocation.j);
00432 
00433   return temp;
00434 }
00435 
00436 // ######################################################################
00437 Image<float> DotStimuli::getPlanarDotStimuli(uint step)
00438 {
00439   //LINFO("PLANAR DOT\n\n\n");
00440 
00441   if(itsAsymmetryMode > 1)
00442     return getGridPlanarDotStimuli(step);
00443   else
00444     return getRandomPlanarDotStimuli(step);
00445 }
00446 
00447 // ######################################################################
00448 Image<float> DotStimuli::getGridPlanarDotStimuli(uint step)
00449 {
00450   Image<float> temp(itsDims, ZEROS);
00451   uint width  = itsDims.w();
00452   uint height = itsDims.h();
00453 
00454   //if(step > NFRAME) return Image<byte>();
00455 
00456   uint sideLength = SIDE_LENGTH;
00457   float orgDotSize = 1.0;
00458 
00459   // create random dot initially
00460   if(step == 0)
00461     {
00462       uint nHorz = width/sideLength;
00463       uint nVert = height/sideLength;  
00464       itsPlanarDots.clear(); itsPlanarDotSizes.clear();
00465 
00466       for(uint i = 0; i < nHorz; i++)
00467         {
00468           for(uint j = 0; j < nVert; j++)
00469             {
00470               Point2D<float> currPt
00471                 (sideLength/2 + i*sideLength,
00472                  sideLength/2 + j*sideLength );
00473               if(currPt.i != itsSingleDotLocation.i - itsSingleDotDx ||
00474                  currPt.j != itsSingleDotLocation.j - itsSingleDotDy   )
00475                 {
00476                   itsPlanarDots.push_back(currPt);                    
00477                   itsPlanarDotSizes.push_back(orgDotSize); 
00478                 }
00479             }
00480         }
00481     }
00482   uint nDots = itsPlanarDots.size();
00483   
00484   // planar motion
00485   if(itsPlanarDx != 0.0 || itsPlanarDy != 0.0)
00486     for(uint i = 0; i < nDots; i++)
00487       {
00488         itsPlanarDots[i] = 
00489           Point2D<float>(fmod(itsPlanarDots[i].i + itsPlanarDx, width), 
00490                          fmod(itsPlanarDots[i].j + itsPlanarDy, height));
00491       }
00492 
00493   // finally draw the dots
00494   for(uint i = 0; i < nDots; i++)
00495     {
00496       LDEBUG("[%d] loc: %10.3f %10.3f: size: %7.3f", 
00497              i, itsPlanarDots[i].i, itsPlanarDots[i].j, itsPlanarDotSizes[i]);
00498       drawDisk(temp,Point2D<int>(itsPlanarDots[i].i, itsPlanarDots[i].j),
00499                itsPlanarDotSizes[i], 1.0F);
00500       //temp.setVal(itsPlanarDots[i].i, itsPlanarDots[i].j, byte(128));
00501       //LINFO("pt: %8.3f %8.3f", itsPlanarDots[i].i, itsPlanarDots[i].j);
00502     }
00503 
00504   return temp;
00505 }
00506 
00507 
00508 // ######################################################################
00509 Image<float> DotStimuli::getRandomPlanarDotStimuli(uint step)
00510 {
00511   Image<float> temp(itsDims, ZEROS);
00512   uint width  = itsDims.w();
00513   uint height = itsDims.h();
00514 
00515   //if(step > NFRAME) return Image<byte>();
00516 
00517   uint dotNum = DOT_NUM;
00518 
00519   float orgDotSize = 1.0;
00520 
00521   // create random dot initially
00522   if(step == 0)
00523     {
00524       itsPlanarDots.resize(dotNum); itsPlanarDotSizes.resize(dotNum);
00525       for(uint i = 0; i < dotNum; i++)
00526         {
00527           itsPlanarDots[i] = Point2D<float>
00528             (width  * double(rand())/(RAND_MAX + 1.0),
00529              height * double(rand())/(RAND_MAX + 1.0));
00530           itsPlanarDotSizes[i] = orgDotSize; 
00531         }
00532     }
00533   
00534   // check for out-of-bounds dot needed to be shown
00535   for(uint i = 0; i < dotNum; i++)
00536     {
00537       // NOTE: can also kill dots randomly before going out of the image
00538       if(!temp.getBounds().contains(Point2D<int>(itsPlanarDots[i].i, 
00539                                                  itsPlanarDots[i].j))) 
00540         {
00541           float srx = 0.0;   float sry = 0.0;
00542           float rx  = width; float ry  = height;
00543           if(itsPlanarDx < 0.0)     { srx = 7.0*width/8.0; rx  = width/8; }
00544           else if(itsPlanarDx > 0.0){ srx = 0.0;           rx  = width/8; }
00545           
00546           if(itsPlanarDy < 0.0)     { sry = 7.0*height/8.0; ry  = height/8; }
00547           else if(itsPlanarDy > 0.0){ sry = 0.0;            ry  = height/8; }
00548 
00549           float sx = rx * double(rand())/(RAND_MAX + 1.0) + srx; 
00550           float sy = ry * double(rand())/(RAND_MAX + 1.0) + sry;
00551           
00552           itsPlanarDots[i] = Point2D<float>(sx,sy);
00553           itsPlanarDotSizes[i] = orgDotSize; 
00554           LDEBUG("new dots[%3d]: %7.3f %7.3f", i, sx, sy);
00555         }
00556       else
00557         {
00558           Point2D<int> pt(itsPlanarDots[i].i, itsPlanarDots[i].j);
00559           LDEBUG("[%3d] it's ok: (%7.3f %7.3f) -> %3d %3d", 
00560                  i, itsPlanarDots[i].i, itsPlanarDots[i].j, pt.i, pt.j);
00561         }
00562     }
00563 
00564   // planar motion
00565   if(itsPlanarDx != 0.0 || itsPlanarDy != 0.0)
00566     for(uint i = 0; i < dotNum; i++)
00567       {
00568         itsPlanarDots[i] = Point2D<float>(itsPlanarDots[i].i + itsPlanarDx, 
00569                                           itsPlanarDots[i].j + itsPlanarDy);
00570       }
00571 
00572   // finally draw the dots
00573   for(uint i = 0; i < dotNum; i++)
00574     {
00575       LDEBUG("[%d] loc: %10.3f %10.3f: size: %7.3f", 
00576              i, itsPlanarDots[i].i, itsPlanarDots[i].j, itsPlanarDotSizes[i]);
00577       drawDisk(temp,Point2D<int>(itsPlanarDots[i].i, itsPlanarDots[i].j),
00578                itsPlanarDotSizes[i], 1.0F);
00579       //temp.setVal(itsPlanarDots[i].i, itsPlanarDots[i].j, byte(128));
00580     }
00581 
00582   return temp;
00583 }
00584 
00585 // ######################################################################
00586 Image<float> DotStimuli::getFoeStimuli(uint step)
00587 {
00588   float dx = 0.0; float dy = 0.0;
00589   //float dx = pshift.i; float dy = pshift.j;
00590   
00591   float dotOrgDSize = DOT_ORG_DSIZE; 
00592   
00593   // planar (Yaw-Pitch) motion correction
00594   uint dir =  0.0; float speed = 0.0;
00595   
00596   LINFO("[%3d] haveMotion: %d haveTempSGrad: %d haveSpatSGrad: %d "
00597         "dx dy: %7.3f %7.3f dotOrgDSize: %f comp: %d %f",
00598         itsStep, 
00599         itsFoeHaveMotion, itsFoeHaveTempSGrad, itsFoeHaveSpatSGrad, 
00600         dx, dy, dotOrgDSize, dir, speed);
00601 
00602   //if(step > NFRAME) return Image<byte>();
00603 
00604   Image<byte> temp(itsDims, ZEROS);
00605   uint width  = itsDims.w();
00606   uint height = itsDims.h();
00607 
00608   float orgDotSize = 1.0;
00609 
00610   // create random dot initially
00611   if(step == 0)
00612     {
00613       itsFoeDots.resize(DOT_NUM); itsFoeDotSizes.resize(DOT_NUM);
00614       for(uint i = 0; i < DOT_NUM; i++)
00615         {
00616           itsFoeDots[i] = Point2D<float>
00617             (width  * double(rand())/(RAND_MAX + 1.0),
00618              height * double(rand())/(RAND_MAX + 1.0));
00619 
00620           // just do it in order to get identical average size
00621           //float range = MAX_DOT_SIZE - MIN_DOT_SIZE;
00622           //dotSizes[i] = i*range/(DOT_NUM-1.0)+ double(MIN_DOT_SIZE); 
00623           itsFoeDotSizes[i] = orgDotSize; 
00624         }
00625     }
00626 
00627   // check for out-of-bounds dot needed to be shown
00628   for(uint i = 0; i < DOT_NUM; i++)
00629     {
00630       // NOTE: can also kill dots randomly before going out of the image
00631       // NOTE: how about adding new dots in the FOE quadrants
00632       if(!temp.getBounds().
00633          contains(Point2D<int>(itsFoeDots[i].i, itsFoeDots[i].j))) 
00634         {
00635           itsFoeDots[i] = Point2D<float>
00636             (width  * double(rand())/(RAND_MAX + 1.0),
00637              height * double(rand())/(RAND_MAX + 1.0) );
00638 
00639           // keep the sizes or 1.0?
00640           itsFoeDotSizes[i] = orgDotSize; 
00641         }
00642     }
00643 
00644   // modify sizes according to rules
00645   for(uint i = 0; i < DOT_NUM; i++)
00646     {
00647       if(itsFoeHaveTempSGrad && itsFoeHaveSpatSGrad)
00648         {
00649           float dist = sqrt(pow((itsFoeDots[i].i - itsFoe.i), 2.0) + 
00650                             pow((itsFoeDots[i].j - itsFoe.j), 2.0)  ); 
00651           if(itsFoeHaveMotion)
00652             {
00653               itsFoeDotSizes[i] = dotOrgDSize * dist;
00654             }
00655           // growing, FOE coherent, but not moving 
00656           else
00657             {
00658               if(step == 0)
00659                 {
00660                   itsFoeDotSizes[i] = dotOrgDSize * dist;
00661                 }
00662               else
00663                 {
00664                   // increase until ABS_MAX_DSIZE, then stop
00665                   if(itsFoeDotSizes[i] < ABS_MAX_DSIZE)
00666                     {
00667                       itsFoeDotSizes[i] = (1.0 + DOT_DSIZE) *
00668                         dotOrgDSize * dist;
00669                     }
00670                   // else dot size stays the same
00671                 }
00672             }
00673         }
00674       else if(itsFoeHaveTempSGrad && !itsFoeHaveSpatSGrad)
00675         {
00676           // all dot have same size just increase 
00677           float ds = MAX_DOT_SIZE - MIN_DOT_SIZE;
00678           itsFoeDotSizes[i] = step*ds/(NFRAME - 1.0)+ double(MIN_DOT_SIZE); 
00679         }
00680       else if(!itsFoeHaveTempSGrad && itsFoeHaveSpatSGrad)
00681         {
00682           float dist = sqrt(pow((itsFoeDots[i].i - itsFoe.i), 2.0) + 
00683                             pow((itsFoeDots[i].j - itsFoe.j), 2.0)  ); 
00684           itsFoeDotSizes[i] = dotOrgDSize * dist;
00685         }
00686       // else just keep size 
00687     }
00688 
00689   // move the dots if needed
00690   if(itsFoeHaveMotion)
00691     for(uint i = 0; i < DOT_NUM; i++)
00692       {
00693         itsFoeDots[i] = Point2D<float>
00694           (itsFoeDots[i].i + DOT_VEL * (itsFoeDots[i].i - itsFoe.i),
00695            itsFoeDots[i].j + DOT_VEL * (itsFoeDots[i].j - itsFoe.j));
00696       }
00697 
00698   // add lateral motion
00699   if(dx != 0.0 || dy != 0.0)
00700     for(uint i = 0; i < DOT_NUM; i++)
00701       {
00702         itsFoeDots[i] = Point2D<float>(itsFoeDots[i].i + dx, 
00703                                        itsFoeDots[i].j + dy);
00704       }
00705 
00706   // finally draw the dots
00707   for(uint i = 0; i < DOT_NUM; i++)
00708     {
00709       //LINFO("loc: %10.3f %10.3f: size: %7.3f", 
00710       //      dots[i].i, dots[i].j, dotSizes[i]);
00711       drawDisk(temp,Point2D<int>(itsFoeDots[i].i, 
00712                                  itsFoeDots[i].j),itsFoeDotSizes[i],
00713                byte(255));
00714       //temp.setVal(itsFoeDots[i].i, itsFoeDots[i].j, byte(128));
00715     }
00716 
00717   // draw the FOE
00718   //drawDisk(temp,itsFoe,2,byte(128));    
00719 
00720   return temp;
00721 }
00722 
00723 // ######################################################################
00724 Image<float> DotStimuli::getRotationDotStimuli(uint step)
00725 {
00726   Image<byte> temp(itsDims, ZEROS);
00727   //uint width  = itsDims.w();
00728   //uint height = itsDims.h();
00729 
00730   LINFO("Rotation Motion: FIXXX: NOT YET IMPLEMENTED");
00731 
00732   return temp;
00733 }
00734 
00735 // ######################################################################
00736 /* So things look consistent in everyone's emacs... */
00737 /* Local Variables: */
00738 /* indent-tabs-mode: nil */
00739 /* End: */
00740 
00741 #endif // TRANSPORT_RANDOMINPUT_C_DEFINED
Generated on Sun May 8 08:42:24 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3