00001 /*!@file Neuro/AttentionGuidanceMap.C Implementation for task-relevance map class */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Neuro/AttentionGuidanceMap.C $ 00035 // $Id: AttentionGuidanceMap.C 14677 2011-04-04 19:37:18Z dberg $ 00036 // 00037 00038 #include "Neuro/AttentionGuidanceMap.H" 00039 00040 #include "Channels/ChannelBase.H" 00041 #include "Component/OptionManager.H" 00042 #include "Image/Image.H" 00043 #include "Image/MathOps.H" 00044 #include "Image/ShapeOps.H" // for rescale() 00045 #include "Neuro/NeuroOpts.H" 00046 #include "Neuro/NeuroSimEvents.H" 00047 #include "Simulation/SimEventQueue.H" 00048 #include "Simulation/SimulationOpts.H" 00049 #include "Transport/FrameInfo.H" 00050 #include "Transport/FrameOstream.H" 00051 #include "Util/log.H" 00052 00053 #ifdef INVT_USE_CPPOX//we need c++ 0X features for this to work 00054 #include "ModelNeuron/StructurePlot.H" 00055 #include "ModelNeuron/SimStructureOpts.H" 00056 #endif 00057 00058 // ###################################################################### 00059 // ###################################################################### 00060 // ########## AttentionGuidanceMap implementation 00061 // ###################################################################### 00062 // ###################################################################### 00063 00064 AttentionGuidanceMap:: 00065 AttentionGuidanceMap(OptionManager& mgr, 00066 const std::string& descrName, 00067 const std::string& tagName) : 00068 SimModule(mgr, descrName, tagName), 00069 SIMCALLBACK_INIT(SimEventSaliencyMapOutput), 00070 SIMCALLBACK_INIT(SimEventTaskRelevanceMapOutput), 00071 SIMCALLBACK_INIT(SimEventClockTick), 00072 SIMCALLBACK_INIT(SimEventSaveOutput), 00073 itsSaveResults(&OPT_AGMsaveResults, this), // see Neuro/NeuroOpts.{H,C} 00074 itsOutputCache() 00075 { } 00076 00077 // ###################################################################### 00078 AttentionGuidanceMap::~AttentionGuidanceMap() 00079 { } 00080 00081 // ###################################################################### 00082 void AttentionGuidanceMap:: 00083 onSimEventSaveOutput(SimEventQueue& q, rutz::shared_ptr<SimEventSaveOutput>& e) 00084 { 00085 this->save1(e->sinfo()); 00086 } 00087 00088 // ###################################################################### 00089 void AttentionGuidanceMap::save1(const ModelComponentSaveInfo& sinfo) 00090 { 00091 if (itsSaveResults.getVal()) 00092 { 00093 // get the OFS to save to, assuming sinfo is of type 00094 // SimModuleSaveInfo (will throw a fatal exception otherwise): 00095 nub::ref<FrameOstream> ofs = 00096 dynamic_cast<const SimModuleSaveInfo&>(sinfo).ofs; 00097 00098 ofs->writeFloat(this->getV(), FLOAT_NORM_PRESERVE, "AGM", 00099 FrameInfo("overall attention guidance map", SRC_POS)); 00100 } 00101 } 00102 00103 // ###################################################################### 00104 void AttentionGuidanceMap:: 00105 onSimEventSaliencyMapOutput(SimEventQueue& q, rutz::shared_ptr<SimEventSaliencyMapOutput>& e) 00106 { 00107 itsOutputCache.freeMem(); 00108 this->inputBU(e->sm()); 00109 } 00110 00111 // ###################################################################### 00112 void AttentionGuidanceMap:: 00113 onSimEventTaskRelevanceMapOutput(SimEventQueue& q, rutz::shared_ptr<SimEventTaskRelevanceMapOutput>& e) 00114 { 00115 itsOutputCache.freeMem(); 00116 this->inputTD(e->trm()); 00117 } 00118 00119 // ###################################################################### 00120 void AttentionGuidanceMap:: 00121 onSimEventClockTick(SimEventQueue& q, rutz::shared_ptr<SimEventClockTick>& e) 00122 { 00123 doClockTick(q); 00124 } 00125 00126 // ###################################################################### 00127 void AttentionGuidanceMap::doClockTick(SimEventQueue& q) 00128 { 00129 // post an event with our output: 00130 if (itsOutputCache.initialized() == false) itsOutputCache = this->getV(); 00131 if (itsOutputCache.initialized()) 00132 q.post(rutz::make_shared(new SimEventAttentionGuidanceMapOutput(this, itsOutputCache))); 00133 } 00134 00135 // ###################################################################### 00136 // ###################################################################### 00137 // ########## AttentionGuidanceMapConfigurator implementation 00138 // ###################################################################### 00139 // ###################################################################### 00140 AttentionGuidanceMapConfigurator:: 00141 AttentionGuidanceMapConfigurator(OptionManager& mgr, 00142 const std::string& descrName, 00143 const std::string& tagName) : 00144 ModelComponent(mgr, descrName, tagName), 00145 itsAGMtype(&OPT_AttentionGuidanceMapType, this), 00146 itsAGM(new AttentionGuidanceMapStd(mgr)) 00147 { 00148 addSubComponent(itsAGM); 00149 } 00150 00151 // ###################################################################### 00152 AttentionGuidanceMapConfigurator::~AttentionGuidanceMapConfigurator() 00153 { } 00154 00155 // ###################################################################### 00156 nub::ref<AttentionGuidanceMap> 00157 AttentionGuidanceMapConfigurator::getAGM() const 00158 { return itsAGM; } 00159 00160 // ###################################################################### 00161 void AttentionGuidanceMapConfigurator:: 00162 paramChanged(ModelParamBase* const param, 00163 const bool valueChanged, 00164 ParamClient::ChangeStatus* status) 00165 { 00166 ModelComponent::paramChanged(param, valueChanged, status); 00167 00168 // was that a change of our baby's name? 00169 if (param == &itsAGMtype) { 00170 // if we had one, let's unregister it (when we later reset() the 00171 // nub::ref, the current AttentionGuidanceMap will unexport its 00172 // command-line options): 00173 removeSubComponent(*itsAGM); 00174 00175 // instantiate a SM of the appropriate type: 00176 if (itsAGMtype.getVal().compare("Std") == 0) // standard 00177 itsAGM.reset(new AttentionGuidanceMapStd(getManager())); 00178 else if (itsAGMtype.getVal().compare("Opt") == 0) // optimized 00179 itsAGM.reset(new AttentionGuidanceMapOpt(getManager())); 00180 #ifdef INVT_USE_CPPOX//we need c++ 0X features for this to work 00181 else if (itsAGMtype.getVal().compare("SC") == 0) // superior colliculus 00182 itsAGM.reset(new AttentionGuidanceMapSC(getManager())); 00183 else if (itsAGMtype.getVal().compare("NF") == 0) // neural field 00184 itsAGM.reset(new AttentionGuidanceMapNF(getManager())); 00185 #endif 00186 else 00187 LFATAL("Unknown AGM type %s", itsAGMtype.getVal().c_str()); 00188 00189 // add our baby as a subcomponent of us so that it will become 00190 // linked to the manager through us (hopefully we are registered 00191 // with the manager), which in turn will allow it to export its 00192 // command-line options and get configured: 00193 00194 addSubComponent(itsAGM); 00195 00196 // tell the controller to export its options: 00197 itsAGM->exportOptions(MC_RECURSE); 00198 00199 // some info message: 00200 LINFO("Selected AGM of type %s", itsAGMtype.getVal().c_str()); 00201 } 00202 } 00203 00204 // ###################################################################### 00205 // ###################################################################### 00206 // ########## AttentionGuidanceMapStd implementation 00207 // ###################################################################### 00208 // ######################################################################ccc_ 00209 00210 // ###################################################################### 00211 AttentionGuidanceMapStd:: 00212 AttentionGuidanceMapStd(OptionManager& mgr, 00213 const std::string& descrName, 00214 const std::string& tagName) : 00215 AttentionGuidanceMap(mgr, descrName, tagName), 00216 itsBUmap(), itsTDmap() 00217 { } 00218 00219 // ###################################################################### 00220 AttentionGuidanceMapStd::~AttentionGuidanceMapStd() 00221 { } 00222 00223 // ###################################################################### 00224 void AttentionGuidanceMapStd::reset() 00225 { itsBUmap.freeMem(); itsTDmap.freeMem(); } 00226 00227 // ###################################################################### 00228 void AttentionGuidanceMapStd::inputBU(const Image<float>& current) 00229 { itsBUmap = current; } 00230 00231 // ###################################################################### 00232 void AttentionGuidanceMapStd::inputTD(const Image<float>& current) 00233 { itsTDmap = current; } 00234 00235 // ###################################################################### 00236 Image<float> AttentionGuidanceMapStd::getV() const 00237 { 00238 Image<float> ret; 00239 if (!itsBUmap.initialized()) 00240 ret = itsTDmap; 00241 else if (!itsTDmap.initialized()) 00242 ret = itsBUmap; 00243 else if (itsBUmap.getDims() == itsTDmap.getDims()) 00244 ret = itsBUmap * itsTDmap; 00245 else 00246 LINFO("Bottom-up %dx%d vs. top-down %dx%d dims mismatch", 00247 itsBUmap.getWidth(), itsBUmap.getHeight(), 00248 itsTDmap.getWidth(), itsTDmap.getHeight()); 00249 00250 return ret; 00251 } 00252 00253 // ###################################################################### 00254 // ###################################################################### 00255 // ########## AttentionGuidanceMapOpt implementation 00256 // ###################################################################### 00257 // ###################################################################### 00258 00259 // ###################################################################### 00260 AttentionGuidanceMapOpt:: 00261 AttentionGuidanceMapOpt(OptionManager& mgr, 00262 const std::string& descrName, 00263 const std::string& tagName) : 00264 AttentionGuidanceMap(mgr, descrName, tagName), 00265 itsBUmap(), itsTDmap() 00266 { } 00267 00268 // ###################################################################### 00269 AttentionGuidanceMapOpt::~AttentionGuidanceMapOpt() 00270 { } 00271 00272 // ###################################################################### 00273 void AttentionGuidanceMapOpt::reset() 00274 { itsBUmap.freeMem(); itsTDmap.freeMem(); } 00275 00276 // ###################################################################### 00277 void AttentionGuidanceMapOpt::inputBU(const Image<float>& current) 00278 { itsBUmap = current; } 00279 00280 // ###################################################################### 00281 void AttentionGuidanceMapOpt::inputTD(const Image<float>& current) 00282 { itsTDmap = current; } 00283 00284 // ###################################################################### 00285 Image<float> AttentionGuidanceMapOpt::getV() const 00286 { 00287 Image<float> ret; 00288 float a = 0.998F, b = 6.603F; 00289 00290 if (!itsBUmap.initialized()) 00291 ret = itsTDmap; 00292 else if (!itsTDmap.initialized()) 00293 ret = itsBUmap; 00294 else if (itsBUmap.getDims() == itsTDmap.getDims()) 00295 ret = itsBUmap*a + itsTDmap*b + itsBUmap * itsTDmap; 00296 else 00297 LINFO("Bottom-up %dx%d vs. top-down %dx%d dims mismatch", 00298 itsBUmap.getWidth(), itsBUmap.getHeight(), 00299 itsTDmap.getWidth(), itsTDmap.getHeight()); 00300 00301 return ret; 00302 } 00303 00304 #ifdef INVT_USE_CPPOX//we need c++ 0X features for this to work 00305 00306 // ###################################################################### 00307 // ###################################################################### 00308 // ########## AttentionGuidanceMapNeuralSim implementation 00309 // ###################################################################### 00310 // ###################################################################### 00311 00312 // ###################################################################### 00313 AttentionGuidanceMapNeuralSim::AttentionGuidanceMapNeuralSim(OptionManager& mgr, 00314 const std::string& descrName, 00315 const std::string& tagName) : 00316 AttentionGuidanceMap(mgr, descrName, tagName), 00317 itsOutRate(&OPT_AGMoutputRate, this), itsTime(SimTime::ZERO()) 00318 { } 00319 00320 // ###################################################################### 00321 AttentionGuidanceMapNeuralSim::~AttentionGuidanceMapNeuralSim() { } 00322 00323 // ###################################################################### 00324 void AttentionGuidanceMapNeuralSim::doClockTick(SimEventQueue& q) 00325 { 00326 const SimTime interval(q.now() - itsTime); 00327 const int steps = (int)(interval.nsecs() / itsOutRate.getVal().nsecs()); 00328 00329 if (steps <= 0) 00330 update(q.now()); 00331 else 00332 for (int ii = 0; ii < steps; ++ii) 00333 { 00334 itsTime += itsOutRate.getVal(); 00335 update(itsTime); 00336 postMessage(q); 00337 } 00338 } 00339 00340 // ###################################################################### 00341 // ###################################################################### 00342 // ########## AttentionGuidanceMapSC implementation 00343 // ###################################################################### 00344 // ###################################################################### 00345 00346 // ###################################################################### 00347 AttentionGuidanceMapSC::AttentionGuidanceMapSC(OptionManager& mgr, 00348 const std::string& descrName, 00349 const std::string& tagName) 00350 : AttentionGuidanceMapNeuralSim(mgr, descrName, tagName), itsSC(new SupColliculusModule(mgr)) 00351 { 00352 addSubComponent(itsSC); 00353 } 00354 00355 // ###################################################################### 00356 AttentionGuidanceMapSC::~AttentionGuidanceMapSC() 00357 { } 00358 00359 // ###################################################################### 00360 void AttentionGuidanceMapSC::reset() 00361 { itsSC->reset(); } 00362 00363 // ###################################################################### 00364 void AttentionGuidanceMapSC::inputBU(const Image<float>& current) 00365 { itsSC->setInput(current, 0); }//input to sgs 00366 00367 // ###################################################################### 00368 void AttentionGuidanceMapSC::inputTD(const Image<float>& current) 00369 { itsSC->setInput(current, 1); }//input to sgs 00370 00371 // ###################################################################### 00372 Image<float> AttentionGuidanceMapSC::getV() const 00373 { 00374 LINFO("Superior Colliculus Guidance Map is an ImageSet, so this function is depricated here"); 00375 return Image<float>(); 00376 } 00377 00378 // ###################################################################### 00379 void AttentionGuidanceMapSC::update(const SimTime& time) 00380 { 00381 itsSC->update(time); 00382 } 00383 00384 // ###################################################################### 00385 void AttentionGuidanceMapSC::postMessage(SimEventQueue& q) 00386 { 00387 q.post(rutz::make_shared(new SimEventAttentionGuidanceMapOutput(this, itsSC->getSubV()))); 00388 } 00389 00390 // ###################################################################### 00391 void AttentionGuidanceMapSC::save1(const ModelComponentSaveInfo& sinfo) 00392 { 00393 if (itsSaveResults.getVal()) 00394 { 00395 // get the OFS to save to, assuming sinfo is of type 00396 // SimModuleSaveInfo (will throw a fatal exception otherwise): 00397 nub::ref<FrameOstream> ofs = 00398 dynamic_cast<const SimModuleSaveInfo&>(sinfo).ofs; 00399 ofs->writeRgbLayout(itsSC->getDisplay(), "AGM-SC", FrameInfo("SC Model Output", SRC_POS)); 00400 } 00401 } 00402 00403 // ###################################################################### 00404 // ###################################################################### 00405 // ########## AttentionGuidanceMapNF implementation 00406 // ###################################################################### 00407 // ###################################################################### 00408 00409 // ###################################################################### 00410 AttentionGuidanceMapNF::AttentionGuidanceMapNF(OptionManager& mgr, 00411 const std::string& descrName, 00412 const std::string& tagName) 00413 : AttentionGuidanceMapNeuralSim(mgr, descrName, tagName), itsNF(new NeuralFieldModule(mgr)) 00414 { 00415 addSubComponent(itsNF); 00416 } 00417 00418 // ###################################################################### 00419 AttentionGuidanceMapNF::~AttentionGuidanceMapNF() 00420 { } 00421 00422 // ###################################################################### 00423 void AttentionGuidanceMapNF::reset() 00424 { itsNF->reset(); } 00425 00426 // ###################################################################### 00427 void AttentionGuidanceMapNF::inputBU(const Image<float>& current) 00428 { itsNF->setInput(current, 0); }//input to sgs 00429 00430 // ###################################################################### 00431 void AttentionGuidanceMapNF::inputTD(const Image<float>& current) 00432 { itsNF->setInput(current, 0); }//input to sgs 00433 00434 // ###################################################################### 00435 Image<float> AttentionGuidanceMapNF::getV() const 00436 { return itsNF->getV(0); }//output from sgi 00437 00438 // ###################################################################### 00439 void AttentionGuidanceMapNF::update(const SimTime& time) 00440 { 00441 itsNF->update(time); 00442 } 00443 00444 // ###################################################################### 00445 void AttentionGuidanceMapNF::postMessage(SimEventQueue& q) 00446 { 00447 q.post(rutz::make_shared(new SimEventAttentionGuidanceMapOutput(this, itsNF->getV(0)))); 00448 } 00449 00450 // ###################################################################### 00451 void AttentionGuidanceMapNF::save1(const ModelComponentSaveInfo& sinfo) 00452 { 00453 if (itsSaveResults.getVal()) 00454 { 00455 // get the OFS to save to, assuming sinfo is of type 00456 // SimModuleSaveInfo (will throw a fatal exception otherwise): 00457 nub::ref<FrameOstream> ofs = 00458 dynamic_cast<const SimModuleSaveInfo&>(sinfo).ofs; 00459 ofs->writeRgbLayout(itsNF->getDisplay(), "AGM-NF", FrameInfo("NF Model Output", SRC_POS)); 00460 } 00461 } 00462 00463 #endif 00464 // ###################################################################### 00465 /* So things look consistent in everyone's emacs... */ 00466 /* Local Variables: */ 00467 /* indent-tabs-mode: nil */ 00468 /* End: */