00001 /*!@file Transport/BarStimuli.C A FrameIstream subclass for 00002 generating bar stimuli */ 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: Christian Siagian <siagian at usc dot edu> 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Transport/BarStimuli.C $ 00036 // $Id: $ 00037 // 00038 00039 #ifndef TRANSPORT_BARSTIMULI_C_DEFINED 00040 #define TRANSPORT_BARSTIMULI_C_DEFINED 00041 00042 #include "Transport/BarStimuli.H" 00043 00044 #include "Image/Image.H" 00045 #include "Image/Pixels.H" 00046 #include "Image/MathOps.H" 00047 #include "Image/ColorOps.H" 00048 #include "Image/DrawOps.H" 00049 #include "Raster/GenericFrame.H" 00050 00051 // ###################################################################### 00052 BarStimuli::BarStimuli(OptionManager& mgr) 00053 : 00054 FrameIstream(mgr, "Random Input", "BarStimuli"), 00055 itsDims(320,240), // if you change this default value, also update 00056 // the documentation of OPT_InputFrameSource in 00057 // Media/MediaOpts.C 00058 itsGenerator(0) 00059 { 00060 itsStep = 0; 00061 itsHaveMotion = true; 00062 00063 itsIsNormal = false; 00064 itsIsApertureProblem = false; 00065 } 00066 00067 // ###################################################################### 00068 BarStimuli::~BarStimuli() 00069 {} 00070 00071 // ###################################################################### 00072 void BarStimuli::setConfigInfo(const std::string& options) 00073 { 00074 // NOTE: if you modify any behavior here, then please update the 00075 // corresponding documentation for the global "--in" option inside 00076 // the OPT_InputFrameSource definition in Media/MediaOpts.C 00077 00078 LINFO("options: %s", options.c_str()); 00079 if (options.size() == 0) return; 00080 00081 // parse the options 00082 00083 // compounds are separated by commas ',' 00084 std::string rops = options; 00085 std::string::size_type fcpos = rops.find_first_of(','); 00086 00087 // check for resizing first option 00088 // (has to be in first position) 00089 // --in=dots:WxH, 00090 std::string op1 = rops.substr(0, fcpos); 00091 std::string::size_type fxpos = rops.find_first_of('x'); 00092 if(fcpos != std::string::npos && fxpos != std::string::npos 00093 && fxpos < fcpos) 00094 { 00095 Dims d; convertFromString(op1, d); 00096 this->setDims(d); 00097 00098 std::string temp = rops.substr(fcpos+1); rops = temp; 00099 } 00100 LINFO("Using default dimensions"); 00101 00102 // subsequent commands 00103 // NOTE: for now the config will be the last 00104 while(rops.size() != 0) 00105 { 00106 std::string op = rops.substr(0, fcpos); 00107 if(fcpos != std::string::npos) 00108 { 00109 std::string temp = rops.substr(fcpos+1); rops = temp; 00110 } 00111 else rops = std::string(""); 00112 00113 LINFO("op:%s rest:%s", op.c_str(), rops.c_str()); 00114 fcpos = rops.find_first_of(','); 00115 00116 // paramaters for this option is between "[ ]" 00117 std::string::size_type fbpos = op.find_first_of('['); 00118 std::string::size_type bbpos = op.find_first_of(']'); 00119 std::string params; 00120 if(fbpos != std::string::npos) 00121 { 00122 params = op.substr(fbpos+1,bbpos - fbpos - 1); 00123 LINFO("params: %s", params.c_str()); 00124 00125 std::string temp = op.substr(0,fbpos); op = temp; 00126 00127 } 00128 00129 // configure for that option 00130 if(!op.compare("Normal")) setConfigNormal(params); 00131 else 00132 if(!op.compare("ApertureProblem")) setConfigApertureProblem(params); 00133 else LFATAL("unknown BarStimuli option: %s", op.c_str()); 00134 } 00135 } 00136 00137 // ###################################################################### 00138 void BarStimuli::setDims(const Dims& s) 00139 { 00140 itsDims = s; 00141 } 00142 00143 // ###################################################################### 00144 void BarStimuli::setConfigNormal(const std::string& params) 00145 { 00146 itsIsNormal = true; 00147 00148 LINFO("Normal (perpendicular) Bar Motion"); 00149 } 00150 00151 // ###################################################################### 00152 void BarStimuli::setConfigApertureProblem(const std::string& params) 00153 { 00154 itsIsApertureProblem = true; 00155 00156 LINFO("Aperture Problem"); 00157 } 00158 00159 // ###################################################################### 00160 GenericFrameSpec BarStimuli::peekFrameSpec() 00161 { 00162 GenericFrameSpec result; 00163 00164 result.nativeType = GenericFrame::RGB_U8; 00165 result.videoFormat = VIDFMT_AUTO; 00166 result.videoByteSwap = false; 00167 result.dims = itsDims; 00168 result.floatFlags = 0; 00169 00170 return result; 00171 } 00172 00173 // ###################################################################### 00174 GenericFrame BarStimuli::readFrame() 00175 { 00176 Image<float> result; 00177 00178 // add dots 00179 if(itsIsNormal) 00180 { 00181 result = getNormalBarStimuli(itsStep); 00182 } 00183 else if(itsIsApertureProblem) 00184 { 00185 result = getApertureProblemStimuli(itsStep); 00186 } 00187 itsStep++; 00188 00189 inplaceNormalize(result, 0.0F, 255.0F); 00190 Image<PixRGB<byte> > temp = makeRGB(result,result,result); 00191 return GenericFrame(temp); 00192 00193 } 00194 00195 // ###################################################################### 00196 Image<float> BarStimuli::getNormalBarStimuli(uint step) 00197 { 00198 Image<float> temp(itsDims, ZEROS); 00199 uint width = itsDims.w(); 00200 uint height = itsDims.h(); 00201 00202 // initially create dots 00203 if(step == 0) 00204 { 00205 itsBars.resize(4); itsBarLengths.resize(4); 00206 00207 // top left 00208 itsBars[0] = Point2D<float> (width/2, height/4); 00209 itsBarLengths[0] = 1.0; 00210 itsBars[1] = Point2D<float> (width/4, height/2); 00211 itsBarLengths[1] = 1.0; 00212 itsBars[2] = Point2D<float> (width/8, height/4); 00213 itsBarLengths[2] = 1.0; 00214 itsBars[3] = Point2D<float> (width/4, height/8); 00215 itsBarLengths[3] = 1.0; 00216 00217 // bottom right 00218 // itsBars[0] = Point2D<float> (7*width/8, 3*height/4); 00219 // itsBarLengths[0] = 1.0; 00220 // itsBars[1] = Point2D<float> (3*width/4, 7*height/8); 00221 // itsBarLengths[1] = 1.0; 00222 // itsBars[2] = Point2D<float> (width/2, 3*height/4); 00223 // itsBarLengths[2] = 1.0; 00224 // itsBars[3] = Point2D<float> (3*width/4, height/2); 00225 // itsBarLengths[3] = 1.0; 00226 00227 } 00228 00229 // move the dots if needed 00230 if(itsHaveMotion) 00231 { 00232 //for(uint i = 0; i < dotNum; i++) 00233 itsBars[0] = Point2D<float>(itsBars[0].i + 2.0, itsBars[0].j); 00234 itsBars[1] = Point2D<float>(itsBars[1].i, itsBars[1].j + 1.0); 00235 itsBars[2] = Point2D<float>(itsBars[2].i - 1.0, itsBars[2].j); 00236 itsBars[3] = Point2D<float>(itsBars[3].i, itsBars[3].j - 1.0); 00237 00238 //LINFO("loc: %f %f: size: %f", itsBars[i].i, itsBars[i].j, itsBarLengths[i]); 00239 } 00240 // finally draw the itsBars 00241 //for(uint i = 0; i < dotNum; i++) 00242 //drawDisk(temp,Point2D<int>(itsBars[i].i, itsBars[i].j),itsBarLengths[i],byte(255)); 00243 00244 //drawDisk(temp,Point2D<int>(itsBars[0].i, itsBars[0].j), 1.0,byte(255)); 00245 //drawDisk(temp,Point2D<int>(itsBars[1].i, itsBars[1].j), 1.0,byte(255)); 00246 //drawDisk(temp,Point2D<int>(itsBars[2].i, itsBars[2].j), 1.0,byte(255)); 00247 //drawDisk(temp,Point2D<int>(itsBars[3].i, itsBars[3].j), 1.0,byte(255)); 00248 00249 drawLine 00250 (temp, 00251 Point2D<int>(itsBars[0].i, itsBars[0].j-15), 00252 Point2D<int>(itsBars[0].i, itsBars[0].j+15), 1.0F, 1); 00253 00254 // control the thickness of the line 00255 // drawLine 00256 // (temp, 00257 // Point2D<int>(itsBars[0].i, itsBars[0].j-15), 00258 // Point2D<int>(itsBars[0].i, itsBars[0].j+15), byte(255), 1); 00259 // drawLine 00260 // (temp, 00261 // Point2D<int>(itsBars[0].i+1, itsBars[0].j-15), 00262 // Point2D<int>(itsBars[0].i+1, itsBars[0].j+15), byte(255), 1); 00263 // drawLine 00264 // (temp, 00265 // Point2D<int>(itsBars[0].i-1, itsBars[0].j-15), 00266 // Point2D<int>(itsBars[0].i-1, itsBars[0].j+15), byte(255), 1); 00267 // drawLine 00268 // (temp, 00269 // Point2D<int>(itsBars[0].i-2, itsBars[0].j-15), 00270 // Point2D<int>(itsBars[0].i-2, itsBars[0].j+15), byte(255), 1); 00271 // drawLine 00272 // (temp, 00273 // Point2D<int>(itsBars[0].i-3, itsBars[0].j-15), 00274 // Point2D<int>(itsBars[0].i-3, itsBars[0].j+15), byte(255), 1); 00275 // drawLine 00276 // (temp, 00277 // Point2D<int>(itsBars[0].i+2, itsBars[0].j-15), 00278 // Point2D<int>(itsBars[0].i+2, itsBars[0].j+15), byte(255), 1); 00279 // drawLine 00280 // (temp, 00281 // Point2D<int>(itsBars[0].i-4, itsBars[0].j-15), 00282 // Point2D<int>(itsBars[0].i-4, itsBars[0].j+15), byte(255), 1); 00283 // drawLine 00284 // (temp, 00285 // Point2D<int>(itsBars[0].i+3, itsBars[0].j-15), 00286 // Point2D<int>(itsBars[0].i+3, itsBars[0].j+15), byte(255), 1); 00287 00288 //=============================================== 00289 // drawLine 00290 // (temp, 00291 // Point2D<int>(itsBars[1].i-15, itsBars[1].j), 00292 // Point2D<int>(itsBars[1].i+15, itsBars[1].j), byte(255), 1); 00293 00294 // drawLine 00295 // (temp, 00296 // Point2D<int>(itsBars[2].i, itsBars[2].j-15), 00297 // Point2D<int>(itsBars[2].i, itsBars[2].j+15), byte(255), 1); 00298 00299 // drawLine 00300 // (temp, 00301 // Point2D<int>(itsBars[3].i-15, itsBars[3].j), 00302 // Point2D<int>(itsBars[3].i+15, itsBars[3].j), byte(255), 1); 00303 00304 00305 //drawDisk(temp,Point2D<int>(itsBars[i].i, itsBars[i].j),itsBarLengths[i],byte(255)); 00306 //temp.setVal(itsBars[i].i, itsBars[i].j, byte(128)); 00307 00308 return temp; 00309 } 00310 00311 // ###################################################################### 00312 Image<float> BarStimuli::getApertureProblemStimuli(uint step) 00313 { 00314 Image<float> temp(itsDims, ZEROS); 00315 uint width = itsDims.w(); 00316 uint height = itsDims.h(); 00317 00318 // create dot initially 00319 if(step == 0) 00320 { 00321 itsBars.resize(1); 00322 // top left 00323 itsBars[0] = Point2D<float> (width/2, height/4); 00324 } 00325 00326 uint len = 15; 00327 itsBars[0] = Point2D<float>(itsBars[0].i + 2.0, itsBars[0].j); 00328 drawLine 00329 (temp, 00330 Point2D<int>(itsBars[0].i-len, itsBars[0].j-len), 00331 Point2D<int>(itsBars[0].i+len, itsBars[0].j+len), 1.0F, 1); 00332 00333 return temp; 00334 } 00335 00336 // ###################################################################### 00337 /* So things look consistent in everyone's emacs... */ 00338 /* Local Variables: */ 00339 /* indent-tabs-mode: nil */ 00340 /* End: */ 00341 00342 #endif // TRANSPORT_BARSTIMULI_C_DEFINED