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
00039 #include "Neuro/SimulationViewerCompress.H"
00040
00041 #include "Channels/IntensityChannel.H"
00042 #include "Channels/ChannelOpts.H"
00043 #include "Channels/ChannelMaps.H"
00044 #include "Component/OptionManager.H"
00045 #include "Image/ColorOps.H"
00046 #include "Image/CutPaste.H"
00047 #include "Image/DrawOps.H"
00048 #include "Image/FilterOps.H"
00049 #include "Image/MathOps.H"
00050 #include "Image/PyramidOps.H"
00051 #include "Image/ShapeOps.H"
00052 #include "Image/Transforms.H"
00053 #include "Neuro/AttentionGuidanceMap.H"
00054 #include "Neuro/Brain.H"
00055 #include "Neuro/NeuroOpts.H"
00056 #include "Neuro/Retina.H"
00057 #include "Neuro/SaccadeControllers.H"
00058 #include "Neuro/SaccadeControllerConfigurator.H"
00059 #include "Neuro/SaliencyMap.H"
00060 #include "Neuro/ShapeEstimator.H"
00061 #include "Neuro/SpatialMetrics.H"
00062 #include "Neuro/TaskRelevanceMap.H"
00063 #include "Neuro/VisualCortex.H"
00064 #include "Simulation/SimulationOpts.H"
00065 #include "Transport/FrameInfo.H"
00066 #include "Transport/FrameOstream.H"
00067 #include "Util/MathFunctions.H"
00068 #include "Neuro/NeuroSimEvents.H"
00069 #include "Media/MediaSimEvents.H"
00070
00071 #include <stdio.h>
00072
00073 SimulationViewerCompress::
00074 SimulationViewerCompress(OptionManager& mgr,
00075 const std::string& descrName,
00076 const std::string& tagName) :
00077 SimulationViewer(mgr, descrName, tagName),
00078 SIMCALLBACK_INIT(SimEventRetinaImage),
00079 SIMCALLBACK_INIT(SimEventSaccadeStatusEye),
00080 SIMCALLBACK_INIT(SimEventSaveOutput),
00081 itsFOAradius(&OPT_FOAradius, this),
00082 itsNumFoveas(&OPT_SVCOMPnumFoveas, this),
00083 itsSaveTraj(&OPT_SVsaveTraj, this),
00084 itsSaveMegaCombo(&OPT_SVmegaCombo, this),
00085 itsSaveMask(&OPT_SVCOMPsaveMask, this),
00086 itsSaveFoveatedImage(&OPT_SVCOMPsaveFoveatedImage, this),
00087 itsDistanceFactor(&OPT_SVCOMPDistanceFactor, this),
00088 itsSaveEyeCombo(&OPT_SVCOMPsaveEyeCombo, this),
00089 itsDisplayPatch(&OPT_SVdisplayPatch, this),
00090 itsDisplayFOA(&OPT_SVdisplayFOA, this),
00091 itsDisplayEye(&OPT_SVCOMPdisplayHumanEye, this),
00092 itsColorNormal("SVcolorNormal", this, PixRGB<byte>(255, 255, 0)),
00093 itsColorEye("SVcolorHumanEye", this, PixRGB<byte>(128, 255, 255)),
00094 itsHeadRadius(&OPT_HeadMarkerRadius, this),
00095 itsMultiRetinaDepth(&OPT_SVCOMPMultiRetinaDepth, this),
00096 itsCacheSize(&OPT_SVCOMPcacheSize, this),
00097 itsUseTRMmax(&OPT_SVCOMPuseTRMmax, this),
00098 itsFoveaSCtype(&OPT_SVCOMPfoveaSCtype, this),
00099 itsOutFname(&OPT_SVEMoutFname, this),
00100 itsLevelSpec(&OPT_LevelSpec, this),
00101 itsNumRandomSamples(&OPT_SVEMnumRandomSamples, this),
00102 itsEyeCompare(&OPT_SVCOMPeyeCompare, this),
00103 itsIFramePeriod(&OPT_SVCOMPiframePeriod, this),
00104 itsMultiTraj(),
00105 itsSC(), itsInputTime(), itsFrame(-1), itsMask(),
00106 itsIgnoreSC(), itsCurrentMask(), itsOutFile(NULL), itsBlurMask(),
00107 itsEyeData()
00108 {
00109 LINFO("NOTE: disabling IOR");
00110 getManager().setOptionValString(&OPT_IORtype, "None");
00111
00112
00113 if(itsEyeCompare.getVal())
00114 getManager().setOptionValString(&OPT_EyeHeadControllerType, "EyeTrack");
00115 }
00116
00117
00118 SimulationViewerCompress::~SimulationViewerCompress()
00119 { }
00120
00121
00122 void SimulationViewerCompress::paramChanged(ModelParamBase* const param,
00123 const bool valueChanged,
00124 ParamClient::ChangeStatus* status)
00125 {
00126 SimulationViewer::paramChanged(param, valueChanged, status);
00127 if (valueChanged && (param == &itsNumFoveas || param == &itsFoveaSCtype)) buildSCC();
00128 }
00129
00130
00131 void SimulationViewerCompress::buildSCC()
00132 {
00133
00134 removeAllSubComponents();
00135
00136 LINFO("Using %d SaccadeControllers of type %s", itsNumFoveas.getVal(), itsFoveaSCtype.getVal().c_str());
00137
00138
00139 for (int i = 0; i < itsNumFoveas.getVal(); i ++)
00140 {
00141 nub::soft_ref<SaccadeControllerEyeConfigurator> scc(new SaccadeControllerEyeConfigurator(getManager()));
00142
00143
00144 char num[10]; sprintf(num, "%d", i);
00145 scc->setTagName(scc->tagName() + num);
00146 scc->setDescriptiveName(scc->descriptiveName() + " " + std::string(num));
00147 scc->exportOptions(MC_RECURSE);
00148 addSubComponent(scc);
00149
00150
00151
00152 scc->setModelParamString("SaccadeControllerEyeType", itsFoveaSCtype.getVal());
00153 }
00154 }
00155
00156
00157 void SimulationViewerCompress::start1()
00158 {
00159 itsSC.clear(); itsEyeData.clear();
00160 itsMask.setMaxSize(itsCacheSize.getVal());
00161
00162
00163 for (uint i = 0; i < numSubComp(); i ++) {
00164 nub::soft_ref<SaccadeControllerEyeConfigurator> scc = dynCast<SaccadeControllerEyeConfigurator>(subComponent(i));
00165 itsSC.push_back(scc->getSC());
00166 itsIgnoreSC.push_back(false);
00167 }
00168
00169
00170 if (itsOutFname.getVal().empty() == false) {
00171 itsOutFile = fopen(itsOutFname.getVal().c_str(), "w");
00172 if (itsOutFile == NULL) PLFATAL("Cannot write '%s'", itsOutFname.getVal().c_str());
00173 }
00174
00175 SimulationViewer::start1();
00176 }
00177
00178
00179 void SimulationViewerCompress::stop1()
00180 {
00181 if (itsOutFile) { fclose(itsOutFile); itsOutFile = NULL; }
00182 }
00183
00184
00185 void SimulationViewerCompress::
00186 onSimEventRetinaImage(SimEventQueue& q, rutz::shared_ptr<SimEventRetinaImage>& e)
00187 {
00188 itsInputTime = q.now();
00189 ++ itsFrame;
00190 itsRawInputRectangle = e->rawInputRectangle();
00191
00192
00193 itsMultiTraj = buildPyrGaussian(e->frame().colorByte(), 0, itsMultiRetinaDepth.getVal(), 9);
00194 }
00195
00196
00197 void SimulationViewerCompress::
00198 onSimEventSaccadeStatusEye(SimEventQueue& q, rutz::shared_ptr<SimEventSaccadeStatusEye>& e)
00199 {
00200
00201
00202
00203 itsEyeData.push_back(e->position());
00204 }
00205
00206
00207 Image< PixRGB<byte> > SimulationViewerCompress::getTraj(SimEventQueue& q)
00208 {
00209 Dims dims = itsMultiTraj[0].getDims();
00210
00211
00212 Image<float> sm = getMap(q, true);
00213
00214
00215
00216
00217 Image<float> smf = rescaleOpt(sm, dims, itsDisplayInterp.getVal());
00218
00219
00220
00221
00222
00223 Image<byte> msk;
00224 if (itsSC.size()) msk = getMaskSC(smf, q); else msk = getMaskSM(smf);
00225
00226
00227 if (itsCacheSize.getVal() > 0)
00228 {
00229 itsMask.push_back(msk);
00230
00231
00232
00233 if (itsFrame % itsIFramePeriod.getVal() == 0) itsCurrentMask = itsMask.mean();
00234 }
00235 else
00236 itsCurrentMask = msk;
00237
00238
00239 if (itsUseTRMmax.getVal() && itsBlurMask.initialized()) {
00240
00241
00242
00243 Image<byte> minMask = takeMin(itsBlurMask, itsCurrentMask);
00244 if (SeC<SimEventTaskRelevanceMapOutput> e = q.check<SimEventTaskRelevanceMapOutput>(this, SEQ_ANY)) {
00245 Image<float> trm = rescaleOpt(e->trm(1.0F), dims, itsDisplayInterp.getVal());
00246 itsBlurMask = thresholdedMix(trm, 0.99F, minMask, itsCurrentMask);
00247 } else LFATAL("Cannot find a TRM!");
00248 } else itsBlurMask = itsCurrentMask;
00249
00250
00251 Image< PixRGB<byte> > traj = weightedBlur(itsBlurMask, itsMultiTraj);
00252
00253
00254 if (itsDisplayPatch.getVal())
00255 {
00256
00257 PixRGB<byte> col(itsColorNormal.getVal()); int psiz = 4 + 2*itsSC.size();
00258
00259
00260 for (uint i = 0; i < itsSC.size(); i ++)
00261 if (itsIgnoreSC[i] == false) drawPatchBB(traj, itsSC[i]->getPreviousDecision(0).p, psiz-i*2, col);
00262 }
00263
00264
00265 if (itsDisplayFOA.getVal())
00266 {
00267
00268 PixRGB<byte> col(itsColorNormal.getVal()); int thick = 3;
00269
00270 Image<byte> om(itsCurrentMask);
00271 om = binaryReverse(om, byte(255));
00272 inplaceLowThresh(om, byte(220), byte(0));
00273 om = contour2D(om);
00274 int w = traj.getWidth(), h = traj.getHeight();
00275 Point2D<int> ppp;
00276 for (ppp.j = 0; ppp.j < h; ppp.j ++)
00277 for (ppp.i = 0; ppp.i < w; ppp.i ++)
00278 if (om.getVal(ppp.i, ppp.j))
00279 drawDisk(traj, ppp, thick, col);
00280 }
00281
00282
00283 Image< PixRGB<byte> > colorsm = toRGB(Image<byte>(rescaleOpt(sm, dims, itsDisplayInterp.getVal())));
00284
00285
00286 Image< PixRGB<byte> > rawinp2;
00287 if (SeC<SimEventInputFrame> e = q.check<SimEventInputFrame>(this)) rawinp2 = e->frame().asRgb();
00288 Image< PixRGB<byte> > rawinp(dims, NO_INIT); rawinp.clear(PixRGB<byte>(64));
00289 Point2D<int> rawinpoff((rawinp.getWidth() - rawinp2.getWidth())/2, (rawinp.getHeight() - rawinp2.getHeight())/2);
00290 inplacePaste(rawinp, rawinp2, rawinpoff);
00291
00292
00293 if (itsOutFile)
00294 {
00295
00296 byte mi, ma, avg; getMinMaxAvg(itsCurrentMask, mi, ma, avg);
00297
00298
00299 Image<float> rawsm;
00300 if (SeC<SimEventSaliencyMapOutput> e = q.check<SimEventSaliencyMapOutput>(this, SEQ_ANY))
00301 rawsm = e->sm(1.0F); else LFATAL("Cannot find a SM!");
00302
00303
00304 int sml = itsLevelSpec.getVal().mapLevel();
00305
00306
00307
00308 std::vector< Image<float> > cmap;
00309 std::vector<float> cmi, cma, cav;
00310
00311
00312 rutz::shared_ptr<SimReqVCXmaps> vcxm(new SimReqVCXmaps(this));
00313 q.request(vcxm);
00314 rutz::shared_ptr<ChannelMaps> chm = vcxm->channelmaps();
00315
00316
00317
00318
00319
00320
00321 Rectangle r = itsRawInputRectangle;
00322
00323
00324
00325
00326 Rectangle rsm = Rectangle::tlbrI(r.top() >> sml, r.left() >> sml, r.bottomO() >> sml, r.rightO() >> sml);
00327 rsm = rsm.getOverlap(rawsm.getBounds());
00328
00329
00330
00331 Image<float> cropsm = crop(rawsm, rsm);
00332 float rawsmmi, rawsmma, rawsmav;
00333 getMinMaxAvg(cropsm, rawsmmi, rawsmma, rawsmav);
00334
00335
00336 for (uint ii = 0; ii < chm->numSubchans(); ii ++) {
00337 Image<float> cm = chm->subChanMaps(ii)->getMap();
00338 if (cm.initialized() == false) cm.resize(rawsm.getDims(), true);
00339 Image<float> cropmap = crop(cm, rsm);
00340 float ccmi, ccma, ccav;
00341 getMinMaxAvg(cropmap, ccmi, ccma, ccav);
00342 cmi.push_back(ccmi); cma.push_back(ccma); cav.push_back(ccav);
00343 cmap.push_back(cropmap);
00344 }
00345
00346
00347 while(itsEyeData.size()) {
00348
00349 Point2D<int> rnd(randomUpToNotIncluding(itsCurrentMask.getWidth()),
00350 randomUpToNotIncluding(itsCurrentMask.getHeight()));
00351
00352
00353 Point2D<int> eye = itsEyeData.front(); itsEyeData.pop_front();
00354 eye.clampToDims(itsCurrentMask.getDims());
00355
00356
00357 Point2D<int> eyesm(eye.i >> sml, eye.j >> sml);
00358
00359
00360 eyesm.i -= rsm.left(); eyesm.j -= rsm.top();
00361 eyesm.clampToDims(cropsm.getDims());
00362
00363
00364 if (itsDisplayEye.getVal())
00365 {
00366
00367 PixRGB<byte> col(itsColorEye.getVal()); int psiz = 5;
00368 drawPatchBB(traj, eye, psiz, col);
00369 drawPatchBB(colorsm, eye, psiz, col);
00370
00371
00372 Point2D<int> rieye;
00373 if (SeC<SimEventRetinaImage> e = q.check<SimEventRetinaImage>(this, SEQ_ANY))
00374 rieye = e->retinalToRaw(eye);
00375 else LFATAL("ooops, no retina image in the queue?");
00376 rieye += rawinpoff;
00377 drawPatchBB(rawinp, rieye, psiz, col);
00378 }
00379
00380 fprintf(itsOutFile, "%d %d %d %d %d %d",
00381 eye.i,
00382 eye.j,
00383 itsCurrentMask.getVal(eye),
00384 mi,
00385 ma,
00386 avg);
00387
00388 LINFO("eye pos and blur val at eye, mi, ma, avg:%d %d %d %d %d %d",
00389 eye.i, eye.j, itsCurrentMask.getVal(eye),mi,ma, avg);
00390 for(int k=0; k<itsNumRandomSamples.getVal(); k++)
00391 {
00392 Point2D<int> randp(randomUpToNotIncluding(itsCurrentMask.getWidth()),
00393 randomUpToNotIncluding(itsCurrentMask.getHeight()));
00394 fprintf(itsOutFile, " %d", itsCurrentMask.getVal(randp));
00395 }
00396 fprintf(itsOutFile, "\n");
00397 }
00398 }
00399
00400
00401 if (itsSaveMegaCombo.getVal())
00402 {
00403 Image< PixRGB<byte> > ret =
00404 concatX(colGreyCombo(itsMultiTraj[0], rescaleOpt(sm, dims, itsDisplayInterp.getVal()), false),
00405 colGreyCombo(traj, itsCurrentMask, false));
00406 drawGrid(ret, 2, 2, 2, PixRGB<byte>(128));
00407 return ret;
00408 }
00409
00410
00411 if(itsSaveMask.getVal()) return itsCurrentMask;
00412
00413
00414 if(itsSaveFoveatedImage.getVal()) return traj;
00415
00416
00417 if (itsSaveEyeCombo.getVal())
00418 {
00419 Image< PixRGB<byte> > ret = concatX(concatX(rawinp, traj), colorsm);
00420 drawLine(ret, Point2D<int>(dims.w()-1, 0), Point2D<int>(dims.w()-1, dims.h()-1), PixRGB<byte>(255,255,0), 3);
00421 drawLine(ret, Point2D<int>(dims.w()*2-1, 0), Point2D<int>(dims.w()*2-1,dims.h()-1), PixRGB<byte>(255,255,0), 3);
00422
00423
00424 while(ret.getWidth() > 1024) ret = decXY(lowPass3(ret));
00425
00426 return ret;
00427 }
00428
00429
00430 return traj;
00431 }
00432
00433
00434 Image<byte> SimulationViewerCompress::getMaskSM(const Image<float>& smf)
00435 {
00436
00437 Image<float> maskf = lowPass9(smf);
00438
00439
00440
00441 float mi, ma, av; getMinMaxAvg(maskf, mi, ma, av);
00442 maskf = squash(maskf, mi, mi, 0.5F*(av-mi), 0.55F*(av-mi), ma, ma);
00443
00444
00445 Image<byte> mask = binaryReverse(maskf, 255.0F);
00446
00447 return mask;
00448 }
00449
00450
00451
00452 namespace
00453 {
00454 struct Point2DS
00455 {
00456 Point2DS(const Point2D<int>& pp, double ss) : p(pp), sal(ss) {}
00457
00458 Point2D<int> p;
00459 double sal;
00460 };
00461 }
00462
00463 Image<byte> SimulationViewerCompress::getMaskSC(const Image<float>& smf,
00464 SimEventQueue& q)
00465 {
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476 std::vector<Point2DS> topsal;
00477 Image<float> smff = smf;
00478 for (uint i = 0; i < itsSC.size() + 4; i ++) {
00479
00480 Point2D<int> p; float sal; findMax(smff, p, sal);
00481
00482
00483 topsal.push_back(Point2DS(p, double(sal)));
00484
00485
00486
00487 Image<byte> objmask;
00488 if (objmask.initialized() == false) {
00489 objmask.resize(smff.getDims(), true);
00490 drawDisk(objmask, p, itsFOAradius.getVal(), byte(255));
00491 }
00492
00493 inplaceSetValMask(smff, objmask, 0.0F);
00494 }
00495
00496
00497
00498 if (itsFeatures.empty())
00499 for (uint i = 0; i < itsSC.size(); i ++)
00500 {
00501
00502 itsSC[i]->setPercept(WTAwinner(topsal[i].p, q.now(), topsal[i].sal, false), q);
00503
00504
00505 rutz::shared_ptr<SimReqVCXfeatures> ef(new SimReqVCXfeatures(this, topsal[i].p));
00506 q.request(ef);
00507 itsFeatures.push_back(ef->features());
00508
00509 LINFO("Initializing SC[%d] to (%d,%d)", i, topsal[i].p.i, topsal[i].p.j);
00510 }
00511 else
00512 {
00513
00514
00515
00516 std::vector<double> minf, maxf; uint nf = itsFeatures[0].size();
00517 for (uint i = 0; i < nf; i ++) { minf.push_back(1.0e50); maxf.push_back(-1.0e50); }
00518
00519 for (uint fov = 0; fov < itsSC.size(); fov ++)
00520 for (uint i = 0; i < nf; i ++)
00521 {
00522 if (itsFeatures[fov][i] < minf[i]) minf[i] = itsFeatures[fov][i];
00523 if (itsFeatures[fov][i] > maxf[i]) maxf[i] = itsFeatures[fov][i];
00524 }
00525
00526
00527
00528
00529 Image<float> score(topsal.size(), itsSC.size(), NO_INIT);
00530 for (uint i = 0; i < topsal.size(); i ++)
00531 for (uint j = 0; j < itsSC.size(); j ++)
00532 {
00533
00534
00535
00536
00537 Point2D<int> pi = topsal[i].p;
00538 Point2D<int> pj = itsSC[j]->getPreviousPercept(0).p;
00539 float dist = pi.distance(pj);
00540
00541
00542 if (dist < 2.0F * float(itsFOAradius.getVal())) dist = 0.0F;
00543
00544
00545 dist /= sqrt(smf.getWidth() * smf.getWidth() + smf.getHeight() * smf.getHeight());
00546
00547
00548
00549
00550 std::vector<float> scf = itsFeatures[j];
00551 double fdist = 1.0e50;
00552 int ci = pi.i; if (ci & 1) ci --;
00553 int cj = pi.j; if (cj & 1) cj --;
00554 for (int jj = cj - 10; jj <= cj + 10; jj += 2)
00555 for (int ii = ci - 10; ii <= ci + 10; ii += 2)
00556 {
00557 Point2D<int> p(ii, jj);
00558 if (smf.coordsOk(p))
00559 {
00560
00561 rutz::shared_ptr<SimReqVCXfeatures> ef(new SimReqVCXfeatures(this, p));
00562 q.request(ef);
00563 const std::vector<float>& ff = ef->features();
00564
00565
00566
00567
00568 double d = 0.0; int numf = 0;
00569 for (uint k = 0; k < nf; k ++)
00570 if (maxf[k] > minf[k] + 1.0)
00571 {
00572 double dd = (ff[k]-scf[k]) / (maxf[k]-minf[k]);
00573
00574
00575 d += dd * dd; numf ++;
00576 }
00577
00578
00579 if (numf) d = sqrt(d / double(numf));
00580
00581
00582 if (d < fdist) fdist = d;
00583 }
00584 }
00585
00586
00587
00588
00589
00590
00591 float sco = -
00592 float(dist * 100.0) -
00593 float(fdist * 0.5) -
00594 10.0F * fabs(float(i)-float(j)) +
00595 100.0F * topsal[i].sal / topsal[0].sal;
00596
00597 score.setVal(i, j, sco);
00598 LINFO("[topsal(%d)(%d,%d), SC(%d)(%d,%d)]: dist=%f fdist=%f "
00599 "score=%f", i, pi.i, pi.j, j, pj.i, pj.j, dist, fdist, sco);
00600 }
00601
00602
00603
00604
00605 for (uint i = 0; i < itsSC.size(); i ++)
00606 {
00607 Point2D<int> best; float val; findMax(score, best, val);
00608 int bi = best.i;
00609 int bj = best.j;
00610
00611
00612 itsSC[bj]->setPercept(WTAwinner(topsal[bi].p, q.now(), topsal[bi].sal, false), q);
00613
00614
00615
00616
00617 rutz::shared_ptr<SimReqVCXfeatures> ef(new SimReqVCXfeatures(this, topsal[bi].p));
00618 q.request(ef);
00619 itsFeatures[bj] = ef->features();
00620
00621
00622 for (int k = 0; k < score.getWidth(); k ++) score.setVal(k, bj, -1.0e30F);
00623
00624
00625 for (int k = 0; k < score.getHeight(); k ++) score.setVal(bi, k, -1.0e30F);
00626
00627 LINFO("Assigned topsal[%d](%d,%d) to SC[%d](%d,%d)", bi, topsal[bi].p.i, topsal[bi].p.j, bj,
00628 itsSC[bj]->getPreviousPercept(1).p.i, itsSC[bj]->getPreviousPercept(1).p.j);
00629 }
00630 }
00631
00632
00633 for (uint i = 0; i < itsSC.size(); ++i) itsSC[i]->evolve(q);
00634
00635
00636 for (uint i = 0; i < itsSC.size(); ++i) itsSC[i]->getDecision(q, false);
00637
00638
00639
00640 Image<float> maskf(smf.getDims(), ZEROS);
00641 for (uint i = 0; i < itsSC.size(); ++i)
00642 {
00643
00644 itsIgnoreSC[i] = true;
00645
00646
00647 Point2DT p = itsSC[i]->getPreviousDecision(0);
00648 if (p.p.isValid() == false)
00649 { LINFO("Ignoring SC[%d] because coords (%d,%d) invalid", i, p.p.i, p.p.j); continue; }
00650
00651
00652 if (smf.getVal(itsSC[i]->getPreviousPercept(0).p) < topsal[0].sal*0.05)
00653 { LINFO("Ignoring SC[%d] because salience too low", i); continue; }
00654
00655
00656
00657 Image<float> objf;
00658 if (objf.initialized()) maskf = takeMax(maskf, objf);
00659 else drawDisk(maskf, p.p, itsFOAradius.getVal(), 1.0F);
00660
00661
00662 itsIgnoreSC[i] = false;
00663 }
00664
00665
00666 inplaceLowThresh(maskf, 0.5F, 0.0F);
00667
00668
00669 float maxdist = std::max(smf.getWidth(), smf.getHeight()) * 2 * itsDistanceFactor.getVal();
00670 float scalefac = maxdist / 255.0f;
00671 maskf = chamfer34(maskf, maxdist) / scalefac;
00672
00673
00674
00675
00676
00677 float mi, ma, av; getMinMaxAvg(maskf, mi, ma, av);
00678 if (mi > 0.0F) maskf /= 3.0F;
00679 else maskf = squash(maskf, mi, mi, 0.5F*(av-mi), 0.6F*(av-mi), ma, ma);
00680
00681
00682 Image<byte> mask = maskf;
00683 return mask;
00684 }
00685
00686
00687 void SimulationViewerCompress::
00688 onSimEventSaveOutput(SimEventQueue& q, rutz::shared_ptr<SimEventSaveOutput>& e)
00689 {
00690
00691 Image< PixRGB<byte> > res = getTraj(q);
00692
00693
00694 if (itsSaveTraj.getVal() || itsSaveMegaCombo.getVal() ||
00695 itsSaveEyeCombo.getVal() || itsSaveMask.getVal() || itsSaveFoveatedImage.getVal())
00696 {
00697
00698
00699 nub::ref<FrameOstream> ofs = dynamic_cast<const SimModuleSaveInfo&>(e->sinfo()).ofs;
00700
00701 ofs->writeRGB(res, "T", FrameInfo("SimulationViewerCompress trajectory", SRC_POS));
00702 }
00703 }
00704
00705
00706 float SimulationViewerCompress::getSample(const Image<float>& smap,
00707 const Point2D<int>& p,
00708 const int radius) const
00709 {
00710
00711 Image<float> fov(smap.getDims(), ZEROS);
00712 drawDisk(fov, p, radius, 1.0F);
00713 fov *= smap;
00714 float junk, salience;
00715 getMinMax(fov, junk, salience);
00716 return salience;
00717
00718
00719
00720 }
00721
00722
00723 float SimulationViewerCompress::
00724 getRandomSample(const Image<float>& smap, const int radius, const int n) const
00725 {
00726 float rndval = 0.0f;
00727 for (int i = 0; i < n; i ++)
00728 {
00729 Point2D<int> rndsm(randomUpToNotIncluding(smap.getWidth()), randomUpToNotIncluding(smap.getHeight()));
00730 rndval += getSample(smap, rndsm, radius);
00731 }
00732 return rndval / n;
00733 }
00734
00735
00736
00737
00738
00739