TaskRelevanceMap.C

Go to the documentation of this file.
00001 /*!@file Neuro/TaskRelevanceMap.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/TaskRelevanceMap.C $
00035 // $Id: TaskRelevanceMap.C 14390 2011-01-13 20:17:22Z pez $
00036 //
00037 
00038 #include "Neuro/TaskRelevanceMap.H"
00039 
00040 #include "Channels/ChannelOpts.H" // for OPT_LevelSpec
00041 #include "Channels/InputFrame.H"
00042 #include "Component/OptionManager.H"
00043 #include "Image/Image.H"
00044 #include "Image/MathOps.H"   // for absDiff()
00045 #include "Image/ShapeOps.H"  // for rescale(), downSize()
00046 #include "Image/CutPaste.H"   // for concatX()
00047 #include "Image/Transforms.H"
00048 #include "Image/DrawOps.H" // for drawFilledPolygon()
00049 #include "Image/MathOps.H"
00050 #include "Image/MatrixOps.H"
00051 #include "Neuro/NeuroOpts.H"
00052 #include "Neuro/NeuroSimEvents.H"
00053 #include "Neuro/SaccadeController.H"
00054 #include "Raster/Raster.H"
00055 #include "Simulation/SimEventQueue.H"
00056 #include "Transport/FrameInfo.H"
00057 #include "Transport/FrameOstream.H"
00058 #include "Util/Types.H"
00059 #include "Util/log.H"
00060 #include "Util/StringConversions.H"
00061 #include "Util/StringUtil.H" // for toLowerCase()
00062 
00063 #include "Simulation/SimEventQueueConfigurator.H"
00064 #include "Neuro/GistEstimator.H"
00065 #include "Neuro/gistParams.H"
00066 #include "GUI/XWinManaged.H"
00067 #include <vector>
00068 
00069 #include <cstdio>
00070 
00071 #define PI 3.141592
00072 
00073 // ######################################################################
00074 // ######################################################################
00075 // ########## TaskRelevanceMap implementation
00076 // ######################################################################
00077 // ######################################################################
00078 
00079 TaskRelevanceMap::TaskRelevanceMap(OptionManager& mgr,
00080                                    const std::string& descrName,
00081                                    const std::string& tagName) :
00082   SimModule(mgr, descrName, tagName)
00083 { }
00084 
00085 // ######################################################################
00086 TaskRelevanceMap::~TaskRelevanceMap()
00087 { }
00088 
00089 // ######################################################################
00090 // ######################################################################
00091 // ########## TaskRelevanceMapConfigurator implementation
00092 // ######################################################################
00093 // ######################################################################
00094 TaskRelevanceMapConfigurator::
00095 TaskRelevanceMapConfigurator(OptionManager& mgr,
00096                              const std::string& descrName,
00097                              const std::string& tagName) :
00098   ModelComponent(mgr, descrName, tagName),
00099   itsTRMtype(&OPT_TaskRelevanceMapType, this),
00100   itsTRM(new TaskRelevanceMapStub(mgr))
00101 {
00102   addSubComponent(itsTRM);
00103 }
00104 
00105 // ######################################################################
00106 TaskRelevanceMapConfigurator::~TaskRelevanceMapConfigurator()
00107 {  }
00108 
00109 // ######################################################################
00110 nub::ref<TaskRelevanceMap> TaskRelevanceMapConfigurator::getTRM() const
00111 { return itsTRM; }
00112 
00113 // ######################################################################
00114 void TaskRelevanceMapConfigurator::
00115 paramChanged(ModelParamBase* const param,
00116              const bool valueChanged,
00117              ParamClient::ChangeStatus* status)
00118 {
00119   ModelComponent::paramChanged(param, valueChanged, status);
00120 
00121   // was that a change of our baby's name?
00122   if (param == &itsTRMtype) {
00123     // if we had one, let's unregister it (when we later reset() the
00124     // nub::ref, the current TaskRelevanceMap will unexport its
00125     // command-line options):
00126     removeSubComponent(*itsTRM);
00127 
00128     // instantiate a SM of the appropriate type:
00129     if (itsTRMtype.getVal().compare("None") == 0 ||
00130         itsTRMtype.getVal().compare("Stub") == 0) // no TRM
00131       itsTRM.reset(new TaskRelevanceMapStub(getManager()));
00132     else if (itsTRMtype.getVal().compare("Std") == 0)          // standard
00133       itsTRM.reset(new TaskRelevanceMapStd(getManager()));
00134     else if (itsTRMtype.getVal().compare("KillStatic") == 0)   // kill-static
00135       itsTRM.reset(new TaskRelevanceMapKillStatic(getManager()));
00136     else if (itsTRMtype.getVal().compare("KillN") == 0)        // kill-n
00137       itsTRM.reset(new TaskRelevanceMapKillN(getManager()));
00138     else if (itsTRMtype.getVal().compare("GistClassify") == 0) // gist-classify
00139       itsTRM.reset(new TaskRelevanceMapGistClassify(getManager()));
00140     else if (itsTRMtype.getVal().compare("Tigs") == 0) // Tigs
00141       itsTRM.reset(new TaskRelevanceMapTigs(getManager()));
00142     else if (itsTRMtype.getVal().compare("Tigs2") == 0) // Tigs(gist and pca image)
00143       itsTRM.reset(new TaskRelevanceMapTigs2(getManager()));
00144     else if (itsTRMtype.getVal().compare("Social") == 0) // Social(requires XML of data)
00145       itsTRM.reset(new TaskRelevanceMapSocial(getManager()));
00146     else
00147       LFATAL("Unknown TRM type %s", itsTRMtype.getVal().c_str());
00148 
00149     // add our baby as a subcomponent of us so that it will become
00150     // linked to the manager through us (hopefully we are registered
00151     // with the manager), which in turn will allow it to export its
00152     // command-line options and get configured:
00153 
00154     addSubComponent(itsTRM);
00155 
00156     // tell the controller to export its options:
00157     itsTRM->exportOptions(MC_RECURSE);
00158 
00159     // some info message:
00160     LINFO("Selected TRM of type %s", itsTRMtype.getVal().c_str());
00161   }
00162 }
00163 
00164 
00165 // ######################################################################
00166 // ######################################################################
00167 // ########## TaskRelevanceMapStub implementation
00168 // ######################################################################
00169 // ######################################################################
00170 
00171 // ######################################################################
00172 TaskRelevanceMapStub::TaskRelevanceMapStub(OptionManager& mgr,
00173                                            const std::string& descrName,
00174                                            const std::string& tagName) :
00175   TaskRelevanceMap(mgr, descrName, tagName)
00176 { }
00177 
00178 // ######################################################################
00179 TaskRelevanceMapStub::~TaskRelevanceMapStub()
00180 { }
00181 
00182 
00183 // ######################################################################
00184 // ######################################################################
00185 // ########## TaskRelevanceMapAdapter implementation
00186 // ######################################################################
00187 // ######################################################################
00188 TaskRelevanceMapAdapter::
00189 TaskRelevanceMapAdapter(OptionManager& mgr,
00190                         const std::string& descrName,
00191                         const std::string& tagName) :
00192   TaskRelevanceMap(mgr, descrName, tagName),
00193   SIMCALLBACK_INIT(SimEventRetinaImage),
00194   SIMCALLBACK_INIT(SimEventSaccadeStatusEye),
00195   SIMCALLBACK_INIT(SimEventClockTick),
00196   SIMCALLBACK_INIT(SimEventSaveOutput),
00197   itsLevelSpec(&OPT_LevelSpec, this), //Channels/ChannelOpts.{H,C}
00198   itsSaveResults(&OPT_TRMsaveResults, this) // see Neuro/NeuroOpts.{H,C}
00199 { }
00200 
00201 // ######################################################################
00202 TaskRelevanceMapAdapter::~TaskRelevanceMapAdapter()
00203 { }
00204 
00205 // ######################################################################
00206 void TaskRelevanceMapAdapter::reset1()
00207 { itsMap.freeMem(); }
00208 
00209 // ######################################################################
00210 void TaskRelevanceMapAdapter::
00211 onSimEventRetinaImage(SimEventQueue& q, rutz::shared_ptr<SimEventRetinaImage>& e)
00212 {
00213   const Dims d = e->frame().colorByte().getDims();
00214   const int sml = itsLevelSpec.getVal().mapLevel();
00215 
00216   const Dims mapdims(d.w() >> sml, d.h() >> sml);
00217 
00218   // great, here is a new input image. Initialize our map if needed:
00219   if (itsMap.getDims() != mapdims)
00220     {
00221       itsMap.resize(mapdims,true);
00222       itsMap.clear(1.0F); // neutral relevance
00223     }
00224 
00225   // now do any implementation-specific processing:
00226   this->inputFrame(e->frame());
00227 }
00228 
00229 // ######################################################################
00230 void TaskRelevanceMapAdapter::
00231 onSimEventSaccadeStatusEye(SimEventQueue& q, rutz::shared_ptr<SimEventSaccadeStatusEye>& e)
00232 {
00233   if (e->saccadeStatus() == TSTATUS_BEGIN) this->saccadicSuppression(true);
00234   else if (e->saccadeStatus() == TSTATUS_END) this->saccadicSuppression(false);
00235 }
00236 
00237 // ######################################################################
00238 void TaskRelevanceMapAdapter::
00239 onSimEventClockTick(SimEventQueue& q, rutz::shared_ptr<SimEventClockTick>& e)
00240 {
00241   // evolve one time step:
00242   this->integrate(q);
00243 
00244   // all right, post our current internals if we have any:
00245   if (itsMap.initialized())
00246     {
00247       rutz::shared_ptr<SimEventTaskRelevanceMapOutput>
00248         etrm(new SimEventTaskRelevanceMapOutput(this, itsMap));
00249       q.post(etrm);
00250     }
00251 }
00252 
00253 // ######################################################################
00254 void TaskRelevanceMapAdapter::
00255 onSimEventSaveOutput(SimEventQueue& q, rutz::shared_ptr<SimEventSaveOutput>& e)
00256 {
00257   this->save1(e->sinfo());
00258 }
00259 
00260 // ######################################################################
00261 void TaskRelevanceMapAdapter::save1(const ModelComponentSaveInfo& sinfo)
00262 {
00263   if (itsSaveResults.getVal())
00264     {
00265       // get the OFS to save to, assuming sinfo is of type
00266       // SimModuleSaveInfo (will throw a fatal exception otherwise):
00267       nub::ref<FrameOstream> ofs =
00268         dynamic_cast<const SimModuleSaveInfo&>(sinfo).ofs;
00269 
00270       ofs->writeFloat(itsMap, FLOAT_NORM_PRESERVE, "TRM",
00271                       FrameInfo("task relevance map (top-down)", SRC_POS));
00272     }
00273 }
00274 
00275 // ######################################################################
00276 // ######################################################################
00277 // ########## TaskRelevanceMapStd implementation
00278 // ######################################################################
00279 // ######################################################################
00280 
00281 // ######################################################################
00282 TaskRelevanceMapStd::
00283 TaskRelevanceMapStd(OptionManager& mgr, const std::string& descrName,
00284                     const std::string& tagName) :
00285   TaskRelevanceMapAdapter(mgr, descrName, tagName),
00286   itsLearnTRM(&OPT_LearnTRM, this),
00287   itsLearnUpdateTRM(&OPT_LearnUpdateTRM, this),
00288   itsBiasTRM(&OPT_BiasTRM, this)
00289 { }
00290 
00291 // ######################################################################
00292 TaskRelevanceMapStd::~TaskRelevanceMapStd()
00293 { }
00294 
00295 // ######################################################################
00296 void TaskRelevanceMapStd::inputFrame(const InputFrame& f)
00297 { }
00298 
00299 /*FIXME
00300 void TaskRelevanceMapStd::input(const Image<float>& current)
00301 {
00302   itsMap = current;
00303   const Dims d = itsMap.getDims();
00304 
00305   // bias TRM if the option is specified
00306   if (strcmp(itsBiasTRM.getValString().c_str(), "") != 0)
00307     {
00308       LINFO("biasing TRM with %s", itsBiasTRM.getValString().c_str());
00309       const Image<float> newtrm =
00310         Raster::ReadGray(itsBiasTRM.getValString());
00311       itsMap = rescale(newtrm * (1.0F/255.0F), d);
00312     }
00313 }
00314 */
00315 
00316 // ######################################################################
00317 void TaskRelevanceMapStd::saccadicSuppression(const bool on)
00318 { }
00319 
00320 // ######################################################################
00321 void TaskRelevanceMapStd::integrate(SimEventQueue& q)
00322 { }
00323 
00324 /*FIXME
00325 void TaskRelevanceMapStd::update(const Point2D<int>& fixation,
00326                                  const Image<byte>& objectMask,
00327                                  const Dims& inputDims,
00328                                  const float relevance)
00329 {
00330   // get the object shape:
00331   Point2D<int> fixn;
00332   fixn.i = fixation.i * itsMap.getWidth() / inputDims.w();
00333   fixn.j = fixation.j * itsMap.getHeight() / inputDims.h();
00334   if ( ! objectMask.initialized())
00335     { LERROR("object mask not initialized!"); return; }
00336   Image<byte> fmask = rescale(objectMask, itsMap.getDims());
00337   Point2D<int> p;
00338 
00339   //FIXME: this should be an Image function
00340   // update relevance only within object
00341   for (p.i = 0; p.i < itsMap.getWidth(); p.i ++)
00342     for (p.j = 0; p.j < itsMap.getHeight(); p.j ++)
00343       if (fmask.getVal(p) == 255)
00344         {
00345           if (relevance == 0.0f) itsMap.setVal(p, itsMap.getVal(p) - 1.0f);
00346           else itsMap.setVal(p, itsMap.getVal(p) + relevance);
00347         }
00348 
00349   if (itsLearnTRM.getVal() == false)
00350     {
00351       // biasing mode / updating mode / none:
00352       // set min to 0 else normalizing will clear the entire TRM
00353       float min, max; getMinMax(itsMap, min, max);
00354       if (min > 0.0f) itsMap.setVal(0, 0, 0.0f);
00355     }
00356 
00357   // normalize TRM else AGM will explode
00358   inplaceNormalize(itsMap, 0.0f, 3.0f);
00359   LINFO("Evolved TRM with relevance = %f", relevance);
00360 }
00361 */
00362 
00363 // ######################################################################
00364 // ######################################################################
00365 // ########## TaskRelevanceMapKillStatic implementation
00366 // ######################################################################
00367 // ######################################################################
00368 
00369 // ######################################################################
00370 TaskRelevanceMapKillStatic::
00371 TaskRelevanceMapKillStatic(OptionManager& mgr,
00372                            const std::string& descrName,
00373                            const std::string& tagName) :
00374   TaskRelevanceMapAdapter(mgr, descrName, tagName),
00375   itsKillStaticThresh(&OPT_TRMKillStaticThresh, this),
00376   itsKillStaticCoeff(&OPT_TRMKillStaticCoeff, this),
00377   itsStaticBuff()
00378 { }
00379 
00380 // ######################################################################
00381 TaskRelevanceMapKillStatic::~TaskRelevanceMapKillStatic()
00382 { }
00383 
00384 // ######################################################################
00385 void TaskRelevanceMapKillStatic::reset1()
00386 {
00387   TaskRelevanceMapAdapter::reset1();
00388   itsStaticBuff.freeMem();
00389 }
00390 
00391 // ######################################################################
00392 void TaskRelevanceMapKillStatic::inputFrame(const InputFrame& f)
00393 {
00394   // NOTE: we are guaranteed that itsMap is initialized and of correct
00395   // size, as this is done by the TaskRelevanceMapAdapter before
00396   // calling us.
00397 
00398   // NOTE: this is duplicating some of the computation done in the
00399   // IntensityChannel, so there is a tiny performance hit (~0.25%) in
00400   // doing this operation twice; however the benefit is that we avoid
00401   // having to somehow pick information out of an IntensityChannel and
00402   // pass it to a TaskRelevanceMap -- that was making for a mess in
00403   // Brain. In the future, we could avoid the ineffiency by caching
00404   // the intensity pyramid in the InputFrame object, and then letting
00405   // IntensityChannel and TaskRelevanceMap both share access to that
00406   // pyramid.
00407   const Image<float> img =
00408     downSize(f.grayFloat(), itsMap.getWidth(), itsMap.getHeight(), 5);
00409 
00410   // is this our first time here?
00411   if (itsStaticBuff.initialized() == false)
00412     { itsStaticBuff = img; return; }
00413 
00414   // otherwise derive TRM from difference between current frame and
00415   // staticBuf:
00416   Image<float> diff = absDiff(itsStaticBuff, img);
00417 
00418   // useful range of diff is 0..255; anything giving an output less
00419   // that itsKillStaticThresh will be considered static; here let's
00420   // clamp to isolate that:
00421   inplaceClamp(diff, 0.0F, itsKillStaticThresh.getVal());
00422 
00423   // the more static, the greater the killing: so, first let's change
00424   // the range so that the min is at -itsKillStaticThresh and zero is
00425   // neutral:
00426   diff -= itsKillStaticThresh.getVal();
00427 
00428   // itsKillStaticCoeff determines how strong the killing should be:
00429   diff *= (1.0F / itsKillStaticThresh.getVal()) * // normalize to min at -1.0
00430     itsKillStaticCoeff.getVal();                  // apply coeff
00431 
00432   // mix our new TRM to the old one; we want to have a fairly high
00433   // mixing coeff for the new one so that we don't penalize recent
00434   // onset objects too much (i.e., were previously static and killed,
00435   // but are not anymore):
00436   itsMap = itsMap * 0.25F + (diff + 1.0F) * 0.75F;
00437   float mi, ma; getMinMax(itsMap, mi, ma);
00438   LINFO("TRM range = [%.2f .. %.2f] -- 1.0 is baseline", mi, ma);
00439 
00440   // update our cumulative buffer:
00441   itsStaticBuff = itsStaticBuff * 0.75F + img * 0.25F;
00442 
00443 }
00444 
00445 // ######################################################################
00446 void TaskRelevanceMapKillStatic::saccadicSuppression(const bool on)
00447 {
00448   // a saccade resets our cumulative buffer:
00449   itsStaticBuff.freeMem();
00450 }
00451 
00452 // ######################################################################
00453 void TaskRelevanceMapKillStatic::integrate(SimEventQueue& q)
00454 { }
00455 
00456 // ######################################################################
00457 void TaskRelevanceMapKillStatic::save1(const ModelComponentSaveInfo& sinfo)
00458 {
00459   TaskRelevanceMapAdapter::save1(sinfo);
00460 
00461   if (itsSaveResults.getVal())
00462     {
00463       // get the OFS to save to, assuming sinfo is of type
00464       // SimModuleSaveInfo (will throw a fatal exception otherwise):
00465       nub::ref<FrameOstream> ofs =
00466         dynamic_cast<const SimModuleSaveInfo&>(sinfo).ofs;
00467 
00468       ofs->writeFloat(itsStaticBuff, FLOAT_NORM_0_255, "TRM-SB",
00469                       FrameInfo("task relevance map static buffer", SRC_POS));
00470     }
00471 }
00472 
00473 
00474 // ######################################################################
00475 // ######################################################################
00476 // ########## TaskRelevanceMapKillN implementation
00477 // ######################################################################
00478 // ######################################################################
00479 
00480 // ######################################################################
00481 TaskRelevanceMapKillN::
00482 TaskRelevanceMapKillN(OptionManager& mgr, const std::string& descrName,
00483                       const std::string& tagName) :
00484   TaskRelevanceMapAdapter(mgr, descrName, tagName),
00485   itsN(&OPT_TRMkillN, this), itsCache()
00486 { }
00487 
00488 // ######################################################################
00489 TaskRelevanceMapKillN::~TaskRelevanceMapKillN()
00490 { }
00491 
00492 // ######################################################################
00493 void TaskRelevanceMapKillN::reset1()
00494 {
00495   TaskRelevanceMapAdapter::reset1();
00496   itsCache.clear();
00497 }
00498 
00499 // ######################################################################
00500 void TaskRelevanceMapKillN::start1()
00501 {
00502   itsCache.setMaxSize(itsN.getVal());
00503 
00504   TaskRelevanceMapAdapter::start1();
00505 }
00506 
00507 // ######################################################################
00508 void TaskRelevanceMapKillN::inputFrame(const InputFrame& f)
00509 { }
00510 
00511 // ######################################################################
00512 void TaskRelevanceMapKillN::integrate(SimEventQueue& q)
00513 {
00514   // anything from the ShapeEstimator?
00515   if (SeC<SimEventShapeEstimatorOutput> e =
00516       q.check<SimEventShapeEstimatorOutput>(this))
00517     {
00518       // get the smooth object mask:
00519       Image<float> mask = e->smoothMask();
00520 
00521       // downscale to our map's size:
00522       mask = downSize(mask, itsMap.getWidth(), itsMap.getHeight(), 5);
00523 
00524       // is the mask uniform (i.e., empty)?  In this case, just push
00525       // it in, otherwise let's segment the objects out:
00526       float mi, ma; getMinMax(mask, mi, ma);
00527       if (fabs(mi - ma) < 1.0e-10)
00528         itsCache.push_back(mask);
00529       else
00530         {
00531           // let's build a distance map out of the object and threhold it:
00532           Image<float> dmap = chamfer34(mask, 255.0F);
00533           inplaceClamp(dmap, 0.0F, 15.0F);
00534           dmap /= 15.0F;  // 0 inside obj, 1 outside
00535 
00536           // get this new input mask into our cache:
00537           itsCache.push_back(dmap);
00538         }
00539 
00540       // our current relevance map is the min over our cache:
00541       itsMap = itsCache.getMin();
00542     }
00543 }
00544 
00545 // ######################################################################
00546 void TaskRelevanceMapKillN::saccadicSuppression(const bool on)
00547 { }
00548 
00549 // ######################################################################
00550 // ######################################################################
00551 // ########## TaskRelevanceMapGistClassify implementation
00552 // ######################################################################
00553 // ######################################################################
00554 // ######################################################################
00555 TaskRelevanceMapGistClassify::
00556 TaskRelevanceMapGistClassify(OptionManager& mgr, const std::string& descrName,
00557                       const std::string& tagName) :
00558   TaskRelevanceMapAdapter(mgr, descrName, tagName),
00559   itsClusterCenterFileName(&OPT_TRMClusterCenterFile, this),
00560   itsTemplateDir(&OPT_TRMTemplateDir, this),
00561   itsPCADims(&OPT_TRMGistPCADims, this),
00562   itsPCAMatrixName(&OPT_TRMGistPCAMatrix, this),
00563   itsCacheSize(&OPT_TRMCacheSize, this),
00564   itsUpdatePeriod(&OPT_TRMUpdatePeriod, this),
00565   itsMapComputedForCurrentFrame(false),
00566   itsTDMap()
00567 {
00568   itsFrame = -1;
00569   itsTDMap.setMaxSize(itsCacheSize.getVal());
00570 }
00571 
00572 // ######################################################################
00573 TaskRelevanceMapGistClassify::~TaskRelevanceMapGistClassify()
00574 { }
00575 
00576 // ######################################################################
00577 void TaskRelevanceMapGistClassify::reset1()
00578 {
00579   TaskRelevanceMapAdapter::reset1();
00580 }
00581 
00582 // ######################################################################
00583 void TaskRelevanceMapGistClassify::inputFrame(const InputFrame& f)
00584 {
00585   getPCAMatrix();
00586   itsFrame++;
00587   itsMapComputedForCurrentFrame = false;
00588 }
00589 
00590 // ######################################################################
00591 void TaskRelevanceMapGistClassify::integrate(SimEventQueue& q)
00592 {
00593   if (SeC<SimEventGistOutput> e =
00594       q.check<SimEventGistOutput>(this))
00595     {
00596       if (itsMapComputedForCurrentFrame)
00597         return;
00598 
00599       //! to make the gist feature value in a reasonable range to get the
00600       //  variance and determine value
00601       itsGist = e->gv() / 10.0F;
00602 
00603       gistmatch(reshape(itsGist,
00604                         Dims(itsGist.getWidth() * itsGist.getHeight(), 1)));
00605 
00606       if (itsCacheSize.getVal() > 0)
00607         {
00608           itsTDMap.push_back(itsTmpTDMap);
00609           if (itsFrame % itsUpdatePeriod.getVal() ==0)
00610             itsCurrentTDMap = itsTDMap.mean();
00611         }
00612       else
00613         itsCurrentTDMap = itsTmpTDMap;
00614 
00615 
00616       itsMap = rescale(itsCurrentTDMap, itsMap.getDims());
00617 
00618       float mi, ma; getMinMax(itsMap, mi, ma);
00619       LINFO("\nFinal TRM range = [%.2f .. %.2f] -- 1.0 is baseline\n", mi, ma);
00620 
00621       itsMapComputedForCurrentFrame = true;
00622     }
00623 }
00624 
00625 // ######################################################################
00626 void TaskRelevanceMapGistClassify::saccadicSuppression(const bool on)
00627 { }
00628 
00629 // ######################################################################
00630 void TaskRelevanceMapGistClassify::
00631 gistmatch(Image<float> currGist)
00632 {
00633   Image<float> gistDist =   computeGistDist(currGist);
00634   itsTmpTDMap = getTDMap(gistDist);
00635 
00636 }
00637 // ######################################################################
00638 void TaskRelevanceMapGistClassify::
00639 getPCAMatrix()
00640 {
00641   FILE* itsFile = fopen(itsPCAMatrixName.getVal().c_str(), "rb");
00642   ASSERT(itsFile != 0);
00643 
00644   int gistDims = 0;
00645   if(fread(&gistDims, sizeof(int), 1, itsFile) != 1) LFATAL("fread failed");
00646 
00647   Image<float> matrixTmp(gistDims, itsPCADims.getVal(), NO_INIT);
00648   size_t sz = itsPCADims.getVal()*gistDims;
00649   if(fread(matrixTmp.beginw(), sizeof(float), sz, itsFile) != sz) LFATAL("fread failed"); 
00650 
00651   itsPCAMatrix = transpose(matrixTmp);
00652 
00653   LDEBUG("itsPCAMatrix first 5 num: %f, %f, %f, %f, %f", itsPCAMatrix.getVal(0,0),
00654         itsPCAMatrix.getVal(1,0), itsPCAMatrix.getVal(2,0),
00655         itsPCAMatrix.getVal(3,0), itsPCAMatrix.getVal(4,0));
00656 
00657   fclose(itsFile);
00658 }
00659 
00660 
00661 
00662 // ######################################################################
00663 Image<float> TaskRelevanceMapGistClassify::
00664 computeGistDist(Image<float> currGist)
00665 {
00666    FILE* itsFile = fopen(itsClusterCenterFileName.getVal().c_str(), "rb");
00667    ASSERT(itsFile != 0);
00668 
00669   if(fread(&itsNumOfCategory, sizeof(int), 1, itsFile) != 1) LFATAL("fread failed");
00670   if(fread(&itsUsedDims, sizeof(int),1,itsFile) != 1) LFATAL("fread failed");
00671   ASSERT(itsNumOfCategory > 0 && itsUsedDims == itsPCADims.getVal());
00672 
00673   LDEBUG("there are %4d categories, pca_dims: %4d",itsNumOfCategory, itsUsedDims);
00674 
00675   Image<float> currGistCut(currGist.getDims().sz()/NUM_GIST_FEAT, 1, NO_INIT);
00676   Image<float> currGistPCA(itsPCADims.getVal(), 1, NO_INIT);
00677 
00678   //! only use the whole image's gist feature to do the classification
00679   for(int i=0; i<currGistCut.getDims().sz(); i++)
00680     currGistCut.setVal(i,0, currGist.getVal(i*NUM_GIST_FEAT, 0));
00681 
00682   LDEBUG("currGistCut dim: %d, PCA matrix height: %4d",
00683         currGistCut.getWidth(), itsPCAMatrix.getHeight());
00684 
00685   ASSERT(currGistCut.getWidth() == itsPCAMatrix.getHeight());
00686 
00687   currGistPCA = matrixMult(currGistCut, itsPCAMatrix);
00688 
00689   LDEBUG("currGistPCA : %f, %f, %f", currGistPCA.getVal(0,0),
00690          currGistPCA.getVal(1,0), currGistPCA.getVal(2,0));
00691 
00692   Image<float> gistDist(itsNumOfCategory, 1,NO_INIT );
00693   Image<float> gistCenter(itsUsedDims, 1, NO_INIT);
00694   Image<float> gistCenterCovarMatrix(itsUsedDims,itsUsedDims, NO_INIT);
00695   Image<float> gistCenterCovarMatrixInv(itsUsedDims, itsUsedDims, NO_INIT);
00696   Image<float> gistDiff(itsUsedDims,1,NO_INIT);
00697 
00698   float meanClusterGistDist=0.0F;
00699   float det = 0.0F;
00700   float coef1 = pow(2*PI, itsUsedDims/2.0F);
00701   float coef2 = 0.0F, coef3=0.0F, coef4=0.0F;
00702 
00703   for(int i=0; i<itsNumOfCategory; i++)
00704     {
00705       if(fread(gistCenter.beginw(), sizeof(float), itsUsedDims, itsFile) != (size_t)itsUsedDims) LFATAL("fread failed");
00706       if(fread(&meanClusterGistDist, sizeof(float), 1, itsFile) != 1) LFATAL("fread failed");
00707       if(fread(&det, sizeof(float), 1, itsFile) != 1) LFATAL("fread failed");
00708       size_t sz = itsUsedDims*itsUsedDims;
00709       if(fread(gistCenterCovarMatrix.beginw(), sizeof(float), sz, itsFile) != sz) LFATAL("fread failed");
00710 
00711       gistCenterCovarMatrixInv = matrixInv(gistCenterCovarMatrix);
00712 
00713       gistDiff = gistCenter - currGistPCA;
00714 
00715       coef2 =1.0F /( coef1 * pow(det, 0.5)+0.0000001F );
00716 
00717       Image<float> tmp = matrixMult(matrixMult(gistDiff,  gistCenterCovarMatrixInv),
00718                                     transpose(gistDiff));
00719 
00720       coef3 = exp(-0.5F * tmp.getVal(0,0));
00721       coef4 = coef2 * coef3 / (meanClusterGistDist+0.5F);
00722 
00723       LDEBUG("%d's is %f,  %f, %f , mean is %f,sumDiff is%f\n", i+1, tmp.getVal(0,0),
00724             coef3, coef4, meanClusterGistDist, sum(gistDiff*gistDiff));
00725       gistDist.setVal(i, 0, coef4);
00726 
00727     }
00728   fclose(itsFile);
00729 
00730   return gistDist;
00731 }
00732 
00733 // ######################################################################
00734 Image<float> TaskRelevanceMapGistClassify::
00735 getTDMap(Image<float> gistDist)
00736 {
00737   std::string TDMapName;
00738   Image<float> TDMap;
00739   float coef = 0.0F;
00740 
00741   for(int i=1; i<= itsNumOfCategory; i++)
00742     {
00743       TDMapName = itsTemplateDir.getVal()+std::string("category")
00744         +convertToString(i)+std::string(".png");
00745 
00746 
00747       Image<float> TDMapTmp = Raster::ReadGray(TDMapName);
00748 
00749       if(1==i)
00750         TDMap = TDMapTmp * gistDist.getVal(i-1,0);
00751       else
00752         TDMap += TDMapTmp * gistDist.getVal(i-1,0);
00753 
00754       coef += gistDist.getVal(i-1,0);
00755     }
00756 
00757   TDMap = (TDMap + 0.0001F) / (coef + 0.0001F);
00758   // consider that failure in classify then use the uniform template
00759 
00760   float mi, ma; getMinMax(TDMap, mi, ma);
00761   LINFO("\ncoef= %.6f TRM range = [%.2f .. %.2f] -- 1.0 is baseline\n", coef, mi, ma);
00762   return TDMap;
00763 }
00764 
00765 
00766 // ######################################################################
00767 // ######################################################################
00768 // ########## TaskRelevanceMapTigs implementation
00769 // ######################################################################
00770 // ######################################################################
00771 // ######################################################################
00772 TaskRelevanceMapTigs::
00773 TaskRelevanceMapTigs(OptionManager& mgr, const std::string& descrName,
00774                       const std::string& tagName) :
00775   TaskRelevanceMapAdapter(mgr, descrName, tagName),
00776   itsTigsMatrixName(&OPT_TRMTigsMatrix, this),
00777   itsPCADims(&OPT_TRMGistPCADims, this),
00778   itsPCAMatrixName(&OPT_TRMGistPCAMatrix, this),
00779   itsCacheSize(&OPT_TRMCacheSize, this),
00780   itsUpdatePeriod(&OPT_TRMUpdatePeriod, this),
00781   itsMapComputedForCurrentFrame(false),
00782   itsTDMap()
00783 {
00784   itsFrame = -1;
00785   itsTDMap.setMaxSize(itsCacheSize.getVal());
00786   getPCAMatrix();
00787   getTigsMatrix();
00788   itsPCADims.setVal(5);  // fixed to 5 now
00789 }
00790 
00791 // ######################################################################
00792 TaskRelevanceMapTigs::~TaskRelevanceMapTigs()
00793 { }
00794 
00795 // ######################################################################
00796 void TaskRelevanceMapTigs::reset1()
00797 {
00798   TaskRelevanceMapAdapter::reset1();
00799 }
00800 
00801 // ######################################################################
00802 void TaskRelevanceMapTigs::inputFrame(const InputFrame& f)
00803 {
00804   itsFrame++;
00805   itsMapComputedForCurrentFrame = false;
00806 }
00807 
00808 // ######################################################################
00809 void TaskRelevanceMapTigs::getPCAMatrix()
00810 {
00811   FILE* itsFile = fopen(itsPCAMatrixName.getVal().c_str(), "rb");
00812   if(itsFile == 0)
00813     PLFATAL("Can not open PCAMatrix for read PCA");
00814   int gistDims = 0;
00815   if(fread(&gistDims, sizeof(int), 1, itsFile) != 1) LFATAL("fread failed");
00816 
00817   Image<float> matrixTmp(gistDims, itsPCADims.getVal(), NO_INIT);
00818   size_t sz = itsPCADims.getVal()*gistDims;
00819   if(fread(matrixTmp.beginw(), sizeof(float), sz, itsFile) != sz) LFATAL("fread failed");
00820 
00821   itsPCAMatrix = transpose(matrixTmp);
00822 
00823   fclose(itsFile);
00824 }
00825 
00826 // ######################################################################
00827 void TaskRelevanceMapTigs::getTigsMatrix()
00828 {
00829   FILE* itsFile = fopen(itsTigsMatrixName.getVal().c_str(),
00830                         "rb");
00831   if(itsFile == 0)
00832     PLFATAL("Can not open TigsMatrix for read Tigs coefficients");
00833   int w,h;
00834   if(fread(&h, sizeof(int), 1, itsFile) != 1) LFATAL("fread failed"); 
00835   if(fread(&w, sizeof(int), 1, itsFile) != 1) LFATAL("fread failed");
00836 
00837   Image<float> matrixTmp(h, w, NO_INIT);
00838   // keep in mind that the definition of Image is Image(width, height)
00839   if(fread(matrixTmp.beginw(), sizeof(float), w*h, itsFile) != size_t(w*h)) LFATAL("fread failed");
00840 
00841   itsTigsMatrix = transpose(matrixTmp);
00842   fclose(itsFile);
00843 }
00844 
00845 // ######################################################################
00846 void TaskRelevanceMapTigs::integrate(SimEventQueue& q)
00847 {
00848   if (SeC<SimEventGistOutput> e =
00849       q.check<SimEventGistOutput>(this))
00850     {
00851       if (itsMapComputedForCurrentFrame)
00852         return;
00853 
00854       itsGist = e->gv();
00855       itsTmpTDMap = getTDMap(itsGist);
00856 
00857       if (itsCacheSize.getVal() > 0)
00858         {
00859           itsTDMap.push_back(itsTmpTDMap);
00860           if (itsFrame % itsUpdatePeriod.getVal() ==0)
00861             itsCurrentTDMap = itsTDMap.mean();
00862         }
00863       else
00864         itsCurrentTDMap = itsTmpTDMap;
00865 
00866 
00867       itsMap = rescale(itsCurrentTDMap, itsMap.getDims());
00868 
00869       float mi, ma; getMinMax(itsMap, mi, ma);
00870       LINFO("\nFinal TRM range = [%.2f .. %.2f] -- 1.0 is baseline\n\n", mi, ma);
00871 
00872       itsMapComputedForCurrentFrame = true;
00873     }
00874 }
00875 
00876 // ######################################################################
00877 void TaskRelevanceMapTigs::saccadicSuppression(const bool on)
00878 { }
00879 
00880 // ######################################################################
00881 Image<float> TaskRelevanceMapTigs::
00882 getTDMap(Image<float> currGist)
00883 {
00884   Image<float> currGistCut(34,1,NO_INIT);
00885   Image<float> currGistPCA(itsPCADims.getVal(), 1, NO_INIT);
00886   Image<float> tmp(300,1, NO_INIT); //300=20x15 (Rob's cvpr 2007 paper, 32x32 for 1 block)
00887   Image<float> tmp2;
00888 
00889   for(int i=0; i<34; i++)
00890     {
00891       currGistCut.setVal(i, 0, currGist.getVal(i*NUM_GIST_FEAT) );
00892     }
00893   currGistPCA = matrixMult(currGistCut, itsPCAMatrix);
00894 
00895   tmp =  matrixMult(currGistPCA, itsTigsMatrix);
00896   tmp2 = decode(tmp); // tranfer the 20x15 dims vector to an image
00897 
00898   return tmp2;
00899 }
00900 
00901 // ######################################################################
00902 Image<float> TaskRelevanceMapTigs:: decode(Image<float> inputVec)
00903 {
00904   const int w = 20;
00905   const int h = 15;
00906   Image<float> smallTDMap(w,h,NO_INIT);
00907   Image<float> bigTDMap;
00908 
00909   for(int i = 0; i< h; i++)
00910     {
00911       for(int j = 0; j < w; j++)
00912         {
00913           smallTDMap.setVal(j,i,inputVec.getVal(i*w+j,0) );
00914         }
00915     }
00916   inplaceNormalize(smallTDMap, 1.0F, 255.0F);
00917   bigTDMap = rescale(smallTDMap,itsMap.getDims());
00918 
00919   return bigTDMap;
00920 }
00921 
00922 // ######################################################################
00923 void TaskRelevanceMapTigs::save1(const ModelComponentSaveInfo& sinfo)
00924 {
00925   if (itsSaveResults.getVal())
00926     {
00927       // get the OFS to save to, assuming sinfo is of type
00928       // SimModuleSaveInfo (will throw a fatal exception otherwise):
00929       nub::ref<FrameOstream> ofs =
00930         dynamic_cast<const SimModuleSaveInfo&>(sinfo).ofs;
00931 
00932       ofs->writeFloat(itsCurrentTDMap, FLOAT_NORM_0_255, "TRM-SB",
00933                       FrameInfo("task relevance map static buffer", SRC_POS));
00934     }
00935 }
00936 
00937 // ######################################################################
00938 // ######################################################################
00939 // ########## TaskRelevanceMapTigs2 implementation
00940 // ######################################################################
00941 // ######################################################################
00942 // ######################################################################
00943 // for the training part see /lab/tmpib/u/gist-trm/trainging/Tigs2
00944 TaskRelevanceMapTigs2::
00945 TaskRelevanceMapTigs2(OptionManager& mgr, const std::string& descrName,
00946                       const std::string& tagName) :
00947   TaskRelevanceMapAdapter(mgr, descrName, tagName),
00948   itsTigsMatrixName(&OPT_TRMTigs2Matrix, this),
00949   itsGistPCADims(&OPT_TRMGistPCADims, this),
00950   itsImgPCADims(&OPT_TRMImgPCADims, this),
00951   itsGistPCAMatrixName(&OPT_TRMGistPCAMatrix, this),
00952   itsImgPCAMatrixName(&OPT_TRMImgPCAMatrix, this),
00953   itsCacheSize(&OPT_TRMCacheSize, this),
00954   itsUpdatePeriod(&OPT_TRMUpdatePeriod, this),
00955   itsMapComputedForCurrentFrame(false),
00956   itsTDMap()
00957 {
00958   itsFrame = -1;
00959   itsTDMap.setMaxSize(itsCacheSize.getVal());
00960   itsGistPCADims.setVal(5); // fixed to 5 now
00961   itsImgPCADims.setVal(20); // fixed to 20 now
00962 }
00963 
00964 // ######################################################################
00965 TaskRelevanceMapTigs2::~TaskRelevanceMapTigs2()
00966 { }
00967 
00968 // ######################################################################
00969 void TaskRelevanceMapTigs2::reset1()
00970 {
00971   TaskRelevanceMapAdapter::reset1();
00972 }
00973 
00974 // ######################################################################
00975 void TaskRelevanceMapTigs2::inputFrame(const InputFrame& f)
00976 {
00977   getGistPCAMatrix();
00978   getImgPCAMatrix();
00979   getTigsMatrix();
00980   itsFrame++;
00981 
00982   Image<float> currFrame = rescale(f.grayFloat(),f.getDims()/16, RESCALE_SIMPLE_NOINTERP);
00983   itsCurrFrameVec = reshape
00984     (transpose(currFrame/255.0F), Dims(currFrame.getWidth()*currFrame.getHeight(),1));
00985 
00986   itsMapComputedForCurrentFrame = false;
00987 }
00988 
00989 // ######################################################################
00990 void TaskRelevanceMapTigs2::getGistPCAMatrix()
00991 {
00992   FILE* itsFile = fopen(itsGistPCAMatrixName.getVal().c_str(), "rb");
00993   if(itsFile == 0)
00994     PLFATAL("Can not open GistPCAMatrix for read PCA");
00995 
00996   int gistDims = 0;
00997   if(fread(&gistDims, sizeof(int), 1, itsFile) != 1) LFATAL("fread failed");
00998 
00999   Image<float> matrixTmp(gistDims, itsGistPCADims.getVal(), NO_INIT);
01000   size_t sz = itsGistPCADims.getVal()*gistDims;
01001   if(fread(matrixTmp.beginw(), sizeof(float), sz, itsFile) != sz) LFATAL("fread failed");
01002   itsGistPCAMatrix = transpose(matrixTmp);
01003 
01004   fclose(itsFile);
01005 }
01006 
01007 // ######################################################################
01008 void TaskRelevanceMapTigs2::getImgPCAMatrix()
01009 {
01010   FILE* itsFile = fopen(itsImgPCAMatrixName.getVal().c_str(), "rb");
01011   if(itsFile == 0)
01012     PLFATAL("Can not open ImgPCAMatrix for read PCA");
01013   int imgDims = 0;
01014   if(fread(&imgDims, sizeof(int), 1, itsFile) != 1) LFATAL("fread failed");
01015 
01016   Image<float> matrixTmp(imgDims, itsImgPCADims.getVal(), NO_INIT);
01017   size_t sz = itsImgPCADims.getVal()*imgDims;
01018   if(fread(matrixTmp.beginw(), sizeof(float), sz, itsFile) != sz) LFATAL("fread failed");
01019 
01020   itsImgPCAMatrix = transpose(matrixTmp);
01021 
01022   fclose(itsFile);
01023 }
01024 
01025 // ######################################################################
01026 void TaskRelevanceMapTigs2::getTigsMatrix()
01027 {
01028   FILE* itsFile = fopen(itsTigsMatrixName.getVal().c_str(), "rb");
01029   if(itsFile == 0)
01030     PLFATAL("Can not open TigsMatrix for read Tigs coefficients");
01031 
01032   int w,h;
01033   if(fread(&h, sizeof(int), 1, itsFile) != 1) LFATAL("fread failed");
01034   if(fread(&w, sizeof(int), 1, itsFile) != 1) LFATAL("fread failed");
01035 
01036   Image<float> matrixTmp(h, w, NO_INIT);
01037   // keep in mind that the definition of Image is Image(width, height)
01038   if(fread(matrixTmp.beginw(), sizeof(float), w*h, itsFile) != size_t(w*h)) LFATAL("fread failed");
01039 
01040   itsTigsMatrix = transpose(matrixTmp);
01041 
01042   fclose(itsFile);
01043 }
01044 
01045 // ######################################################################
01046 void TaskRelevanceMapTigs2::integrate(SimEventQueue& q)
01047 {
01048   if (SeC<SimEventGistOutput> e =
01049       q.check<SimEventGistOutput>(this))
01050     {
01051       if (itsMapComputedForCurrentFrame)
01052         return;
01053 
01054       itsGist = e->gv();
01055 
01056       itsTmpTDMap = getTDMap(itsGist/10.0F); // for consistent with the training
01057 
01058       if (itsCacheSize.getVal() > 0)
01059         {
01060           itsTDMap.push_back(itsTmpTDMap);
01061           if (itsFrame % itsUpdatePeriod.getVal() ==0)
01062             itsCurrentTDMap = itsTDMap.mean();
01063         }
01064       else
01065         itsCurrentTDMap = itsTmpTDMap;
01066 
01067 
01068       itsMap = rescale(itsCurrentTDMap, itsMap.getDims());
01069 
01070       float mi, ma; getMinMax(itsMap, mi, ma);
01071       LINFO("\nFinal TRM range = [%.2f .. %.2f] -- 1.0 is baseline\n\n", mi, ma);
01072 
01073       itsMapComputedForCurrentFrame = true;
01074     }
01075 }
01076 
01077 // ######################################################################
01078 void TaskRelevanceMapTigs2::saccadicSuppression(const bool on)
01079 { }
01080 
01081 // ######################################################################
01082 Image<float> TaskRelevanceMapTigs2::
01083 getTDMap(Image<float> currGist)
01084 {
01085   Image<float> currGistCut(34,1,NO_INIT);
01086   Image<float> currGistPCA(itsGistPCADims.getVal(), 1, NO_INIT);
01087   Image<float> currImgPCA(itsImgPCADims.getVal(), 1, NO_INIT);
01088   Image<float> tmp(300,1, NO_INIT); //300=20x15 (Rob's cvpr 2007 paper, 32x32 for 1 block)
01089   Image<float> tmp2;
01090 
01091   for(int i=0; i<34; i++)
01092     {
01093       currGistCut.setVal(i, 0, currGist.getVal(i*NUM_GIST_FEAT) );
01094     }
01095   currGistPCA = matrixMult(currGistCut, itsGistPCAMatrix);
01096 
01097   currImgPCA = matrixMult(itsCurrFrameVec, itsImgPCAMatrix);
01098   LINFO("the dim of gist is %d %d, of img is %d %d \n",
01099         currGistCut.getHeight(), currGistCut.getWidth(),
01100         itsCurrFrameVec.getHeight(), itsCurrFrameVec.getWidth());
01101 
01102   Image<float> combo = concatX(currGistPCA,currImgPCA);
01103 
01104   tmp = matrixMult(combo, itsTigsMatrix);
01105 
01106   tmp2 = decode(tmp); // tranfer the 20x15 dims vector to an image
01107 
01108   return tmp2;
01109 }
01110 
01111 // ######################################################################
01112 Image<float> TaskRelevanceMapTigs2:: decode(Image<float> inputVec)
01113 {
01114   const int w = 20;
01115   const int h = 15;
01116   Image<float> smallTDMap(w,h,NO_INIT);
01117   Image<float> bigTDMap;
01118 
01119   for(int i = 0; i< h; i++)
01120     {
01121       for(int j = 0; j < w; j++)
01122         {
01123           smallTDMap.setVal(j,i,inputVec.getVal(i*w+j,0) );
01124         }
01125     }
01126   inplaceNormalize(smallTDMap, 1.0F, 255.0F);
01127   bigTDMap = rescale(smallTDMap,itsMap.getDims());
01128 
01129   return bigTDMap;
01130 }
01131 
01132 // ######################################################################
01133 void TaskRelevanceMapTigs2::save1(const ModelComponentSaveInfo& sinfo)
01134 {
01135   if (itsSaveResults.getVal())
01136     {
01137       // get the OFS to save to, assuming sinfo is of type
01138       // SimModuleSaveInfo (will throw a fatal exception otherwise):
01139       nub::ref<FrameOstream> ofs =
01140         dynamic_cast<const SimModuleSaveInfo&>(sinfo).ofs;
01141 
01142       ofs->writeFloat(itsCurrentTDMap, FLOAT_NORM_0_255, "TRM-SB",
01143                       FrameInfo("task relevance map static buffer", SRC_POS));
01144     }
01145 }
01146 
01147 // ######################################################################
01148 // ######################################################################
01149 // ########## TaskRelevanceMapSocial implementation
01150 // ######################################################################
01151 // ######################################################################
01152 
01153 // ######################################################################
01154 TaskRelevanceMapSocial::
01155 TaskRelevanceMapSocial(OptionManager& mgr,
01156                            const std::string& descrName,
01157                            const std::string& tagName) :
01158   TaskRelevanceMapAdapter(mgr, descrName, tagName),
01159   itsXMLFName(&OPT_TRMSocialRegionFName, this),
01160   itsObjectsInfo(), itsObjectsNames(), itsNumObjects(0),
01161   itsFrame(0)
01162 { }
01163 
01164 // ######################################################################
01165 void TaskRelevanceMapSocial::start1()
01166 {
01167   // copied from SVEyeRegion::start1
01168   if (itsXMLFName.getVal().empty())
01169     LFATAL("No XML file given - use --trmsocial-input-file option with trm-social");
01170   else
01171     {
01172     // load up the objects from the XML file
01173     itsObjectsInfo.reset(new TestImages(itsXMLFName.getVal().c_str(),
01174                                         TestImages::XMLFILE));
01175 
01176     // "count" the number of distinct objects by ID and get their names
01177     // this works b/c currently our script indexes objects sequentially 
01178     // from 0 ... n
01179     Scene thisScene;
01180     std::string nom;
01181     for (uint i = 0; i < itsObjectsInfo->getNumScenes(); i++)
01182       {
01183          thisScene = itsObjectsInfo->getSceneData(i);
01184         for (std::vector<Object>::iterator iObj = thisScene.objects.begin();
01185              iObj != thisScene.objects.end(); iObj++)
01186           {
01187             //if the array is too small, resize the array
01188             if((*iObj).id >= itsNumObjects) 
01189               {
01190                 itsNumObjects = (*iObj).id+1;
01191                 itsObjectsNames.resize(itsNumObjects,std::string());
01192               }
01193 
01194             // get rid of leading and trailing underscores
01195             nom = (*iObj).name;
01196             if(!nom.empty() && (nom[nom.length()-1] == '_')) 
01197               nom.erase(nom.length()-1);
01198             if(!nom.empty() && (nom[0] == '_')) nom.erase(0,1);
01199 
01200             //if this is a new name, use the id to write the name
01201             if(itsObjectsNames[(*iObj).id].empty()==true) 
01202               {
01203                 itsObjectsNames[(*iObj).id] = nom;
01204                 LINFO("assigning obj %s to obj id #%d from frame %u",
01205                       nom.c_str(),(*iObj).id,i);
01206               }
01207 
01208             // if this id is already used for a different object, throw an error
01209             if (itsObjectsNames[(*iObj).id].compare(nom) != 0)
01210               LFATAL("XML file %s has name conflict for object #%u, %s <-> %s",
01211                      itsXMLFName.getVal().c_str(), (*iObj).id, 
01212                      itsObjectsNames[(*iObj).id].c_str(), nom.c_str());
01213           }
01214      
01215        }
01216     }
01217 
01218   TaskRelevanceMapAdapter::start1(); 
01219 }
01220 
01221 // ######################################################################
01222 TaskRelevanceMapSocial::~TaskRelevanceMapSocial()
01223 { }
01224 
01225 // ######################################################################
01226 void TaskRelevanceMapSocial::inputFrame(const InputFrame& f)
01227 {
01228   const Dims mapdims = f.getDims();
01229   const int sml = itsLevelSpec.getVal().mapLevel();
01230   const float EyeVal = 128.0F, MouthVal = 64.0F, FaceVal = 32.0F, BodyVal = 16.0F, PersonVal = 4.0F, BkgdVal = 1.0F;
01231 
01232   Image<float> BigMap;
01233   BigMap.resize(mapdims, true); 
01234   BigMap.clear(1.0F);
01235   
01236   Scene sceneData =
01237     itsObjectsInfo->getSceneData(itsFrame);
01238 
01239   // loop through all the regions on a given frame and assign z-stack order
01240   std::vector<float> weights(itsNumObjects, 1.0F);
01241   for (std::vector<Object>::iterator itrObject = sceneData.objects.begin(); itrObject != sceneData.objects.end(); itrObject++) {
01242 
01243     uint idx = (*itrObject).id;
01244     std::string ObjName = toLowerCase(itsObjectsNames[idx]);
01245     if (ObjName.find("eye") != std::string::npos) {weights[idx] = EyeVal;}
01246     else if (ObjName.find("mouth") != std::string::npos) {weights[idx] = MouthVal;}
01247     else if (ObjName.find("head") != std::string::npos || 
01248              ObjName.find("face") != std::string::npos) {weights[idx] = FaceVal;}
01249     else if (ObjName.find("body") != std::string::npos) {weights[idx] = BodyVal;}
01250     else if (ObjName.find("person") != std::string::npos ||
01251              ObjName.find("people") != std::string::npos ||
01252              ObjName.find("man") != std::string::npos ||
01253              ObjName.find("woman") != std::string::npos) {weights[idx] = PersonVal;}
01254     else {weights[idx] = BkgdVal;}
01255   }
01256   uint i,j,tmp;
01257   // sort z-stack weights
01258 
01259   const uint numInScene = sceneData.objects.size();
01260   std::vector<uint> zorder(numInScene);
01261   for (i = 0; i < numInScene; i++) zorder[i] = i;
01262   for (i = 0; i < numInScene; i++)  
01263     for (j = 0; j < numInScene-i-1; j++) 
01264       if(weights[sceneData.objects[zorder[j]].id] > 
01265          weights[sceneData.objects[zorder[j+1]].id]) {
01266         tmp = zorder[j];
01267         zorder[j] = zorder[j+1];
01268         zorder[j+1] = tmp;
01269       }  
01270   
01271   // fill BigMap from bottom of z-stack to top
01272   // todo: enforce C0/C1 continuity by some poisson problem?
01273   for (i = 0; i < numInScene; i++) {
01274     Object iObj = sceneData.objects[zorder[i]]; 
01275     drawFilledPolygon(BigMap, iObj.polygon, weights[iObj.id]);
01276   }
01277   
01278   itsMap = rescale(BigMap, mapdims.w() >> sml, mapdims.h() >> sml);
01279   itsFrame++;
01280 }
01281 
01282 // ######################################################################
01283 void TaskRelevanceMapSocial::saccadicSuppression(const bool on)
01284 { }
01285 
01286 // ######################################################################
01287 void TaskRelevanceMapSocial::integrate(SimEventQueue& q)
01288 { }
01289 
01290 // ######################################################################
01291 void TaskRelevanceMapSocial::reset1()
01292 {
01293   TaskRelevanceMapAdapter::reset1();
01294 }
01295 
01296 // ######################################################################
01297 /* So things look consistent in everyone's emacs... */
01298 /* Local Variables: */
01299 /* indent-tabs-mode: nil */
01300 /* End: */
Generated on Sun May 8 08:05:26 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3