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/SaliencyMap.H"
00039
00040 #include "Channels/ChannelOpts.H"
00041 #include "Component/OptionManager.H"
00042 #include "Image/Image.H"
00043 #include "Image/MathOps.H"
00044 #include "Image/FilterOps.H"
00045 #include "Neuro/NeuroOpts.H"
00046 #include "Neuro/SpatialMetrics.H"
00047 #include "Neuro/NeuroSimEvents.H"
00048 #include "Simulation/SimulationOpts.H"
00049 #include "Simulation/SimEventQueue.H"
00050 #include "Transport/FrameInfo.H"
00051 #include "Transport/FrameOstream.H"
00052 #include "Util/Assert.H"
00053 #include "Util/MathFunctions.H"
00054 #include "Util/Types.H"
00055 #include "Util/log.H"
00056 #include "rutz/trace.h"
00057
00058 #include <cmath>
00059
00060 namespace
00061 {
00062
00063 double iorHelper(const double d, const double ampl, const double sdev)
00064 {
00065 double d_dev = d / sdev; d_dev = -0.5 * d_dev * d_dev;
00066 if (d_dev < -20.0) return 0.0;
00067 return ampl * exp(d_dev);
00068 }
00069
00070
00071 double iorHelper(const Point2D<int>& p1, const Point2D<int>& p2,
00072 const double pampl, const double mampl,
00073 const double psdev, const double msdev)
00074 {
00075 double dx = double(p1.i - p2.i);
00076 double dy = double(p1.j - p2.j);
00077 double d = sqrt(squareOf(dx) + squareOf(dy));
00078 return iorHelper(d, pampl, psdev) - iorHelper(d, mampl, msdev);
00079 }
00080 }
00081
00082
00083
00084
00085
00086
00087
00088 SaliencyMap::SaliencyMap(OptionManager& mgr,
00089 const std::string& descrName,
00090 const std::string& tagName) :
00091 SimModule(mgr, descrName, tagName)
00092 {
00093 GVX_TRACE(__PRETTY_FUNCTION__);
00094 }
00095
00096
00097 SaliencyMap::~SaliencyMap()
00098 {
00099 GVX_TRACE(__PRETTY_FUNCTION__);
00100 }
00101
00102
00103
00104
00105
00106
00107
00108 SaliencyMapStub::SaliencyMapStub(OptionManager& mgr,
00109 const std::string& descrName,
00110 const std::string& tagName) :
00111 SaliencyMap(mgr, descrName, tagName)
00112 {
00113 GVX_TRACE(__PRETTY_FUNCTION__);
00114 }
00115
00116
00117 SaliencyMapStub::~SaliencyMapStub()
00118 {
00119 GVX_TRACE(__PRETTY_FUNCTION__);
00120 }
00121
00122
00123
00124
00125
00126
00127
00128 SaliencyMapAdapter::SaliencyMapAdapter(OptionManager& mgr,
00129 const std::string& descrName,
00130 const std::string& tagName) :
00131 SaliencyMap(mgr, descrName, tagName),
00132 SIMCALLBACK_INIT(SimEventWTAwinner),
00133 SIMCALLBACK_INIT(SimEventVisualCortexOutput),
00134 SIMCALLBACK_INIT(SimEventSaccadeStatusEye),
00135 SIMCALLBACK_INIT(SimEventSaveOutput),
00136 itsMetrics(new SpatialMetrics(mgr)),
00137 itsIORtype(&OPT_IORtype, this),
00138 itsLevelSpec(&OPT_LevelSpec, this),
00139 itsSaveResults(&OPT_SMsaveResults, this),
00140 itsSaveCumResults(&OPT_SMsaveCumResults, this),
00141 itsUseSaccadicSuppression(&OPT_SMuseSacSuppress, this),
00142 itsUseBlinkSuppression(&OPT_SMuseBlinkSuppress, this),
00143 itsMaxWinMv(&OPT_SMmaxWinV, this)
00144 {
00145 GVX_TRACE(__PRETTY_FUNCTION__);
00146 this->addSubComponent(itsMetrics);
00147 }
00148
00149
00150 SaliencyMapAdapter::~SaliencyMapAdapter()
00151 {
00152 GVX_TRACE(__PRETTY_FUNCTION__);
00153 }
00154
00155
00156 void SaliencyMapAdapter::
00157 onSimEventWTAwinner(SimEventQueue& q, rutz::shared_ptr<SimEventWTAwinner>& e)
00158 {
00159 const WTAwinner winner = e->winner();
00160 const float winV = this->getV(winner.smpos);
00161
00162
00163 LINFO("SM voltage at winner: %fmV above rest", 1000.0 * winV);
00164
00165
00166
00167 if (1000.0 * winV > itsMaxWinMv.getVal())
00168 {
00169 LINFO("Triggering global inhibition to avoid map explosion.");
00170 this->depress(q, winner.smpos,
00171 0.00005 * (winV - itsMaxWinMv.getVal() / 1000.0),
00172 0.0,
00173 1000.0 * double(itsMetrics->getFOAradius()),
00174 100.0);
00175 }
00176
00177
00178 if (itsIORtype.getVal() != IORnone)
00179 {
00180
00181
00182
00183
00184
00185 Image<float> IORmask;
00186 if (SeC<SimEventShapeEstimatorOutput> ee =
00187 q.check<SimEventShapeEstimatorOutput>(this, SEQ_ANY))
00188 IORmask = ee->iorMask();
00189
00190 if (itsIORtype.getVal() == IORdisc || IORmask.initialized() == false)
00191 {
00192
00193
00194 const double pAmpl = 0.1 * double(winV);
00195 const double mAmpl = 1e-4 * pAmpl;
00196
00197 const double pSdev = 0.3 * double(itsMetrics->getFOAradius()) /
00198 double(1 << itsLevelSpec.getVal().mapLevel());
00199 const double mSdev = 4.0 * pSdev;
00200 this->depress(q, winner.smpos, pAmpl, mAmpl, pSdev, mSdev);
00201 LINFO("Inhibition of return fired.");
00202 }
00203 else if (itsIORtype.getVal() == IORshapeEst && IORmask.initialized())
00204 {
00205 this->depress(q, winner.smpos, winV, IORmask);
00206 LINFO("ShapeEstimator-based inhibition of return fired.");
00207 }
00208 }
00209 }
00210
00211
00212 void SaliencyMapAdapter::
00213 onSimEventVisualCortexOutput(SimEventQueue& q, rutz::shared_ptr<SimEventVisualCortexOutput>& e)
00214 {
00215
00216 this->input(q, e->vco());
00217 }
00218
00219
00220 void SaliencyMapAdapter::
00221 onSimEventSaccadeStatusEye(SimEventQueue& q, rutz::shared_ptr<SimEventSaccadeStatusEye>& e)
00222 {
00223
00224
00225
00226 if (itsUseSaccadicSuppression.getVal())
00227 {
00228 if (e->saccadeStatus() == TSTATUS_BEGIN) this->saccadicSuppression(q, true);
00229 else if (e->saccadeStatus() == TSTATUS_END) this->saccadicSuppression(q, false);
00230 }
00231
00232
00233 if (itsUseBlinkSuppression.getVal())
00234 {
00235 if (e->blinkStatus() == TSTATUS_BEGIN) this->blinkSuppression(q, true);
00236 else if (e->blinkStatus() == TSTATUS_END) this->blinkSuppression(q, false);
00237 }
00238 }
00239
00240
00241 void SaliencyMapAdapter::
00242 onSimEventSaveOutput(SimEventQueue& q, rutz::shared_ptr<SimEventSaveOutput>& e)
00243 {
00244
00245
00246 nub::ref<FrameOstream> ofs = dynamic_cast<const SimModuleSaveInfo&>(e->sinfo()).ofs;
00247
00248
00249 const Image<float> rawsm = this->getV();
00250
00251 if (itsSaveResults.getVal())
00252
00253 ofs->writeFloat(rawsm, FLOAT_NORM_PRESERVE, "SM", FrameInfo("saliency map (bottom-up)", SRC_POS));
00254
00255 if (itsSaveCumResults.getVal())
00256 {
00257
00258
00259
00260 if (itsCumMap.initialized())
00261 const_cast<SaliencyMapAdapter*>(this)->itsCumMap += rawsm;
00262 else
00263 const_cast<SaliencyMapAdapter*>(this)->itsCumMap = rawsm;
00264
00265 ofs->writeFloat(itsCumMap, FLOAT_NORM_PRESERVE, "CUMSM",
00266 FrameInfo("cumulative saliency map", SRC_POS));
00267 }
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277 SaliencyMapStd::SaliencyMapStd(OptionManager& mgr,
00278 const std::string& descrName,
00279 const std::string& tagName) :
00280 SaliencyMapAdapter(mgr, descrName, tagName),
00281 SIMCALLBACK_INIT(SimEventClockTick),
00282 itsGinhDecay(&OPT_SMginhDecay, this), itsNeurons()
00283 {
00284 GVX_TRACE(__PRETTY_FUNCTION__);
00285 }
00286
00287
00288 SaliencyMapStd::~SaliencyMapStd()
00289 {
00290 GVX_TRACE(__PRETTY_FUNCTION__);
00291 }
00292
00293
00294 void SaliencyMapStd::input(SimEventQueue& q, const Image<float>& in)
00295 {
00296
00297 if (itsNeurons.initialized() == false)
00298 {
00299 itsNeurons.resize(in.getDims(), true);
00300 Image<LeakyIntegrator>::iterator
00301 nptr = itsNeurons.beginw(), stop = itsNeurons.endw();
00302 const float decay = itsGinhDecay.getVal();
00303 while(nptr != stop) (nptr++)->setGinhDecay(decay);
00304 }
00305
00306
00307 Image<LeakyIntegrator>::iterator nptr = itsNeurons.beginw();
00308 Image<float>::const_iterator cptr = in.begin(), stop = in.end();
00309 while (cptr != stop) (nptr++)->input(*cptr++);
00310 }
00311
00312
00313 void SaliencyMapStd::depress(SimEventQueue& q, const Point2D<int>& winner,
00314 const double& pampl, const double& mampl,
00315 const double& psdev, const double& msdev)
00316 {
00317 GVX_TRACE(__PRETTY_FUNCTION__);
00318 Point2D<int> p;
00319 const int ww = itsNeurons.getWidth();
00320 const int hh = itsNeurons.getHeight();
00321 Image<LeakyIntegrator>::iterator src = itsNeurons.beginw();
00322
00323
00324 for (p.j = 0; p.j < hh; p.j ++)
00325 for (p.i = 0; p.i < ww; p.i ++)
00326 (src++)->addGinh(float(iorHelper(winner, p, pampl, mampl, psdev, msdev)));
00327
00328 LDEBUG("Peak IOR conductance: %fmS",
00329 iorHelper(winner, winner, pampl, mampl, psdev, msdev) * 1000.0);
00330 }
00331
00332
00333 void SaliencyMapStd::depress(SimEventQueue& q, const Point2D<int>& winner, const double& ampl,
00334 const Image<byte>& objectMask)
00335 {
00336 GVX_TRACE(__PRETTY_FUNCTION__);
00337 Point2D<int> p;
00338 const int ww = itsNeurons.getWidth();
00339 const int hh = itsNeurons.getHeight();
00340 Image<LeakyIntegrator>::iterator src = itsNeurons.beginw();
00341
00342
00343 for (p.j = 0; p.j < hh; p.j ++)
00344 for (p.i = 0; p.i < ww; p.i ++)
00345 (src++)->addGinh(0.1F / 255.F * ampl * float(objectMask.getVal(p)));
00346
00347 LDEBUG("Peak IOR conductance: %fmS",
00348 0.1F / 255.F * ampl * float(objectMask.getVal(winner)) * 1000.0F);
00349 }
00350
00351
00352 void SaliencyMapStd::
00353 onSimEventClockTick(SimEventQueue& q, rutz::shared_ptr<SimEventClockTick>& e)
00354 {
00355
00356 Image<LeakyIntegrator>::iterator itr = itsNeurons.beginw();
00357 Image<LeakyIntegrator>::iterator stop = itsNeurons.endw();
00358 while (itr != stop) (itr++)->integrate(q.now());
00359
00360
00361 const Image<float> sm = this->getV();
00362 q.post(rutz::make_shared(new SimEventSaliencyMapOutput(this, sm, itsLevelSpec.getVal().mapLevel())));
00363 }
00364
00365
00366 void SaliencyMapStd::saccadicSuppression(SimEventQueue& q, const bool on)
00367 {
00368
00369
00370
00371 const float inG = on ? 1.0e-6F : 0.0F;
00372
00373
00374
00375
00376
00377 Image<LeakyIntegrator>::iterator src = itsNeurons.beginw();
00378 Image<LeakyIntegrator>::iterator stop = itsNeurons.endw();
00379 while(src != stop) (src++)->setGinh(inG);
00380
00381 LINFO("------- SaliencyMapStd saccadic suppression %s -------", on ? "on" : "off");
00382 }
00383
00384
00385 void SaliencyMapStd::blinkSuppression(SimEventQueue& q, const bool on)
00386 {
00387
00388
00389
00390 const float inG = on ? 1.0e-6F : 0.0F;
00391
00392
00393
00394
00395
00396 Image<LeakyIntegrator>::iterator src = itsNeurons.beginw();
00397 Image<LeakyIntegrator>::iterator stop = itsNeurons.endw();
00398 while(src != stop) (src++)->setGinh(inG);
00399
00400 LINFO("------- SaliencyMapStd blink suppression %s -------", on ? "on" : "off");
00401 }
00402
00403
00404 Image<float> SaliencyMapStd::getV() const
00405 {
00406 GVX_TRACE(__PRETTY_FUNCTION__);
00407 if (itsNeurons.initialized() == false) return Image<float>();
00408
00409 Image<float> ret(itsNeurons.getDims(), NO_INIT);
00410 Image<float>::iterator dest = ret.beginw();
00411 Image<LeakyIntegrator>::const_iterator src = itsNeurons.begin();
00412 Image<LeakyIntegrator>::const_iterator stop = itsNeurons.end();
00413 while (src != stop) *dest++ = (src++)->getV();
00414
00415 return ret;
00416 }
00417
00418
00419 float SaliencyMapStd::getV(const Point2D<int>& p) const
00420 {
00421 GVX_TRACE(__PRETTY_FUNCTION__);
00422 return itsNeurons.getVal(p).getV();
00423 }
00424
00425
00426 void SaliencyMapStd::reset1()
00427 {
00428 GVX_TRACE(__PRETTY_FUNCTION__);
00429 itsNeurons.freeMem();
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439 SaliencyMapTrivial::SaliencyMapTrivial(OptionManager& mgr,
00440 const std::string& descrName,
00441 const std::string& tagName) :
00442 SaliencyMapAdapter(mgr, descrName, tagName),
00443 itsItoVcoeff(&OPT_SMItoVcoeff, this),
00444 itsNeurons()
00445 {
00446 GVX_TRACE(__PRETTY_FUNCTION__);
00447 }
00448
00449
00450 SaliencyMapTrivial::~SaliencyMapTrivial()
00451 {
00452 GVX_TRACE(__PRETTY_FUNCTION__);
00453 }
00454
00455
00456 void SaliencyMapTrivial::reset1()
00457 {
00458 GVX_TRACE(__PRETTY_FUNCTION__);
00459 itsNeurons.freeMem();
00460 }
00461
00462
00463 void SaliencyMapTrivial::input(SimEventQueue& q, const Image<float>& current)
00464 {
00465 GVX_TRACE(__PRETTY_FUNCTION__);
00466 itsNeurons = current * itsItoVcoeff.getVal();
00467
00468
00469 if (itsNeurons.initialized())
00470 q.post(rutz::make_shared(new SimEventSaliencyMapOutput(this, itsNeurons, itsLevelSpec.getVal().mapLevel())));
00471 }
00472
00473
00474 void SaliencyMapTrivial::depress(SimEventQueue& q, const Point2D<int>& winner,
00475 const double& pampl, const double& mampl,
00476 const double& psdev, const double& msdev)
00477 {
00478 GVX_TRACE(__PRETTY_FUNCTION__);
00479 Point2D<int> p;
00480 const int ww = itsNeurons.getWidth();
00481 const int hh = itsNeurons.getHeight();
00482 Image<float>::iterator src = itsNeurons.beginw();
00483
00484
00485 for (p.j = 0; p.j < hh; p.j ++)
00486 for (p.i = 0; p.i < ww; p.i ++)
00487 {
00488 *src -= float(iorHelper(winner, p, pampl, mampl, psdev, msdev));
00489 if (*src < 0.0F) *src = 0.0F;
00490 ++ src;
00491 }
00492
00493 LDEBUG("Peak IOR conductance: %fmS",
00494 float(iorHelper(winner, winner, pampl, mampl, psdev, msdev)) * 1000.0F);
00495
00496
00497 if (itsNeurons.initialized())
00498 q.post(rutz::make_shared(new SimEventSaliencyMapOutput(this, itsNeurons, itsLevelSpec.getVal().mapLevel())));
00499 }
00500
00501
00502 void SaliencyMapTrivial::depress(SimEventQueue& q, const Point2D<int>& winner, const double& ampl,
00503 const Image<byte>& objectMask)
00504 {
00505 GVX_TRACE(__PRETTY_FUNCTION__);
00506 Image<float> inhib = objectMask * (ampl / 255.0F);
00507 itsNeurons -= inhib;
00508 inplaceRectify(itsNeurons);
00509
00510
00511 if (itsNeurons.initialized())
00512 q.post(rutz::make_shared(new SimEventSaliencyMapOutput(this, itsNeurons, itsLevelSpec.getVal().mapLevel())));
00513 }
00514
00515
00516 void SaliencyMapTrivial::saccadicSuppression(SimEventQueue& q, const bool on)
00517 {
00518 GVX_TRACE(__PRETTY_FUNCTION__);
00519
00520
00521
00522 if (on) itsNeurons -= 1.0e-6F;
00523 LINFO("------- SaliencyMapTrivial saccadic suppression %s -------", on ? "on":"off");
00524
00525
00526 if (itsNeurons.initialized())
00527 q.post(rutz::make_shared(new SimEventSaliencyMapOutput(this, itsNeurons, itsLevelSpec.getVal().mapLevel())));
00528 }
00529
00530
00531 void SaliencyMapTrivial::blinkSuppression(SimEventQueue& q, const bool on)
00532 {
00533 GVX_TRACE(__PRETTY_FUNCTION__);
00534
00535
00536
00537 if (on) itsNeurons -= 1.0e-6F;
00538 LINFO("------- SaliencyMapTrivial blink suppression %s -------", on ? "on":"off");
00539
00540
00541 if (itsNeurons.initialized())
00542 q.post(rutz::make_shared(new SimEventSaliencyMapOutput(this, itsNeurons, itsLevelSpec.getVal().mapLevel())));
00543 }
00544
00545
00546 Image<float> SaliencyMapTrivial::getV() const
00547 {
00548 GVX_TRACE(__PRETTY_FUNCTION__);
00549 return itsNeurons;
00550 }
00551
00552
00553 float SaliencyMapTrivial::getV(const Point2D<int>& p) const
00554 {
00555 GVX_TRACE(__PRETTY_FUNCTION__);
00556 return itsNeurons.getVal(p);
00557 }
00558
00559
00560
00561
00562
00563
00564
00565
00566 SaliencyMapFast::SaliencyMapFast(OptionManager& mgr,
00567 const std::string& descrName,
00568 const std::string& tagName) :
00569 SaliencyMapAdapter(mgr, descrName, tagName),
00570 itsTimeStep(&OPT_SimulationTimeStep, this),
00571 itsInputCoeff(&OPT_SMfastInputCoeff, this),
00572 itsItoVcoeff(&OPT_SMItoVcoeff, this),
00573 itsNeurons(), itsInputCopy(), itsT()
00574 {
00575 GVX_TRACE(__PRETTY_FUNCTION__);
00576 }
00577
00578
00579 SaliencyMapFast::~SaliencyMapFast()
00580 {
00581 GVX_TRACE(__PRETTY_FUNCTION__);
00582 }
00583
00584
00585 void SaliencyMapFast::reset1()
00586 {
00587 GVX_TRACE(__PRETTY_FUNCTION__);
00588 itsNeurons.freeMem(); itsT = SimTime::ZERO();
00589 }
00590
00591
00592 void SaliencyMapFast::input(SimEventQueue& q, const Image<float>& current)
00593 {
00594 GVX_TRACE(__PRETTY_FUNCTION__);
00595
00596
00597 integrate(q);
00598
00599
00600 itsInputCopy = current * itsItoVcoeff.getVal();
00601 itsNeurons = itsInputCopy;
00602
00603
00604
00605 if (itsNeurons.initialized())
00606 q.post(rutz::make_shared(new SimEventSaliencyMapOutput(this, itsNeurons, itsLevelSpec.getVal().mapLevel())));
00607 }
00608
00609
00610 void SaliencyMapFast::depress(SimEventQueue& q, const Point2D<int>& winner,
00611 const double& pampl, const double& mampl,
00612 const double& psdev, const double& msdev)
00613 {
00614 GVX_TRACE(__PRETTY_FUNCTION__);
00615
00616
00617 integrate(q);
00618
00619 Point2D<int> p;
00620 const int ww = itsNeurons.getWidth();
00621 const int hh = itsNeurons.getHeight();
00622 Image<float>::iterator src = itsNeurons.beginw();
00623
00624
00625 for (p.j = 0; p.j < hh; p.j ++)
00626 for (p.i = 0; p.i < ww; p.i ++)
00627 {
00628 *src -= float(iorHelper(winner, p, pampl*30, mampl, psdev, msdev));
00629 if (*src < 0.0F) *src = 0.0F;
00630 ++ src;
00631 }
00632
00633 LDEBUG("Peak IOR conductance: %fmS",
00634 float(iorHelper(winner, winner, pampl*30, mampl, psdev, msdev)) * 1000.0F);
00635
00636
00637 if (itsNeurons.initialized())
00638 q.post(rutz::make_shared(new SimEventSaliencyMapOutput(this, itsNeurons, itsLevelSpec.getVal().mapLevel())));
00639 }
00640
00641
00642 void SaliencyMapFast::depress(SimEventQueue& q, const Point2D<int>& winner, const double& ampl,
00643 const Image<byte>& objectMask)
00644 {
00645 GVX_TRACE(__PRETTY_FUNCTION__);
00646
00647 integrate(q);
00648
00649 Image<float> inhib = objectMask * (ampl / 255.0F);
00650 itsNeurons -= inhib;
00651 inplaceRectify(itsNeurons);
00652
00653
00654 if (itsNeurons.initialized())
00655 q.post(rutz::make_shared(new SimEventSaliencyMapOutput(this, itsNeurons, itsLevelSpec.getVal().mapLevel())));
00656 }
00657
00658
00659 void SaliencyMapFast::integrate(SimEventQueue& q)
00660 {
00661 GVX_TRACE(__PRETTY_FUNCTION__);
00662 double nsteps = (q.now() - itsT).secs() / itsTimeStep.getVal().secs();
00663 if (nsteps >= 1.0 && itsInputCoeff.getVal() < 1)
00664 {
00665 float c1 = pow(itsInputCoeff.getVal(), nsteps), c2 = 1.0F - c1;
00666 itsNeurons *= c1;
00667 inplaceAddWeighted(itsNeurons, itsInputCopy, c2);
00668 }
00669 itsT = q.now();
00670 }
00671
00672
00673 void SaliencyMapFast::saccadicSuppression(SimEventQueue& q, const bool on)
00674 {
00675 GVX_TRACE(__PRETTY_FUNCTION__);
00676
00677 integrate(q);
00678
00679
00680
00681
00682 if (on) itsNeurons -= 1.0e-6F;
00683 LINFO("------- SaliencyMapFast saccadic suppression %s -------", on ? "on":"off");
00684
00685
00686 if (itsNeurons.initialized())
00687 q.post(rutz::make_shared(new SimEventSaliencyMapOutput(this, itsNeurons, itsLevelSpec.getVal().mapLevel())));
00688 }
00689
00690
00691 void SaliencyMapFast::blinkSuppression(SimEventQueue& q, const bool on)
00692 {
00693 GVX_TRACE(__PRETTY_FUNCTION__);
00694
00695 integrate(q);
00696
00697
00698
00699
00700 if (on) itsNeurons -= 1.0e-6F;
00701 LINFO("------- SaliencyMapFast blink suppression %s -------", on ? "on":"off");
00702
00703
00704 if (itsNeurons.initialized())
00705 q.post(rutz::make_shared(new SimEventSaliencyMapOutput(this, itsNeurons, itsLevelSpec.getVal().mapLevel())));
00706 }
00707
00708
00709 Image<float> SaliencyMapFast::getV() const
00710 {
00711 GVX_TRACE(__PRETTY_FUNCTION__);
00712 return itsNeurons;
00713 }
00714
00715
00716 float SaliencyMapFast::getV(const Point2D<int>& p) const
00717 {
00718 GVX_TRACE(__PRETTY_FUNCTION__);
00719 return itsNeurons.getVal(p);
00720 }
00721
00722
00723
00724
00725
00726