00001 /*!@file Neuro/VisualCortexConfigurator.C Class to select a VisualCortex at 00002 runtime */ 00003 00004 // //////////////////////////////////////////////////////////////////// // 00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003 // 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: Laurent Itti <itti@usc.edu> 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Neuro/VisualCortexConfigurator.C $ 00036 // $Id: VisualCortexConfigurator.C 11580 2009-08-11 00:54:51Z itti $ 00037 // 00038 00039 #include "Neuro/VisualCortexConfigurator.H" 00040 00041 #include "Beowulf/Beowulf.H" 00042 #include "Channels/RawVisualCortex.H" 00043 #include "Channels/IntegerRawVisualCortex.H" 00044 #include "Channels/ChannelOpts.H" 00045 #include "Channels/ChannelVisitor.H" 00046 #include "Channels/EntropyChannel.H" 00047 #include "Channels/InformationChannel.H" 00048 #include "Channels/InputHandlerThreaded.H" 00049 #include "Channels/MichelsonChannel.H" 00050 #include "Channels/MultiSpectralResidualChannel.H" 00051 #include "Channels/PN03contrastChannel.H" 00052 #include "Channels/ScorrChannel.H" 00053 #include "Channels/SpectralResidualChannel.H" 00054 #include "Channels/TcorrChannel.H" 00055 #include "Channels/VarianceChannel.H" 00056 #include "Component/OptionManager.H" 00057 #include "Neuro/NeuroOpts.H" 00058 #include "Neuro/VisualCortex.H" 00059 #include "Neuro/VisualCortexBeo.H" 00060 #include "Neuro/VisualCortexEyeMvt.H" 00061 #include "Neuro/VisualCortexSurprise.H" 00062 #include "Beowulf/BeowulfOpts.H" 00063 #include "Util/StringUtil.H" 00064 00065 namespace 00066 { 00067 class ThreadInstaller : public ChannelVisitor 00068 { 00069 public: 00070 ThreadInstaller() 00071 {} 00072 00073 virtual ~ThreadInstaller() 00074 {} 00075 00076 virtual void visitChannelBase(ChannelBase& chan) 00077 { 00078 LFATAL("I don't know how to configure channel '%s' for Threaded use", 00079 chan.descriptiveName().c_str()); 00080 } 00081 00082 virtual void visitSingleChannel(SingleChannel& chan) 00083 { 00084 chan.setInputHandler 00085 (rutz::make_shared(new InputHandlerThreaded)); 00086 } 00087 00088 virtual void visitComplexChannel(ComplexChannel& chan) 00089 { 00090 chan.setSubchanVisitor 00091 (rutz::make_shared(new ThreadInstaller)); 00092 00093 // now iterate over the subchannels: 00094 for (uint i = 0; i < chan.numChans(); ++i) 00095 chan.subChan(i)->accept(*this); 00096 } 00097 }; 00098 } 00099 00100 // ###################################################################### 00101 VisualCortexConfigurator:: 00102 VisualCortexConfigurator(OptionManager& mgr, 00103 const std::string& descrName, 00104 const std::string& tagName) : 00105 ModelComponent(mgr, descrName, tagName), 00106 itsVCtype(&OPT_VisualCortexType, this), 00107 itsVC(new VisualCortex(mgr)), // initialize with an empty VisualCortex 00108 itsBeo() 00109 { 00110 addSubComponent(itsVC); 00111 } 00112 00113 // ###################################################################### 00114 VisualCortexConfigurator::~VisualCortexConfigurator() 00115 { } 00116 00117 // ###################################################################### 00118 nub::ref<VisualCortex> VisualCortexConfigurator::getVC() const 00119 { return itsVC; } 00120 00121 // ###################################################################### 00122 nub::soft_ref<Beowulf> VisualCortexConfigurator::getBeo() const 00123 { return itsBeo; } 00124 00125 // ###################################################################### 00126 void VisualCortexConfigurator::paramChanged(ModelParamBase* const param, 00127 const bool valueChanged, 00128 ParamClient::ChangeStatus* status) 00129 { 00130 ModelComponent::paramChanged(param, valueChanged, status); 00131 00132 // was that a change of our baby's name? 00133 if (param == &itsVCtype) { 00134 // some info message: 00135 LINFO("Configuring VC of type %s", itsVCtype.getVal().c_str()); 00136 OptionManager& mgr = this->getManager(); 00137 00138 // if we had one, let's unregister it (when we later reset() the 00139 // nub::ref, the current VisualCortex will unexport its 00140 // command-line options). NOTE: here we explicitly reset itsVC to 00141 // a placeholder dummy (base class) VisualCortex, to make sure all 00142 // options get unexported right now, as otherwise some conflict 00143 // will occur between the int definition of --vc-chans and the std 00144 // one, when switching from an Std VisualCortex to an Int one: 00145 LINFO("Resetting VisualCortex..."); 00146 removeSubComponent(*itsVC); 00147 itsVC.reset(new VisualCortex(mgr)); 00148 00149 if (itsBeo.isValid()) { 00150 LINFO("Resetting VisualCortex Beowulf..."); 00151 removeSubComponent(*itsBeo); itsBeo.reset(NULL); 00152 } 00153 00154 // Look for modifiers, like "Thread:" 00155 std::vector<std::string> tok; 00156 split(itsVCtype.getVal(), ":", std::back_inserter(tok)); 00157 bool threaded = false; const std::string vct = tok.back(); tok.pop_back(); 00158 for (size_t i = 0; i < tok.size(); ++i) 00159 if (tok[i].compare("Thread") == 0) threaded = true; 00160 else LFATAL("Unknown vc-type modifier: %s", tok[i].c_str()); 00161 00162 // instantiate a VC of the appropriate type: 00163 00164 // #################### Empty "Stub" visual cortex: 00165 if (vct.compare("None") == 0 || vct.compare("Stub") == 0) 00166 itsVC.reset(new VisualCortex(mgr)); 00167 00168 // #################### Standard channels: 00169 else if (vct.compare("Std") == 0) 00170 { 00171 nub::ref<VisualCortexStd> vcx(new VisualCortexStd(mgr, "Visual Cortex", "VisualCortex")); 00172 if (threaded) { 00173 vcx->itsVCX->setSubchanVisitor(rutz::make_shared(new ThreadInstaller)); 00174 vcx->itsVCX->sortChannelsByNumSubmaps(true); 00175 } 00176 itsVC = vcx; 00177 } 00178 // #################### Human eye movement fake cortex: 00179 else if (vct.compare("EyeMvt") == 0) 00180 itsVC.reset(new VisualCortexEyeMvt(mgr)); 00181 00182 // #################### Entropy model: 00183 else if (vct.compare("Entrop") == 0) // entropy 00184 { 00185 nub::ref<VisualCortexStd> vcx(new VisualCortexStd(mgr)); 00186 vcx->itsVCX->removeAllSubChans(); vcx->itsVCX->hideOption(&OPT_RawVisualCortexChans); 00187 nub::soft_ref<EntropyChannel> channel(new EntropyChannel(mgr)); 00188 vcx->itsVCX->addSubChan(channel); 00189 mgr.setOptionValString(&OPT_LevelSpec, "4-4,0-0,4"); 00190 itsVC = vcx; 00191 } 00192 00193 // #################### Variance model: 00194 else if (vct.compare("Variance") == 0) 00195 { 00196 nub::ref<VisualCortexStd> vcx(new VisualCortexStd(mgr)); 00197 vcx->itsVCX->removeAllSubChans(); vcx->itsVCX->hideOption(&OPT_RawVisualCortexChans); 00198 nub::soft_ref<VarianceChannel> channel(new VarianceChannel(mgr)); 00199 vcx->itsVCX->addSubChan(channel); 00200 mgr.setOptionValString(&OPT_LevelSpec, "4-4,0-0,4"); 00201 itsVC = vcx; 00202 } 00203 00204 // #################### Michelson contrast model: 00205 else if (vct.compare("Michelson") == 0) 00206 { 00207 nub::ref<VisualCortexStd> vcx(new VisualCortexStd(mgr)); 00208 vcx->itsVCX->removeAllSubChans(); vcx->itsVCX->hideOption(&OPT_RawVisualCortexChans); 00209 nub::soft_ref<MichelsonChannel> channel(new MichelsonChannel(mgr)); 00210 vcx->itsVCX->addSubChan(channel); 00211 mgr.setOptionValString(&OPT_LevelSpec, "4-4,0-0,4"); 00212 itsVC = vcx; 00213 } 00214 00215 // #################### Tcorr model: 00216 else if (vct.compare("Tcorr") == 0) 00217 { 00218 nub::ref<VisualCortexStd> vcx(new VisualCortexStd(mgr)); 00219 vcx->itsVCX->removeAllSubChans(); vcx->itsVCX->hideOption(&OPT_RawVisualCortexChans); 00220 nub::soft_ref<TcorrChannel> channel(new TcorrChannel(mgr)); 00221 vcx->itsVCX->addSubChan(channel); 00222 mgr.setOptionValString(&OPT_LevelSpec, "4-4,0-0,4"); 00223 itsVC = vcx; 00224 } 00225 00226 // #################### Scorr model: 00227 else if (vct.compare("Scorr") == 0) 00228 { 00229 nub::ref<VisualCortexStd> vcx(new VisualCortexStd(mgr)); 00230 vcx->itsVCX->removeAllSubChans(); vcx->itsVCX->hideOption(&OPT_RawVisualCortexChans); 00231 nub::soft_ref<ScorrChannel> channel(new ScorrChannel(mgr)); 00232 vcx->itsVCX->addSubChan(channel); 00233 mgr.setOptionValString(&OPT_LevelSpec, "4-4,0-0,4"); 00234 itsVC = vcx; 00235 } 00236 00237 // #################### Information model: 00238 else if (vct.compare("Info") == 0) 00239 { 00240 nub::ref<VisualCortexStd> vcx(new VisualCortexStd(mgr)); 00241 vcx->itsVCX->removeAllSubChans(); vcx->itsVCX->hideOption(&OPT_RawVisualCortexChans); 00242 nub::soft_ref<InformationChannel> channel(new InformationChannel(mgr)); 00243 vcx->itsVCX->addSubChan(channel); 00244 mgr.setOptionValString(&OPT_LevelSpec, "4-4,0-0,4"); 00245 itsVC = vcx; 00246 } 00247 00248 // #################### PN03contrast model: 00249 else if (vct.compare("PN03contrast") == 0) 00250 { 00251 nub::ref<VisualCortexStd> vcx(new VisualCortexStd(mgr)); 00252 vcx->itsVCX->removeAllSubChans(); vcx->itsVCX->hideOption(&OPT_RawVisualCortexChans); 00253 nub::soft_ref<PN03contrastChannel> channel(new PN03contrastChannel(mgr)); 00254 vcx->itsVCX->addSubChan(channel); 00255 mgr.setOptionValString(&OPT_LevelSpec, "4-4,0-0,4"); 00256 itsVC = vcx; 00257 } 00258 00259 // #################### Spectral Residual model: 00260 else if (vct.compare("SpectralResidual") == 0) 00261 { 00262 nub::ref<VisualCortexStd> vcx(new VisualCortexStd(mgr)); 00263 vcx->itsVCX->removeAllSubChans(); vcx->itsVCX->hideOption(&OPT_RawVisualCortexChans); 00264 nub::soft_ref<SpectralResidualChannel> channel(new SpectralResidualChannel(mgr)); 00265 vcx->itsVCX->addSubChan(channel); 00266 mgr.setOptionValString(&OPT_LevelSpec, "4-4,0-0,4"); 00267 itsVC = vcx; 00268 } 00269 00270 // #################### Multi Spectral Residual model: 00271 else if (vct.compare("MultiSpectralResidual") == 0) 00272 { 00273 nub::ref<VisualCortexStd> vcx(new VisualCortexStd(mgr)); 00274 vcx->itsVCX->removeAllSubChans(); vcx->itsVCX->hideOption(&OPT_RawVisualCortexChans); 00275 nub::soft_ref<MultiSpectralResidualChannel> channel(new MultiSpectralResidualChannel(mgr)); 00276 vcx->itsVCX->addSubChan(channel); 00277 mgr.setOptionValString(&OPT_LevelSpec, "4-4,0-0,4"); 00278 itsVC = vcx; 00279 } 00280 00281 // #################### Standard beo-channels: 00282 else if (vct.compare("Beo") == 0) 00283 { 00284 itsBeo.reset(new Beowulf(mgr, "Visual Cortex Beowulf", "VisualCortexBeowulf", true)); 00285 nub::ref<VisualCortexStd> vcx(new VisualCortexStd(mgr, "Visual Cortex", "VisualCortex")); 00286 setupVisualCortexBeo(*(vcx->itsVCX), itsBeo); 00287 itsVC = vcx; 00288 } 00289 00290 // #################### Standard surprise-channels: 00291 else if (vct.compare("Surp") == 0) 00292 { 00293 nub::ref<VisualCortexSurprise> vcs(new VisualCortexSurprise(mgr)); 00294 nub::ref<VisualCortexStd> vcx(new VisualCortexStd(mgr, "Visual Cortex", "VisualCortex", vcs)); 00295 if (threaded) { 00296 vcx->itsVCX->setSubchanVisitor(rutz::make_shared(new ThreadInstaller)); 00297 vcx->itsVCX->sortChannelsByNumSubmaps(true); 00298 } 00299 itsVC = vcx; 00300 } 00301 00302 // #################### Standard int channels: 00303 else if (vct.compare("Int") == 0) 00304 { 00305 nub::ref<VisualCortexInt> vcx(new VisualCortexInt(mgr, "Visual Cortex", "VisualCortex")); 00306 if (threaded) { 00307 vcx->itsVCX->setSubchanVisitor(rutz::make_shared(new ThreadInstaller)); 00308 vcx->itsVCX->sortChannelsByNumSubmaps(true); 00309 } 00310 itsVC = vcx; 00311 } 00312 // #################### EnvVisualCortex 00313 else if (vct.compare("Env") == 0) 00314 { 00315 nub::ref<VisualCortexEnv> vcx(new VisualCortexEnv(mgr, "Visual Cortex", "VisualCortex")); 00316 itsVC = vcx; 00317 } 00318 // #################### unknown 00319 else 00320 LFATAL("Unknown vc-type: %s", vct.c_str()); 00321 00322 // add our babies as a subcomponents of us so that they will 00323 // become linked to the manager through us (hopefully we are 00324 // registered with the manager), which in turn will allow them to 00325 // export their command-line options and get configured. Note: the 00326 // Beowulf needs to be start()'ed by the time the VC starts, so we 00327 // add it first here if we have one: 00328 if (itsBeo.isValid()) 00329 { 00330 addSubComponent(itsBeo); 00331 00332 // export options: 00333 itsBeo->exportOptions(MC_RECURSE); 00334 00335 // make sure we are beowulf master: 00336 mgr.setOptionValString(&OPT_BeowulfMaster, "true"); 00337 } 00338 00339 // register our visual cortex as a subcomponent: 00340 addSubComponent(itsVC); 00341 00342 // export its options: 00343 itsVC->exportOptions(MC_RECURSE); 00344 } 00345 } 00346 00347 00348 // ###################################################################### 00349 /* So things look consistent in everyone's emacs... */ 00350 /* Local Variables: */ 00351 /* indent-tabs-mode: nil */ 00352 /* End: */