00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
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
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
00101 if (param == &itsType) {
00102
00103 removeSubComponent(*itsPFC);
00104
00105
00106
00107
00108 if (itsType.getVal().compare("Stub") == 0)
00109 itsPFC.reset(new PrefrontalCortexStub(getManager()));
00110 else if (itsType.getVal().compare("OG") == 0)
00111 itsPFC.reset(new PrefrontalCortexOG(getManager()));
00112 else if (itsType.getVal().compare("GS") == 0)
00113 itsPFC.reset(new PrefrontalCortexGS(getManager()));
00114 else if (itsType.getVal().compare("SB") == 0)
00115 itsPFC.reset(new PrefrontalCortexSB(getManager()));
00116 else
00117 LFATAL("Unknown PrefrontalCortex type %s", itsType.getVal().c_str());
00118
00119
00120
00121
00122
00123 addSubComponent(itsPFC);
00124
00125
00126 itsPFC->exportOptions(MC_RECURSE);
00127
00128
00129 LINFO("Selected PFC of type %s", itsType.getVal().c_str());
00130 }
00131 }
00132
00133
00134
00135
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
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
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
00238
00239
00240
00241
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
00250 if (objData.objmask.initialized())
00251 {
00252 LINFO("Drawing target mask from B/W mask file data...");
00253 itsTargetMask += objData.objmask;
00254 }
00255
00256
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
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
00295
00296 }
00297
00298
00299 PrefrontalCortexOG::~PrefrontalCortexOG()
00300 { }
00301
00302
00303
00304
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
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
00345 rutz::shared_ptr<ParamMap> pmap = ParamMap::loadPmapFile(itsFilename.getVal());
00346
00347
00348 rutz::shared_ptr<SimReqVCXchanVis> ev(new SimReqGSbias(this, pmap));
00349 q.request(ev);
00350 }
00351
00352
00353
00354
00355
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
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));
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
00413 rutz::shared_ptr<SimEventObjectToBias>
00414 eotb(new SimEventObjectToBias(this, oname));
00415 q.post(eotb);
00416
00417
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
00434
00435
00436