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/SimulationViewerNerdCam.H"
00039
00040 #include "Channels/BlueYellowChannel.H"
00041 #include "Channels/ChannelBase.H"
00042 #include "Channels/ColorChannel.H"
00043 #include "Channels/DirectionChannel.H"
00044 #include "Channels/FlickerChannel.H"
00045 #include "Channels/GaborChannel.H"
00046 #include "Channels/IntensityChannel.H"
00047 #include "Channels/MotionChannel.H"
00048 #include "Channels/OrientationChannel.H"
00049 #include "Channels/RedGreenChannel.H"
00050 #include "Image/ColorOps.H"
00051 #include "Image/CutPaste.H"
00052 #include "Image/DrawOps.H"
00053 #include "Image/MathOps.H"
00054 #include "Image/PyramidOps.H"
00055 #include "Image/ShapeOps.H"
00056 #include "Image/Transforms.H"
00057 #include "Image/LevelSpec.H"
00058 #include "Neuro/AttentionGuidanceMap.H"
00059 #include "Neuro/NeuroOpts.H"
00060 #include "Neuro/NeuroSimEvents.H"
00061 #include "Neuro/SaliencyMap.H"
00062 #include "Neuro/TaskRelevanceMap.H"
00063 #include "Raster/Raster.H"
00064 #include "Simulation/SimEventQueue.H"
00065 #include "Transport/FrameInfo.H"
00066 #include "Transport/FrameOstream.H"
00067 #include "Util/readConfig.H"
00068 #include <time.h>
00069 #include <stdio.h>
00070
00071
00072
00073
00074 SimulationViewerNerdCam::SimulationViewerNerdCam(OptionManager& mgr,
00075 const std::string& descrName,
00076 const std::string& tagName) :
00077 SimulationViewer(mgr, descrName, tagName),
00078 SIMCALLBACK_INIT(SimEventInputFrame),
00079 SIMCALLBACK_INIT(SimEventClockTick),
00080 SIMCALLBACK_INIT(SimEventWTAwinner),
00081 SIMCALLBACK_INIT(SimEventSaveOutput),
00082 itsMetrics(new SpatialMetrics(mgr)),
00083 itsColorBoring("SVcolorBoring", this, PixRGB<byte>(127, 0, 0)),
00084 itsColorLink("SVcolorLink", this, PixRGB<byte>(255, 0, 0)),
00085 itsColorNormal("SVcolorNormal", this, PixRGB<byte>(255, 255, 0)),
00086 itsConfigFile(&OPT_NerdCamConfigFile, this),
00087 itsCropFOA(&OPT_SVcropFOA, this),
00088 itsDisplayAdditive(&OPT_SVdisplayAdditive, this),
00089 itsDisplayBoring(&OPT_SVdisplayBoring, this),
00090 itsDisplayFOA(&OPT_SVdisplayFOA, this),
00091 itsDisplayFOALinks(&OPT_SVdisplayFOALinks, this),
00092 itsDisplayHighlights(&OPT_SVdisplayHighlights, this),
00093 itsDisplayPatch(&OPT_SVdisplayPatch, this),
00094 itsDisplaySMmodulate(&OPT_SVdisplaySMmodulate, this),
00095 itsDisplayTime(&OPT_SVdisplayTime, this),
00096 itsFOApsiz("SVfoapsiz", this, 3),
00097 itsFOAthick("SVfoathick", this, 3),
00098 itsFOAlinkThick("SVfoalinkthick", this, 2),
00099 itsMegaCombo(&OPT_SVmegaCombo, this),
00100 itsWarp3Dpitch("SVwarp3DInitialPitch", this, -25.0F),
00101 itsWarp3Dyaw("SVwarp3DInitialYaw", this, -15.0F),
00102 itsWarp3DpitchRate("SVwarp3DpitchRate", this, 0.0F),
00103 itsWarp3DyawRate("SVwarp3DyawRate", this, 15.0F),
00104 itsWarp3DpitchMax("SVwarp3DpitchMax", this, 0.0F),
00105 itsWarp3DyawMax("SVwarp3DyawMax", this, 20.0F),
00106 itsUseLargerDrawings(&OPT_SVuseLargerDrawings, this),
00107 itsCumFOAmask(),
00108 itsCurrFOA(WTAwinner::NONE()),
00109 itsCurrFOAmask(),
00110 itsCurrTime(),
00111 itsDims3D(),
00112 itsMultiTraj(),
00113 itsPrevFOA(WTAwinner::NONE()),
00114 itsTraj(),
00115 itsPitch3D(-1.0e10F),
00116 itsYaw3D(-1.0e10F)
00117 {
00118 this->addSubComponent(itsMetrics);
00119 itsInit = false;
00120 nlog("INIT - Normal startup recognized");
00121 }
00122
00123
00124 SimulationViewerNerdCam::~SimulationViewerNerdCam()
00125 {
00126 nlog("SHUTDOWN - normal shutdown recognized");
00127 }
00128
00129
00130 void SimulationViewerNerdCam::init(const ushort baseSizeX,
00131 const ushort baseSizeY)
00132 {
00133 char base[100];
00134 std::string logstr;
00135
00136 itsBaseSizeX = baseSizeX;
00137 itsBaseSizeY = baseSizeY;
00138
00139 const std::string configFile = itsConfigFile.getVal();
00140 readConfig config(25);
00141 config.openFile(configFile.c_str(),false);
00142
00143 itsLogFile = config.getItemValueS("LogFile");
00144 sprintf(base,"INIT - Config File %s",configFile.c_str());
00145 logstr = base; nlog(logstr);
00146
00147 itsOutputMotionImage = config.getItemValueS("OutputMotionImage");
00148 itsOutputSalMapImage = config.getItemValueS("OutputSalMapImage");
00149 itsOutput3DImage = config.getItemValueS("Output3DImage");
00150 itsOutputMegaImage = config.getItemValueS("OutputMegaImage");
00151 itsOutputTrajImage = config.getItemValueS("OutputTrajImage");
00152 itsWebPageFile = config.getItemValueS("WebPageFile");
00153 itsStatusFile = config.getItemValueS("StatusFile");
00154 itsStatusHeader = config.getItemValueS("StatusHeader");
00155 itsStatusFooter = config.getItemValueS("StatusFooter");
00156 itsChannelFile = config.getItemValueS("ChannelFile");
00157 itsBaseURL = config.getItemValueS("BaseURL");
00158 itsBaseName = config.getItemValueS("BaseName");
00159 itsMotionThreshold = config.getItemValueF("MotionThreshold");
00160
00161 sprintf(base,"INIT - Image %d x %d",itsBaseSizeX,itsBaseSizeY);
00162 logstr = base; nlog(logstr);
00163 nlog("INIT - Init complete");
00164 itsInit = true;
00165
00166
00167 time_t rawtime; struct tm * timeinfo;
00168 time ( &rawtime ); timeinfo = localtime ( &rawtime );
00169 itsStartTime = asctime (timeinfo);
00170 itsTotalFrames = 0;
00171 }
00172
00173
00174 void SimulationViewerNerdCam::reset1()
00175 {
00176 itsCurrFOA = WTAwinner::NONE();
00177 itsCurrFOAmask.freeMem();
00178 itsCurrTime = SimTime::ZERO();
00179 itsCumFOAmask.freeMem();
00180 itsDims3D = Dims();
00181 itsHasNewInput = false;
00182 itsMultiTraj.reset();
00183 itsPitch3D = -1.0e10F;
00184 itsPrevFOA = WTAwinner::NONE();
00185 itsTraj.freeMem();
00186 itsYaw3D = -1.0e10F;
00187
00188 SimulationViewer::reset1();
00189 nlog("INIT - Model reset complete");
00190 }
00191
00192
00193 void SimulationViewerNerdCam::start2()
00194 {
00195
00196 if (itsUseLargerDrawings.getVal())
00197 {
00198 itsFOApsiz.setVal(5);
00199 }
00200 }
00201
00202
00203 void SimulationViewerNerdCam::
00204 onSimEventInputFrame(SimEventQueue& q, rutz::shared_ptr<SimEventInputFrame>& e)
00205 {
00206 LINFO("Inputing to Nerd-cam");
00207
00208 itsInput = e->frame().asRgb();
00209
00210 if (!itsInit) init(itsInput.getWidth(), itsInput.getHeight());
00211
00212
00213 itsTraj = itsInput;
00214
00215
00216
00217 itsHasNewInput = true;
00218 itsTotalFrames++;
00219 }
00220
00221
00222 void SimulationViewerNerdCam::
00223 onSimEventClockTick(SimEventQueue& q, rutz::shared_ptr<SimEventClockTick>& e)
00224 {
00225 const SimTime t = q.now();
00226
00227
00228 if (itsPitch3D == -1.0e10F)
00229 itsPitch3D = itsWarp3Dpitch.getVal();
00230 if (itsYaw3D == -1.0e10F)
00231 itsYaw3D = itsWarp3Dyaw.getVal();
00232
00233 itsPitch3D += itsWarp3DpitchRate.getVal() * (t - itsCurrTime).secs();
00234 itsYaw3D += itsWarp3DyawRate.getVal() * (t - itsCurrTime).secs();
00235
00236 if (itsYaw3D >= itsWarp3DyawMax.getVal() ||
00237 itsYaw3D <= -itsWarp3DyawMax.getVal())
00238 itsWarp3DyawRate.setVal(- itsWarp3DyawRate.getVal());
00239 if (itsPitch3D >= itsWarp3DpitchMax.getVal() ||
00240 itsPitch3D <= -itsWarp3DpitchMax.getVal())
00241 itsWarp3DpitchRate.setVal(- itsWarp3DpitchRate.getVal());
00242
00243 itsCurrTime = t;
00244 }
00245
00246
00247 void SimulationViewerNerdCam::
00248 onSimEventWTAwinner(SimEventQueue& q, rutz::shared_ptr<SimEventWTAwinner>& e)
00249 {
00250
00251 Image<byte> foaMask;
00252 if (SeC<SimEventShapeEstimatorOutput> ee = q.check<SimEventShapeEstimatorOutput>(this))
00253 {
00254 foaMask = Image<byte>(ee->smoothMask() * 255.0F);
00255 if (foaMask.isSameSize(itsInput) == false)
00256 LFATAL("Dimensions of FOAmask must match those of input");
00257 }
00258
00259
00260 if (foaMask.initialized() && foaMask.isSameSize(itsInput) == false)
00261 LFATAL("Dimensions of FOAmask must match those of input");
00262
00263
00264 itsPrevFOA = itsCurrFOA; itsCurrFOA = e->winner();
00265 if (foaMask.initialized())
00266 itsCurrFOAmask = foaMask;
00267 else
00268 {
00269
00270 itsCurrFOAmask.resize(itsInput.getDims(), true);
00271 if (itsCurrFOA.isValid())
00272 drawDisk(itsCurrFOAmask, itsCurrFOA.p,
00273 itsMetrics->getFOAradius(), byte(255));
00274 }
00275
00276
00277 if (itsDisplayAdditive.getVal() &&
00278 itsCumFOAmask.initialized() &&
00279 itsCumFOAmask.isSameSize(itsCurrFOAmask))
00280 itsCumFOAmask = takeMax(itsCumFOAmask, itsCurrFOAmask);
00281 else
00282 itsCumFOAmask = itsCurrFOAmask;
00283
00284
00285 if (itsTraj.initialized() == false) return;
00286
00287
00288 if (itsDisplayFOA.getVal() || itsDisplayPatch.getVal()) drawFOA();
00289
00290
00291 if (itsDisplayFOALinks.getVal()) linkFOAs();
00292 }
00293
00294
00295 Image< PixRGB<byte> > SimulationViewerNerdCam::getTraj(SimEventQueue& q)
00296 {
00297
00298 itsCurrTime = q.now(); bool redraw = false;
00299 if (itsTraj.initialized() == false) return itsTraj;
00300
00301
00302
00303 if (itsDisplayAdditive.getVal() == false)
00304 { itsTraj = itsInput; redraw = true; }
00305
00306
00307
00308
00309
00310 if (redraw || itsHasNewInput)
00311 {
00312 if (itsDisplayFOA.getVal() || itsDisplayPatch.getVal()) drawFOA();
00313 itsHasNewInput = false;
00314 }
00315
00316
00317
00318
00319 Image< PixRGB<byte> > ret;
00320
00321
00322
00323 if (itsCropFOA.getVal().isNonEmpty())
00324 {
00325 Dims crop_dims = itsCropFOA.getVal();
00326 Rectangle crect =
00327 Rectangle::tlbrI(itsCurrFOA.p.j - crop_dims.h() / 2,
00328 itsCurrFOA.p.i - crop_dims.w() / 2,
00329 itsCurrFOA.p.j + crop_dims.h() / 2 - 1,
00330 itsCurrFOA.p.i + crop_dims.w() / 2 - 1);
00331 ret = crop(itsTraj, crect, true);
00332 }
00333 else ret = itsTraj;
00334
00335
00336 if (itsDisplayTime.getVal()) drawTime(ret);
00337
00338 return ret;
00339 }
00340
00341
00342 void SimulationViewerNerdCam::saveResults(const nub::ref<FrameOstream>& ofs,
00343 SimEventQueue& q)
00344 {
00345
00346 const Image< PixRGB<byte> > traj = getTraj(q);
00347
00348 const double msecs = itsCurrTime.msecs();
00349
00350 LINFO("Running Nerd-cam on Sample Input time %f ms",msecs);
00351 Image<float> salMap = getMap(q);
00352
00353
00354 itsSalMap = rescale(salMap,itsBaseSizeX,itsBaseSizeY);
00355
00356
00357
00358 const Image<byte> bsal = itsSalMap;
00359 struct flock fl_smap;
00360 int fd_smap;
00361 lockFile(itsOutputSalMapImage,fd_smap,fl_smap);
00362 Raster::WriteRGB(bsal,itsOutputSalMapImage);
00363
00364
00365 nub::soft_ref<MotionChannel> mc;
00366
00367 LFATAL("FIXME I should derive from SimulationViewerStd");
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 if (mc.isInvalid())
00378 {
00379 nlog("FATAL - Channel named 'motion' not a MotionChannel");
00380 LFATAL("Channel named 'motion' not a MotionChannel");
00381 }
00382
00383 int fd_traj, fd_mega;
00384 struct flock fl_traj;
00385 struct flock fl_mega;
00386 if(itsTraj.initialized())
00387 {
00388
00389 lockFile(itsOutputTrajImage,fd_traj,fl_traj);
00390 Raster::WriteRGB(traj,itsOutputTrajImage);
00391
00392 if(itsTotalFrames > 1)
00393 {
00394 const Image< PixRGB<byte> > meg = drawMegaCombo(q);
00395 lockFile(itsOutputMegaImage,fd_mega,fl_mega);
00396 Raster::WriteRGB(meg,itsOutputMegaImage);
00397 itsComboSizeX = meg.getWidth();
00398 itsComboSizeY = meg.getHeight();
00399 }
00400 }
00401
00402 float min = 0, max = 0, avg = 0;
00403 float div = 0;
00404
00405 bool doMotion = false;
00406
00407 for(ushort i = 0; i < mc->numChans(); i++)
00408 {
00409 float mi,ma,av;
00410 const Image<float> ftmp = mc->dirChan(i).getOutput();
00411 getMinMaxAvg(ftmp,mi,ma,av);
00412 min += mi; max += ma; avg += av;
00413 div++;
00414 if(ma > itsMotionThreshold)
00415 doMotion = true;
00416 }
00417 min = min/div; max = max/div; avg = avg/div;
00418
00419
00420
00421 int fd_mot;
00422 struct flock fl_mot;
00423 if(doMotion)
00424 {
00425 LINFO("Drawing Motion Image");
00426 const Image<PixRGB<byte> > bimg = itsInput;
00427 lockFile(itsOutputMotionImage,fd_mot,fl_mot);
00428 Raster::WriteRGB(bimg,itsOutputMotionImage);
00429 }
00430
00431
00432 Image< PixRGB<byte> > ret = itsInput;
00433 drawGrid(ret, ret.getWidth() / 6, ret.getHeight() / 6, 3, 3,
00434 itsColorNormal.getVal());
00435 drawRect(ret, Rectangle::tlbrI(1, 1, ret.getHeight()-2, ret.getWidth()-2),
00436 itsColorNormal.getVal(), 3);
00437 ret = warp3Dmap(ret, getMap(q), itsPitch3D, itsYaw3D, itsDims3D);
00438 int fd_3d;
00439 struct flock fl_3d;
00440 lockFile(itsOutput3DImage,fd_3d,fl_3d);
00441 Raster::WriteRGB(ret,itsOutput3DImage);
00442 its3DSizeX = ret.getWidth();
00443 its3DSizeY = ret.getHeight();
00444
00445 writeStatusPage();
00446
00447 if(itsTotalFrames > 1)
00448 {
00449 writeChannelPage();
00450 }
00451
00452
00453 if(avg > itsMotionThreshold)
00454 {
00455 unlockFile(itsOutputMotionImage,fd_mot,fl_mot);
00456 }
00457 if(itsTraj.initialized())
00458 {
00459 unlockFile(itsOutputTrajImage,fd_traj,fl_traj);
00460 if(itsTotalFrames > 1)
00461 {
00462 unlockFile(itsOutputMegaImage,fd_mega,fl_mega);
00463 }
00464 }
00465 unlockFile(itsOutputSalMapImage,fd_smap,fl_smap);
00466 unlockFile(itsOutput3DImage,fd_3d,fl_3d);
00467 }
00468
00469
00470 void SimulationViewerNerdCam::
00471 onSimEventSaveOutput(SimEventQueue& q, rutz::shared_ptr<SimEventSaveOutput>& e)
00472 {
00473 this->save1(e->sinfo());
00474 }
00475
00476
00477 void SimulationViewerNerdCam::save1(const ModelComponentSaveInfo& sinfo)
00478 {
00479
00480
00481 nub::ref<FrameOstream> ofs =
00482 dynamic_cast<const SimModuleSaveInfo&>(sinfo).ofs;
00483
00484
00485 SimEventQueue *q = dynamic_cast<const SimModuleSaveInfo&>(sinfo).q;
00486
00487 saveResults(ofs, *q);
00488 }
00489
00490
00491 void SimulationViewerNerdCam::writeStatusPage() const
00492 {
00493 std::ifstream headFile(itsStatusHeader.c_str(),std::ios::in);
00494 std::ifstream footFile(itsStatusFooter.c_str(),std::ios::in);
00495
00496
00497 double peaksum;
00498 const double sdev = stdev(itsSalMap);
00499 float mi, ma, av; getMinMaxAvg(itsSalMap, mi, ma, av);
00500 const int npeaks = findPeaks(itsSalMap, 0.0f, 255.0f, peaksum);
00501
00502
00503 float maxval; Point2D<int> maxloc;
00504 findMax(itsSalMap, maxloc, maxval);
00505 const float scale = float(itsInput.getWidth()) / float(itsSalMap.getWidth());
00506 maxloc.i = int(maxloc.i * scale + 0.4999F);
00507 maxloc.j = int(maxloc.j * scale + 0.4999F);
00508
00509
00510 float minval; Point2D<int> minloc;
00511 findMin(itsSalMap, minloc, minval);
00512 minloc.i = int(minloc.i * scale + 0.4999F);
00513 minloc.j = int(minloc.j * scale + 0.4999F);
00514
00515 int fd; struct flock fl;
00516 lockFile(itsStatusFile,fd,fl);
00517 std::ofstream statFile(itsStatusFile.c_str(),std::ios::out);
00518
00519 std::string in;
00520 while (headFile >> in)
00521 {
00522 if(!in.compare("\\"))
00523 statFile << "\n";
00524 else
00525 statFile << in << " ";
00526 }
00527 statFile.flush();
00528 statFile << "\n<!-- End Header File -->\n"
00529 << "<!--\n"
00530 << "Nerd Cam Daemon\n"
00531 << "T. Nathan Mundhenk and Laurent Itti\n"
00532 << "http://www.nerd-cam.com\n"
00533 << "-->\n"
00534 << "<a href=\"" << itsBaseURL << "\">"
00535 << "<H1>" << itsBaseName << "</a> "
00536 << "Detailed Server Status</H1>\n";
00537
00538 time_t rawtime; struct tm * timeinfo;
00539 time ( &rawtime ); timeinfo = localtime ( &rawtime );
00540
00541
00542 statFile << "<H2>Nerd-Cam Daemon Saliency Server Statistics </H2>\n"
00543 << "<table border=\"0\" width=\"800\">\n"
00544 << "<tr>\n"
00545 << "\t<td width=\"275\">\n"
00546 << "\t\t<H3>Current Time </H3>"
00547 << asctime (timeinfo) << "<br>\n"
00548 << "\t\t<H3>Server Start Time </H3>"
00549 << itsStartTime << "<br>\n"
00550 << "\t\t<H3>Total Frames Processed </H3>"
00551 << itsTotalFrames << "<br>\n"
00552 << "\t\t<p> </td>\n"
00553 << "\t<td width=\"525\" align=\"center\">\n"
00554 << "\t\t<h1>Last Nerd Spotted by Nerd-Cam</h1>\n"
00555 << "\t\t<p><img border=\"0\" src=\"nerd-cam.motion.png\" "
00556 << "width=\"320\" height=\"240\"></p>\n"
00557 << "\t</td>\n"
00558 << "</tr>\n"
00559 << "</table>\n";
00560
00561 statFile.flush();
00562
00563 statFile << "<H2>Current Saliency Map Statistics </H2>\n"
00564 << "<table border=0 cellpadding=0 width=800>\n"
00565 << "<tr>\n"
00566 << "\t<td width=275 valign=top>\n"
00567 << "\t\t<H3>Point of Maximum Saliency </H3>"
00568 << "(" << maxloc.i << "," << maxloc.j << ")<br>\n"
00569 << "\t\t<H3>Point of Minimum Saliency </H3>"
00570 << "(" << minloc.i << "," << minloc.j << ")<br>\n"
00571 << "\t\t<H3>Maximum Saliency Value </H3>"
00572 << ma << "<br>\n"
00573 << "\t\t<H3>Minimum Saliency Value </H3>"
00574 << mi << "<br>\n"
00575 << "\t\t<H3>Average Saliency Value </H3>"
00576 << av << "<br>\n"
00577 << "\t\t<H3>Standard Deviation </H3>"
00578 << sdev << "<br>\n"
00579 << "\t\t<H3>Number of Peaks </H3>"
00580 << npeaks << "<br>\n"
00581 << "\t\t<H3>Peak Sum </H3>"
00582 << peaksum << "<br>\n"
00583 << "\t</td>\n"
00584 << "\t<td width=525 valign=top align=\"center\">\n"
00585 << "\t\t<H1>Superimposed 3D Saliency Image</H1>\n"
00586 << "\t\t<img border=0 width="
00587 << its3DSizeX
00588 << " height="
00589 << its3DSizeY
00590 << " src=\"awesome.3d.image.png\" "
00591 << " alt=\"Awesome 3D Saliency Map "
00592 << "to shock and awe\"><br>\n"
00593 << "\t</td>\n"
00594 << "</tr>\n"
00595 << "</table>\n";
00596 statFile.flush();
00597 statFile << "<!-- Start Footer File -->\n";
00598 while (footFile >> in)
00599 {
00600 if(!in.compare("\\"))
00601 statFile << "\n";
00602 else
00603 statFile << in << " ";
00604 }
00605
00606 statFile.flush();
00607 statFile.close();
00608 while(statFile.is_open() != 0){}
00609 unlockFile(itsStatusFile,fd,fl);
00610 }
00611
00612
00613 void SimulationViewerNerdCam::writeChannelPage() const
00614 {
00615 std::ifstream headFile(itsStatusHeader.c_str(),std::ios::in);
00616 std::ifstream footFile(itsStatusFooter.c_str(),std::ios::in);
00617
00618 int fd; struct flock fl;
00619 lockFile(itsChannelFile,fd,fl);
00620 std::ofstream statFile(itsChannelFile.c_str(),std::ios::out);
00621
00622 std::string in;
00623 while (headFile >> in)
00624 {
00625 if(!in.compare("\\"))
00626 statFile << "\n";
00627 else
00628 statFile << in << " ";
00629 }
00630 statFile.flush();
00631 statFile << "\n<!-- End Header File -->\n"
00632 << "<!--\n"
00633 << "Nerd Cam Daemon\n"
00634 << "T. Nathan Mundhenk and Laurent Itti\n"
00635 << "http://www.nerd-cam.com\n"
00636 << "-->\n"
00637 << "<a href=\"" << itsBaseURL << "\">"
00638 << "<H1>" << itsBaseName << "</a> "
00639 << "Detailed Channel Status</H1>\n"
00640 << "<H2>Mega Combo Saliency Image</H2>\n"
00641 << "<img border=0 width="
00642 << itsComboSizeX
00643 << " height="
00644 << itsComboSizeY
00645 << " src=\"mega.surprise.combo.png\" "
00646 << " alt=\"Mega Combo Saliency Map with all the topings "
00647 << "for your viewing pleasure\"><br>\n";
00648
00649 statFile << "<H2>Current Saliency Map Statistics Per Channel</H2>\n"
00650 << "<table border=0 cellpadding=0 width=900>\n"
00651 << "<tr>\n"
00652 << "\t<td width=\"150\" bgcolor=\"#AAD0F0\">\n"
00653 << "\t\t<H2>Channel Type</H2>\n"
00654 << "\t</td>\n"
00655 << "\t<td width=\"150\" bgcolor=\"#AAD0F0\">\n"
00656 << "\t\t<H2>Maximum Saliency</H2>\n"
00657 << "\t</td>\n"
00658 << "\t<td width=\"150\" bgcolor=\"#AAD0F0\">\n"
00659 << "\t\t<H2>Minimum Saliency</H2>\n"
00660 << "\t</td>\n"
00661 << "\t<td width=\"150\" bgcolor=\"#AAD0F0\">\n"
00662 << "\t\t<H2>Average Saliency</H2>\n"
00663 << "\t</td>\n"
00664 << "\t<td width=\"150\" bgcolor=\"#AAD0F0\">\n"
00665 << "\t\t<H2>Saliency Peaks</H2>\n"
00666 << "\t</td>\n"
00667 << "\t<td width=\"150\" bgcolor=\"#AAD0F0\">\n"
00668 << "\t\t<H2>Saliency Peaks Sum</H2>\n"
00669 << "\t</td>\n"
00670 << "</tr>\n";
00671 statFile.flush();
00672
00673 LFATAL("FIXME I should derive from SimulationViewerStd");
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 statFile << "</table>\n"
00868 << "<!-- Start Footer File -->\n";
00869 while (footFile >> in)
00870 {
00871 if(!in.compare("\\"))
00872 statFile << "\n";
00873 else
00874 statFile << in << " ";
00875 }
00876
00877 statFile.flush();
00878 statFile.close();
00879 while(statFile.is_open() != 0){}
00880 unlockFile(itsChannelFile,fd,fl);
00881 }
00882
00883
00884 void SimulationViewerNerdCam::drawTime(Image<PixRGB<byte> >& image) const
00885 {
00886 char txt[20]; sprintf(txt, " %dms ", int(itsCurrTime.msecs() + 0.4999));
00887 writeText(image, Point2D<int>(0, 0), txt);
00888 }
00889
00890
00891 void SimulationViewerNerdCam::lockFile(const std::string fileName,
00892 int &fd,
00893 struct flock &fl) const
00894 {
00895
00896 fd = open(fileName.c_str(), O_RDWR);
00897 if (fd < 0)
00898 {
00899 LINFO("lockFile: Open failure on file %s",fileName.c_str());
00900 }
00901 else
00902 {
00903 fl.l_type = F_WRLCK;
00904 fl.l_whence = SEEK_SET;
00905 fl.l_start = 0;
00906 fl.l_len = 0;
00907 if (fcntl(fd, F_SETLK, &fl) == -1)
00908 {
00909 if (errno == EACCES || errno == EAGAIN)
00910 LINFO("'%s' Already locked by another process",fileName.c_str());
00911 else if(errno == EBADF)
00912 LINFO("'%s' not a valid open file descriptor",fileName.c_str());
00913 else if(errno == EINVAL)
00914 LINFO("'%s In a locking operation, fildes refers to a file with a type that does not support locking, or the struct flock pointed to by the third argument has an incorrect form",fileName.c_str());
00915 else if(errno == EMFILE)
00916 LINFO("'%s' process has already reached its maximum number of file descriptors",fileName.c_str());
00917 else
00918 LINFO("Cannot lock file '%s' Error code '%d'",fileName.c_str(),errno);
00919 }
00920 }
00921 }
00922
00923
00924 void SimulationViewerNerdCam::unlockFile(const std::string fileName,
00925 const int fd,
00926 struct flock &fl) const
00927 {
00928
00929 fl.l_type = F_UNLCK;
00930 fl.l_whence = SEEK_SET;
00931 fl.l_start = 0;
00932 fl.l_len = 0;
00933 if (fcntl(fd, F_SETLK, &fl) == -1)
00934 {
00935 LINFO("Cannot unlock file '%s'",fileName.c_str());
00936 }
00937 close(fd);
00938 }
00939
00940
00941 void SimulationViewerNerdCam::nlog(const std::string logData) const
00942 {
00943 time_t rawtime; struct tm * timeinfo;
00944 time ( &rawtime ); timeinfo = localtime ( &rawtime );
00945
00946 int fd; struct flock fl;
00947 lockFile(itsLogFile,fd,fl);
00948 std::ofstream logFile(itsLogFile.c_str(),std::ios::app);
00949
00950 logFile << asctime (timeinfo) << " - " << logData << "\n";
00951
00952 logFile.close();
00953 unlockFile(itsLogFile,fd,fl);
00954 }
00955
00956
00957 void SimulationViewerNerdCam::drawDateTime(Image<PixRGB<byte> >& image) const
00958 {
00959 time_t rawtime; struct tm * timeinfo;
00960 time ( &rawtime ); timeinfo = localtime ( &rawtime );
00961
00962 writeText(image, Point2D<int>(0, 0), asctime (timeinfo));
00963 }
00964
00965
00966 void SimulationViewerNerdCam::drawFOA()
00967 {
00968 if (itsCurrFOA.isValid() == false) return;
00969
00970
00971 PixRGB<byte> col(itsColorNormal.getVal());
00972 if (itsCurrFOA.boring) col -= itsColorBoring.getVal();
00973
00974
00975 drawPatch(itsTraj, itsCurrFOA.p, itsFOApsiz.getVal(), col);
00976
00977
00978 if (itsDisplayFOA.getVal())
00979 drawMaskOutline(itsTraj, itsCurrFOAmask, col, itsFOAthick.getVal(),
00980 itsCurrFOA.p, itsMetrics->getFOAradius());
00981 }
00982
00983
00984 void SimulationViewerNerdCam::linkFOAs()
00985 {
00986 if (itsCurrFOA.isValid() == false) return;
00987
00988 const PixRGB<byte> col = itsColorLink.getVal();
00989 if (itsPrevFOA.isValid())
00990 {
00991 int d = int(itsPrevFOA.p.distance(itsCurrFOA.p));
00992 if (d > 0) drawArrow(itsTraj, itsPrevFOA.p, itsCurrFOA.p,
00993 col, itsFOAlinkThick.getVal());
00994 }
00995 }
00996
00997
00998 Image< PixRGB<byte> > SimulationViewerNerdCam::
00999 drawMegaCombo(SimEventQueue& q) const
01000 {
01001 LINFO("Drawing Mega Combo");
01002
01003 const PixRGB<byte> bg(128, 128, 255);
01004 const short XWW = itsTraj.getWidth() * 2;
01005 const short XWH = itsTraj.getHeight() * 2;
01006 Image< PixRGB<byte> > xwi(XWW/2, XWH/2, ZEROS);
01007 Image< PixRGB<byte> > xwin(XWW, XWH, ZEROS);
01008
01009 Rectangle r(Point2D<int>(0,0), Dims(XWW/2, XWH/2));
01010 inplaceEmbed(xwi, itsTraj, r, bg, true);
01011 inplacePaste(xwin, xwi, Point2D<int>(0, 0));
01012
01013
01014 const Image<float> agm = getMap(q);
01015 Image< PixRGB<byte> > xwi2(XWW/2, XWH/2, NO_INIT);
01016
01017
01018 Image<float> trm;
01019 if (SeC<SimEventTaskRelevanceMapOutput> e =
01020 q.check<SimEventTaskRelevanceMapOutput>(this, SEQ_ANY))
01021 trm = e->trm(1.0F);
01022 else LFATAL("Cannot find a TRM!");
01023
01024
01025
01026 Image<byte> rr, gg, bb;
01027 Image<float> trmfac(trm);
01028 inplaceClamp(trmfac, 0.0F, 1.0F);
01029 trmfac *= -1.0F; trmfac += 1.0F;
01030 rr = trmfac * 255.0F;
01031 trmfac = trm;
01032 inplaceClamp(trmfac, 1.0F, 3.0F);
01033 trmfac -= 1.0F;
01034 gg = trmfac * 127.5F;
01035 bb = agm;
01036
01037
01038 Image<PixRGB<byte> > cbtmp = rescale(makeRGB(rr, gg, bb), XWW/2, XWH/2);
01039 inplaceEmbed(xwi2, cbtmp, r, PixRGB<byte>(192, 192, 192), true);
01040 writeText(xwi2, Point2D<int>(0,0), " Attention Map ");
01041 inplacePaste(xwin, xwi2, Point2D<int>(XWW/2, 0));
01042
01043
01044 r = Rectangle::tlbrI(0, 0, XWH/4 - 1, XWW/4 - 1);
01045 xwi2.resize(XWW/4, XWH/4);
01046
01047 LFATAL("FIXME I should derive from SimulationViewerStd");
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129 return xwin;
01130 }
01131
01132
01133 void SimulationViewerNerdCam::drawMaskOutline(Image< PixRGB<byte> >& traj,
01134 const Image<byte> mask,
01135 const PixRGB<byte>& col,
01136 const int thick,
01137 const Point2D<int>& pos,
01138 const int radius) const
01139 {
01140 if (traj.initialized() == false) return;
01141
01142
01143 Image<byte> om(mask);
01144 inplaceLowThresh(om, byte(128));
01145 om = contour2D(om);
01146 const int w = traj.getWidth();
01147 const int h = traj.getHeight();
01148 Point2D<int> ppp;
01149 for (ppp.j = 0; ppp.j < h; ppp.j ++)
01150 for (ppp.i = 0; ppp.i < w; ppp.i ++)
01151 if (om.getVal(ppp.i, ppp.j))
01152 drawDisk(traj, ppp, thick, col);
01153
01154 }
01155
01156
01157
01158
01159
01160