PrefrontalCortex.C

Go to the documentation of this file.
00001 /*!@file Neuro/PrefrontalCortex.C a human PrefrontalCortex */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003   //
00005 // by the 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: Lior Elazary
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Neuro/PrefrontalCortex.C $
00035 // $Id: PrefrontalCortex.C 13065 2010-03-28 00:01:00Z itti $
00036 //
00037 
00038 #include "Neuro/PrefrontalCortex.H"
00039 
00040 #include "Component/OptionManager.H"
00041 #include "Component/ModelOptionDef.H"
00042 #include "Channels/GuidedSearch.H"
00043 #include "Channels/OptimalGains.H"
00044 #include "Image/DrawOps.H"
00045 #include "Learn/Bayes.H"
00046 #include "Media/MediaSimEvents.H"
00047 #include "Media/TestImages.H"
00048 #include "Neuro/NeuroOpts.H"
00049 #include "Neuro/NeuroSimEvents.H"
00050 #include "Neuro/VisualCortex.H"
00051 #include "ObjRec/BayesianBiaser.H"
00052 #include "Simulation/SimEventQueue.H"
00053 
00054 // ######################################################################
00055 // ######################################################################
00056 // ########## PrefrontalCortex implementation
00057 // ######################################################################
00058 // ######################################################################
00059 PrefrontalCortex::PrefrontalCortex(OptionManager& mgr,
00060                                    const std::string& descrName,
00061                                    const std::string& tagName) :
00062   SimModule(mgr, descrName, tagName)
00063 { }
00064 
00065 // ######################################################################
00066 PrefrontalCortex::~PrefrontalCortex()
00067 { }
00068 
00069 // ######################################################################
00070 // ######################################################################
00071 // ########## PrefrontalCortexConfigurator implementation
00072 // ######################################################################
00073 // ######################################################################
00074 PrefrontalCortexConfigurator::
00075 PrefrontalCortexConfigurator(OptionManager& mgr,
00076                    const std::string& descrName,
00077                    const std::string& tagName) :
00078   ModelComponent(mgr, descrName, tagName),
00079   itsType(&OPT_PrefrontalCortexType, this),
00080   itsPFC(new PrefrontalCortexStub(mgr))
00081 {
00082   addSubComponent(itsPFC);
00083 }
00084 
00085 // ######################################################################
00086 PrefrontalCortexConfigurator::~PrefrontalCortexConfigurator()
00087 {  }
00088 
00089 // ######################################################################
00090 nub::ref<PrefrontalCortex> PrefrontalCortexConfigurator::getPFC() const
00091 { return itsPFC; }
00092 
00093 // ######################################################################
00094 void PrefrontalCortexConfigurator::paramChanged(ModelParamBase* const param,
00095                                       const bool valueChanged,
00096                                       ParamClient::ChangeStatus* status)
00097 {
00098   ModelComponent::paramChanged(param, valueChanged, status);
00099 
00100   // was that a change of our baby's name?
00101   if (param == &itsType) {
00102     // let's unregister our existing PrefrontalCortex:
00103     removeSubComponent(*itsPFC);
00104 
00105     // instantiate a PrefrontalCortex of the appropriate type (when the old
00106     // PrefrontalCortex is destroyed, it will un-export its command-line
00107     // options):
00108     if (itsType.getVal().compare("Stub") == 0)              // stub
00109       itsPFC.reset(new PrefrontalCortexStub(getManager()));
00110     else if (itsType.getVal().compare("OG") == 0)           // Optimal Gains
00111       itsPFC.reset(new PrefrontalCortexOG(getManager()));
00112     else if (itsType.getVal().compare("GS") == 0)           // Guided Search
00113       itsPFC.reset(new PrefrontalCortexGS(getManager()));
00114     else if (itsType.getVal().compare("SB") == 0)           // SalBayes
00115       itsPFC.reset(new PrefrontalCortexSB(getManager()));
00116     else
00117       LFATAL("Unknown PrefrontalCortex type %s", itsType.getVal().c_str());
00118 
00119     // add our baby as a subcomponent of us so that it will become
00120     // linked to the manager through us (hopefully we are registered
00121     // with the manager), which in turn will allow it to export its
00122     // command-line options and get configured:
00123     addSubComponent(itsPFC);
00124 
00125     // tell the controller to export its options:
00126     itsPFC->exportOptions(MC_RECURSE);
00127 
00128     // some info message:
00129     LINFO("Selected PFC of type %s", itsType.getVal().c_str());
00130   }
00131 }
00132 
00133 // ######################################################################
00134 // ######################################################################
00135 // ########## PrefrontalCortexStub implementation
00136 // ######################################################################
00137 // ######################################################################
00138 PrefrontalCortexStub::PrefrontalCortexStub(OptionManager& mgr,
00139                                            const std::string& descrName,
00140                                            const std::string& tagName) :
00141   PrefrontalCortex(mgr, descrName, tagName)
00142 { }
00143 
00144 // ######################################################################
00145 PrefrontalCortexStub::~PrefrontalCortexStub()
00146 { }
00147 
00148 // ######################################################################
00149 // ######################################################################
00150 // ########## PrefrontalCortexOG implementation
00151 // ######################################################################
00152 // ######################################################################
00153 
00154 static const ModelOptionDef OPT_PFCOG_stsdfilename =
00155   { MODOPT_ARG_STRING, "PFCOGstsdfilename", &MOC_PFC, OPTEXP_CORE,
00156     "Name of the file to save computed salienceT and salienceD values, "
00157     "so that they could be later combined across several images.",
00158     "stsd-filename", '\0', "<filename>", "" };
00159 
00160 static const ModelOptionDef OPT_PFCOG_DoMax =
00161   { MODOPT_FLAG, "PFCOGdoMax", &MOC_PFC, OPTEXP_CORE,
00162     "Use the max value from the object as a feature or the mean value.",
00163     "pfc-do-max", '\0', "", "false" };
00164 
00165 static const ModelOptionDef OPT_PFCOG_targetMaskObjName =
00166   { MODOPT_ARG_STRING, "PFCOGtargetMaskObjName", &MOC_PFC, OPTEXP_CORE,
00167     "Name of the object used to build the target mask. The mask is "
00168     "built by looking at all objects matching this name. If no name "
00169     "is specified then every object that is in the xml is used to "
00170     "build the target mask. ",
00171     "target-mask-objName", '\0', "<name>", "" };
00172 
00173 static const ModelOptionDef OPT_PFCOG_distractorMaskObjName =
00174   { MODOPT_ARG_STRING, "PFCOGdistractorMaskObjName", &MOC_PFC, OPTEXP_CORE,
00175     "Name of the object used to build the distractor mask. The mask is "
00176     "built by looking at all objects matching this name. If no name "
00177     "is specified then the distractor is build by taking the "
00178     "complement of the target mask",
00179     "distractor-mask-objName", '\0', "<name>", "" };
00180 
00181 namespace {
00182   // a SimEvent to compute salience of target and distractor
00183   class SimReqOGtrain : public SimReqVCXchanVis {
00184   public:
00185     SimReqOGtrain(SimModule* src, const Image<byte>& tmask,
00186                   const Image<byte>& dmask,
00187                   rutz::shared_ptr<ParamMap> pmap,
00188                   const std::string& fname, const bool domax) :
00189       SimReqVCXchanVis(src, rutz::shared_ptr<ChannelVisitor>
00190                        (new OptimalGainsFinder(tmask, dmask, pmap, domax))),
00191       itsPmap(pmap), itsFilename(fname)
00192     { }
00193 
00194     virtual ~SimReqOGtrain()
00195     { }
00196 
00197     virtual void postProcessing(RawVisualCortex *vcx)
00198     {
00199       if (itsFilename.empty() == false)
00200         {
00201           LINFO("Saving sT and sD values to %s", itsFilename.c_str());
00202           itsPmap->format(itsFilename);
00203         }
00204     }
00205 
00206   private:
00207     rutz::shared_ptr<ParamMap> itsPmap;
00208     const std::string itsFilename;
00209   };
00210 };
00211 
00212 // ######################################################################
00213 PrefrontalCortexOG::PrefrontalCortexOG(OptionManager& mgr,
00214                                        const std::string& descrName,
00215                                        const std::string& tagName) :
00216   PrefrontalCortex(mgr, descrName, tagName),
00217   SIMCALLBACK_INIT(SimEventInputFrame),
00218   SIMCALLBACK_INIT(SimEventVisualCortexOutput),
00219   itsFilename(&OPT_PFCOG_stsdfilename, this),
00220   itsTargetMaskObjName(&OPT_PFCOG_targetMaskObjName, this),
00221   itsDistractorMaskObjName(&OPT_PFCOG_distractorMaskObjName, this),
00222   itsDoMax(&OPT_PFCOG_DoMax, this),
00223   itsTargetMask(), itsDistractorMask()
00224 { }
00225 
00226 // ######################################################################
00227 void PrefrontalCortexOG::
00228 onSimEventInputFrame(SimEventQueue& q, rutz::shared_ptr<SimEventInputFrame>& e)
00229 {
00230   GenericFrame gf = e->frame();
00231   rutz::shared_ptr<GenericFrame::MetaData>
00232     metaData = gf.getMetaData(std::string("SceneData"));
00233   if (metaData.get() != 0) {
00234     rutz::shared_ptr<TestImages::SceneData> sceneData;
00235     sceneData.dyn_cast_from(metaData);
00236 
00237     // Train on all objects in the scene
00238     // Build the target and distractor mask, if multiple objects then add
00239     // which ever matches the target string to the target mask, and distractor string to
00240     // distractor mask. If no strings are spacified, then build from all objects and/or distractor
00241     // that is complmant the object
00242 
00243     itsDistractorMask = Image<byte>(sceneData->dims, ZEROS);
00244     itsTargetMask = Image<byte>(sceneData->dims, ZEROS);
00245 
00246     for (uint i = 0; i < sceneData->objects.size(); i++) {
00247       TestImages::ObjData objData = sceneData->objects[i];
00248 
00249       // get the target mask, either it was provided as a mask image:
00250       if (objData.objmask.initialized())
00251       {
00252         LINFO("Drawing target mask from B/W mask file data...");
00253         itsTargetMask += objData.objmask;
00254       }
00255 
00256       // ... and/or with a polygon:
00257       if (objData.polygon.empty() == false) {
00258         LINFO("Drawing target mask from polygon data from %s...", objData.name.c_str());
00259         if (itsTargetMaskObjName.getVal().size() > 0 &&
00260             objData.name == itsTargetMaskObjName.getVal())
00261           drawFilledPolygon(itsTargetMask, objData.polygon, byte(255));
00262 
00263         if (itsTargetMaskObjName.getVal().size() == 0)
00264           drawFilledPolygon(itsTargetMask, objData.polygon, byte(255));
00265       }
00266 
00267       if (itsDistractorMaskObjName.getVal().size() > 0 &&
00268           objData.name == itsDistractorMaskObjName.getVal())
00269       {
00270         LINFO("Drawing distractor mask from polygon data from %s...", objData.name.c_str());
00271         drawFilledPolygon(itsDistractorMask, objData.polygon, byte(255));
00272       }
00273     }
00274 
00275     if (itsDistractorMaskObjName.getVal().size() == 0)
00276     {
00277       // Create a distractor mask from 255-targetMask:
00278       itsDistractorMask.clear(255);
00279       itsDistractorMask -= itsTargetMask;
00280     }
00281   }
00282 }
00283 
00284 // ######################################################################
00285 void PrefrontalCortexOG::
00286 onSimEventVisualCortexOutput(SimEventQueue& q, rutz::shared_ptr<SimEventVisualCortexOutput>& e)
00287 {
00288   rutz::shared_ptr<ParamMap> pmap(new ParamMap());
00289   rutz::shared_ptr<SimReqVCXchanVis> ev(new SimReqOGtrain(this, itsTargetMask, itsDistractorMask, pmap,
00290                                                           itsFilename.getVal(), itsDoMax.getVal()));
00291   LINFO("Requesting training STSD data from VCX...");
00292   q.request(ev);
00293 
00294   // the resulting sT and sD values will be saved to our
00295   // filename in the form of a ParamMap.
00296 }
00297 
00298 // ######################################################################
00299 PrefrontalCortexOG::~PrefrontalCortexOG()
00300 { }
00301 
00302 // ######################################################################
00303 // ######################################################################
00304 // ########## PrefrontalCortexGS implementation
00305 // ######################################################################
00306 // ######################################################################
00307 // ######################################################################
00308 static const ModelOptionDef OPT_PFCGS_gainsfilename =
00309   { MODOPT_ARG_STRING, "PFCGSgainsfilename", &MOC_PFC, OPTEXP_CORE,
00310     "Name of the file to load biasing gains.",
00311     "gains-filename", '\0', "<filename>", "" };
00312 
00313 namespace {
00314   // a SimEvent to do guided search from a pmap of gains
00315   class SimReqGSbias : public SimReqVCXchanVis {
00316   public:
00317     SimReqGSbias(SimModule* src, rutz::shared_ptr<ParamMap> pmap) :
00318       SimReqVCXchanVis(src, rutz::shared_ptr<ChannelVisitor>(new GuidedSearchBiaser(pmap)))
00319     { }
00320 
00321     virtual ~SimReqGSbias()
00322     { }
00323   };
00324 };
00325 
00326 
00327 // ######################################################################
00328 PrefrontalCortexGS::PrefrontalCortexGS(OptionManager& mgr,
00329                                        const std::string& descrName,
00330                                        const std::string& tagName) :
00331   PrefrontalCortex(mgr, descrName, tagName),
00332   SIMCALLBACK_INIT(SimEventInputFrame),
00333   itsFilename(&OPT_PFCGS_gainsfilename, this)
00334 { }
00335 
00336 // ######################################################################
00337 PrefrontalCortexGS::~PrefrontalCortexGS()
00338 { }
00339 
00340 // ######################################################################
00341 void PrefrontalCortexGS::
00342 onSimEventInputFrame(SimEventQueue& q, rutz::shared_ptr<SimEventInputFrame>& e)
00343 {
00344   // load the paramap:
00345   rutz::shared_ptr<ParamMap> pmap = ParamMap::loadPmapFile(itsFilename.getVal());
00346 
00347   // post an event with biasing information:
00348   rutz::shared_ptr<SimReqVCXchanVis> ev(new SimReqGSbias(this, pmap));
00349   q.request(ev);
00350 }
00351 
00352 
00353 // ######################################################################
00354 // ######################################################################
00355 // ########## PrefrontalCortexSB implementation
00356 // ######################################################################
00357 // ######################################################################
00358 
00359 static const ModelOptionDef OPT_PFCSalBayes_NetworkFile =
00360   { MODOPT_ARG_STRING, "PFCBaysNetFile", &MOC_PFC, OPTEXP_CORE,
00361     "Name of the file to read the computed Bayesian Network",
00362     "pfc-BayesNet-file", '\0', "<filename>", "SalBayes.net" };
00363 
00364 static const ModelOptionDef OPT_PFCSalBayes_ObjToBias =
00365   { MODOPT_ARG(int), "PFCObjectToBiasFor", &MOC_PFC, OPTEXP_CORE,
00366     "The object ID from the database that we should be biasing for.",
00367     "pfc-obj-to-bias", '\0', "<int>", "0" };
00368 
00369 namespace {
00370   // a SimEvent to do SalBayes biasing
00371   class SimReqSBbias : public SimReqVCXchanVis {
00372   public:
00373     SimReqSBbias(SimModule* src, Bayes& b, const int obj) :
00374       SimReqVCXchanVis(src, rutz::shared_ptr<ChannelVisitor>(new BayesianBiaser(b, obj, -1, true)))
00375     { }
00376 
00377     virtual ~SimReqSBbias()
00378     { }
00379   };
00380 };
00381 
00382 // ######################################################################
00383 PrefrontalCortexSB::PrefrontalCortexSB(OptionManager& mgr,
00384                                        const std::string& descrName,
00385                                        const std::string& tagName) :
00386   PrefrontalCortex(mgr, descrName, tagName),
00387   SIMCALLBACK_INIT(SimEventInputFrame),
00388   itsBayesNetFilename(&OPT_PFCSalBayes_NetworkFile, this),
00389   itsObjToBias(&OPT_PFCSalBayes_ObjToBias, this)
00390 { }
00391 
00392 // ######################################################################
00393 void PrefrontalCortexSB::start1()
00394 {
00395   itsBayesNet.reset(new Bayes(0, 0)); //This will be set by the load
00396   if (!itsBayesNet->load(itsBayesNetFilename.getVal().c_str()))
00397     LFATAL("Cannot load database file %s",
00398            itsBayesNetFilename.getVal().c_str());
00399 
00400   PrefrontalCortex::start1();
00401 }
00402 
00403 // ######################################################################
00404 void PrefrontalCortexSB::
00405 onSimEventInputFrame(SimEventQueue& q, rutz::shared_ptr<SimEventInputFrame>& e)
00406 {
00407   const uint obj = uint(itsObjToBias.getVal());
00408   if (obj < itsBayesNet->getNumClasses()) {
00409     const char* oname = itsBayesNet->getClassName(obj);
00410     LINFO("Biasing VC for '%s'", oname);
00411 
00412     // Post the object we are biasing for so that interested people know:
00413     rutz::shared_ptr<SimEventObjectToBias>
00414       eotb(new SimEventObjectToBias(this, oname));
00415     q.post(eotb);
00416 
00417     // Post the bias visitor to blackboard
00418     rutz::shared_ptr<SimReqVCXchanVis> ebv(new SimReqSBbias(this, *itsBayesNet.get(), obj));
00419     q.request(ebv);
00420   } else {
00421     LINFO("Cannot find objid %i in the database", obj);
00422     LINFO("Available objects are:");
00423     for (uint i = 0; i < itsBayesNet->getNumClasses(); i++)
00424       LINFO("%i: %s", i, itsBayesNet->getClassName(i));
00425     LFATAL("Please specify a valid object id");
00426   }
00427 }
00428 
00429 // ######################################################################
00430 PrefrontalCortexSB::~PrefrontalCortexSB()
00431 { }
00432 
00433 /* So things look consistent in everyone's emacs... */
00434 /* Local Variables: */
00435 /* indent-tabs-mode: nil */
00436 /* End: */
Generated on Sun May 8 08:05:25 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3