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
00040
00041
00042
00043
00044
00045
00046 #include "Beowulf/Beowulf.H"
00047 #include "Component/ModelManager.H"
00048 #include "Devices/DeviceOpts.H"
00049 #include "Devices/FrameGrabberConfigurator.H"
00050 #include "GUI/XWindow.H"
00051 #include "Image/CutPaste.H"
00052 #include "Image/DrawOps.H"
00053 #include "Image/FilterOps.H"
00054 #include "Image/Image.H"
00055 #include "Image/ImageSet.H"
00056 #include "Image/ShapeOps.H"
00057 #include "Media/FrameSeries.H"
00058 #include "Neuro/NeuroOpts.H"
00059 #include "Neuro/SaccadeController.H"
00060 #include "Neuro/SaccadeControllerConfigurator.H"
00061 #include "Simulation/SimEventQueue.H"
00062 #include "Simulation/SimEventQueueConfigurator.H"
00063 #include "Transport/FrameIstream.H"
00064 #ifdef HAVE_SDL_SDL_H
00065 #include "Psycho/PsychoDisplay.H"
00066 #endif
00067 #include "Util/Assert.H"
00068 #include "Util/Timer.H"
00069 #include "VFAT/featureClusterVision.H"
00070 #include "Video/RgbConversion.H"
00071
00072 #include <signal.h>
00073 #include <unistd.h>
00074
00075
00076
00077 #define BEO_RETINA 1
00078 #define BEO_WINNER 2
00079 #define BEO_LUMINANCE 3
00080 #define BEO_REDGREEN 4
00081 #define BEO_BLUEYELLOW 5
00082 #define BEO_ORI0 6
00083 #define BEO_ORI45 7
00084 #define BEO_ORI90 8
00085 #define BEO_ORI135 9
00086 #define BEO_CMAP 10
00087 #define BEO_FLICKER 11
00088
00089
00090 #define NBCMAP 7
00091
00092
00093 #define NBCMAP2 8
00094
00095
00096 #define POFFSET 8
00097
00098
00099 #define NAVG 20
00100
00101
00102 #define PRESCALE 2
00103
00104 static bool goforever = true;
00105
00106
00107 void terminate(int s)
00108 { LERROR("*** INTERRUPT ***"); goforever = false; exit(1); }
00109
00110
00111 void receiveCMAPS(nub::soft_ref<Beowulf>& beo, std::vector<Image<float> > *cmap,
00112 int32 *cmapframe);
00113
00114
00115 extern "C" int main(const int argc, char** argv)
00116 {
00117 #ifndef HAVE_SDL_SDL_H
00118
00119 LFATAL("<SDL/SDL.h> must be installed to use this program");
00120
00121 #else
00122
00123 MYLOGVERB = LOG_INFO;
00124
00125
00126 ModelManager manager("Parallel Vision TCP Version 3");
00127
00128
00129 nub::soft_ref<SimEventQueueConfigurator>
00130 seqc(new SimEventQueueConfigurator(manager));
00131 manager.addSubComponent(seqc);
00132
00133 nub::soft_ref<FrameGrabberConfigurator>
00134 gbc(new FrameGrabberConfigurator(manager));
00135 manager.addSubComponent(gbc);
00136
00137 nub::soft_ref<Beowulf>
00138 beo(new Beowulf(manager, "Beowulf Master", "BeowulfMaster", true));
00139 manager.addSubComponent(beo);
00140
00141 nub::soft_ref<PsychoDisplay>
00142 d(new PsychoDisplay(manager));
00143 manager.addSubComponent(d);
00144
00145
00146 nub::soft_ref<InputFrameSeries> ifs(new InputFrameSeries(manager));
00147 manager.addSubComponent(ifs);
00148
00149
00150
00151 nub::soft_ref<SaccadeControllerEyeConfigurator>
00152 scc(new SaccadeControllerEyeConfigurator(manager));
00153 manager.addSubComponent(scc);
00154
00155
00156 manager.setOptionValString(&OPT_SaccadeControllerEyeType, "Threshfric");
00157 manager.setOptionValString(&OPT_FrameGrabberType, "V4L");
00158 manager.setOptionValString(&OPT_SCeyeMaxIdleSecs, "1000.0");
00159 manager.setOptionValString(&OPT_SCeyeThreshMinOvert, "4.0");
00160 manager.setOptionValString(&OPT_SCeyeThreshMaxCovert, "3.0");
00161
00162
00163
00164 if (manager.parseCommandLine(argc, argv, "", 0, 0) == false) return(1);
00165
00166
00167 nub::soft_ref<SimEventQueue> seq = seqc->getQ();
00168
00169 nub::soft_ref<FrameIstream> gb = gbc->getFrameGrabber();
00170 if (gb.isInvalid())
00171 LFATAL("You need to select a frame grabber type via the "
00172 "--fg-type=XX command-line option for this program "
00173 "to be useful");
00174 int w = gb->getWidth(), h = gb->getHeight();
00175
00176 nub::ref<SaccadeController> sc = scc->getSC();
00177
00178 int foa_size = std::min(w, h) / 12;
00179 manager.setModelParamVal("InputFrameDims", Dims(w, h),
00180 MC_RECURSE | MC_IGNORE_MISSING);
00181 manager.setModelParamVal("SCeyeStartAtIP", true,
00182 MC_RECURSE | MC_IGNORE_MISSING);
00183 manager.setModelParamVal("SCeyeInitialPosition",Point2D<int>(w/2,h/2),
00184 MC_RECURSE | MC_IGNORE_MISSING);
00185 manager.setModelParamVal("FOAradius", foa_size,
00186 MC_RECURSE | MC_IGNORE_MISSING);
00187 manager.setModelParamVal("FoveaRadius", foa_size,
00188 MC_RECURSE | MC_IGNORE_MISSING);
00189
00190
00191 signal(SIGHUP, terminate); signal(SIGINT, terminate);
00192 signal(SIGQUIT, terminate); signal(SIGTERM, terminate);
00193 signal(SIGALRM, terminate);
00194
00195
00196 int32 frame = 0;
00197 PixRGB<byte> pix(255, 255, 0);
00198 TCPmessage smsg;
00199
00200 uint64 avgtime = 0; int avgn = 0;
00201 float fps = 0.0F;
00202 Timer tim;
00203 Timer masterclock;
00204
00205 Image<float> bimage;
00206 std::vector<Image<float> > cmap(NBCMAP2,bimage);
00207 int32 cmapframe[NBCMAP2];
00208 for (int i = 0; i < NBCMAP2; i ++) cmapframe[i] = -1;
00209 int sml = 4;
00210 Image<float> sm(w >> sml, h >> sml, ZEROS);
00211 Point2D<int> fixation(-1, -1);
00212 const std::string name = "featureCluster";
00213 const std::string tag = "fCV";
00214
00215 featureClusterVision<float> fCVout(manager,name,tag,&sm,&cmap,ifs,
00216 manager.getExtraArg(0));
00217
00218 nub::soft_ref<featureClusterVision<float> >
00219 fCV(&fCVout);
00220 manager.addSubComponent(fCV);
00221
00222
00223
00224 Image<PixRGB<byte> > disp(w * 2, h + 20, ZEROS);
00225 disp += d->getGrey();
00226 int dw = d->getDims().w(), dh = d->getDims().h();
00227 ASSERT(dw == w * 2); ASSERT(dh >= disp.getHeight());
00228 int ovlyoff = (w * 2) * ((dh - disp.getHeight()) / 2);
00229 int ovluvoff = ovlyoff / 4;
00230
00231 char info[1000];
00232
00233
00234 manager.start();
00235
00236
00237 d->clearScreen();
00238 d->displayText("<SPACE> to start - <SPACE> again to quit");
00239 while(d->waitForKey() != ' ') ;
00240 d->clearScreen();
00241
00242
00243 d->createYUVoverlay(SDL_YV12_OVERLAY);
00244
00245
00246 gb->startStream();
00247
00248
00249
00250 tim.reset(); masterclock.reset();
00251 XWindow win1(Dims(720, 480), 0, 0, "CLASSES");
00252 Image<PixRGB<float> > fima1; Image<PixRGB<byte> > bima1;
00253 XWindow win2(Dims(720, 480), 0, 0, "CLASSES TEMPORAL");
00254 Image<PixRGB<float> > fima2; Image<PixRGB<byte> > bima2;
00255 XWindow win3(Dims(720, 480), 0, 0, "TARGETS TEMPORAL");
00256 Image<PixRGB<float> > fima3; Image<PixRGB<byte> > bima3;
00257 XWindow win4(Dims(720, 480), 0, 0, "SALIENCY MAP");
00258 Image<float> fima4; Image<PixRGB<byte> > bima4;
00259
00260
00261 while(goforever)
00262 {
00263
00264 receiveCMAPS(beo, &cmap, cmapframe);
00265
00266
00267 Image< PixRGB<byte> > ima = gb->readRGB();
00268 std::string myname;
00269 myname = "Beowulf." + frame;
00270 fCVout.fCVuploadImage(ima,myname);
00271
00272
00273 inplacePaste(disp, ima, Point2D<int>(0, 0));
00274 Image<float> dispsm(sm); inplaceNormalize(dispsm, 0.0F, 255.0F);
00275 inplacePaste(disp,
00276 Image<PixRGB<byte> >(toRGB(quickInterpolate(dispsm, 1 << sml))),
00277 Point2D<int>(w, 0));
00278
00279 sc->evolve(*seq);
00280 Point2D<int> eye = sc->getDecision(*seq);
00281 if (eye.i >= 0) fixation = eye;
00282 if (fixation.i >= 0)
00283 {
00284 drawPatch(disp, fixation, 2, pix);
00285 drawCircle(disp, fixation, foa_size, pix, 2);
00286 }
00287 sprintf(info, "%.1ffps", fps);
00288 writeText(disp, Point2D<int>(w, 0), info, PixRGB<byte>(255), PixRGB<byte>(0));
00289
00290 SDL_Overlay* ovl = d->lockYUVoverlay();
00291 toVideoYUV422(disp, ovl->pixels[0] + ovlyoff,
00292 ovl->pixels[2] + ovluvoff,
00293 ovl->pixels[1] + ovluvoff);
00294 d->unlockYUVoverlay();
00295 d->displayYUVoverlay(-1, SDLdisplay::NO_WAIT);
00296
00297
00298
00299 if (d->checkForKey() == ' ') goforever = false;
00300
00301
00302 receiveCMAPS(beo, &cmap, cmapframe);
00303
00304
00305 if (frame & 1)
00306 {
00307
00308 Image<PixRGB<byte> > ima2 =
00309 decY(lowPass5y(decX(lowPass5x(ima),1<<PRESCALE)),1<<PRESCALE);
00310
00311
00312
00313 Image<byte> lum = luminance(ima2);
00314
00315
00316 smsg.reset(frame, BEO_ORI0); smsg.addImage(lum); beo->send(smsg);
00317 smsg.setAction(BEO_ORI45); beo->send(smsg);
00318 smsg.setAction(BEO_ORI90); beo->send(smsg);
00319 smsg.setAction(BEO_ORI135); beo->send(smsg);
00320
00321
00322 smsg.setAction(BEO_FLICKER); beo->send(smsg);
00323
00324
00325 smsg.setAction(BEO_LUMINANCE); beo->send(smsg);
00326
00327
00328 Image<byte> r, g, b, y; getRGBY(ima2, r, g, b, y, (byte)25);
00329 smsg.reset(frame, BEO_REDGREEN);
00330 smsg.addImage(r); smsg.addImage(g); beo->send(smsg);
00331 smsg.reset(frame, BEO_BLUEYELLOW);
00332 smsg.addImage(b); smsg.addImage(y); beo->send(smsg);
00333 }
00334
00335
00336 receiveCMAPS(beo, &cmap, cmapframe);
00337
00338
00339 sprintf(info, "%06d / ", frame);
00340 Image<float> sminput;
00341 for (int i = 0; i < NBCMAP2; i ++)
00342 if (cmap[i].initialized())
00343 {
00344 if (sminput.initialized()) sminput += cmap[i];
00345 else sminput = cmap[i];
00346 char num[10]; sprintf(num, "%06d ", cmapframe[i]);
00347 strcat(info, num);
00348 }
00349 else
00350 strcat(info, "------ ");
00351 writeText(disp, Point2D<int>(0, h), info,
00352 PixRGB<byte>(255), d->getGrey());
00353
00354
00355 if (sminput.initialized()) sm = sm * 0.7F + sminput * 0.3F;
00356
00357
00358 while(seq->now() < masterclock.getSimTime()) seq->evolve();
00359 sc->evolve(*seq);
00360
00361
00362 float maxval; Point2D<int> currwin; findMax(sm, currwin, maxval);
00363 WTAwinner newwin =
00364 WTAwinner::buildFromSMcoords(currwin, sml, true,
00365 masterclock.getSimTime(),
00366 maxval, false);
00367 if (newwin.isValid()) sc->setPercept(newwin, *seq);
00368
00369 fCVout.fCVgetClusterImages(&fima1,&fima2,&fima3,&fima4);
00370 bima1 = fima1; bima2 = fima2; bima3 = fima3;
00371 win1.drawImage(bima1);
00372 win2.drawImage(bima2);
00373 win3.drawImage(bima3);
00374
00375
00376 receiveCMAPS(beo, &cmap, cmapframe);
00377
00378
00379 avgtime += tim.getReset(); avgn ++;
00380 if (avgn == NAVG)
00381 {
00382 fps = 1000.0F / float(avgtime) * float(avgn);
00383 avgtime = 0; avgn = 0;
00384 }
00385
00386
00387 frame++;
00388 while(seq->now() < masterclock.getSimTime()) seq->evolve();
00389 }
00390
00391
00392 d->destroyYUVoverlay();
00393 LINFO("Normal exit");
00394 manager.stop();
00395 return 0;
00396
00397 #endif // HAVE_SDL_SDL_H
00398
00399 }
00400
00401
00402 void receiveCMAPS(nub::soft_ref<Beowulf>& beo, std::vector<Image<float> > *cmap,
00403 int32 *cmapframe)
00404 {
00405 TCPmessage rmsg;
00406 int32 rframe, raction, rnode = -1, recnb=0;
00407 while(beo->receive(rnode, rmsg, rframe, raction))
00408 {
00409
00410
00411 switch(raction & 0xffff)
00412 {
00413 case BEO_CMAP:
00414 {
00415
00416 Image<float> ima = rmsg.getElementFloatIma();
00417
00418
00419
00420 int32 mapn = raction >> 16;
00421 if (mapn < 0 || mapn >= NBCMAP2) {
00422 LERROR("Bogus cmap number ignored");
00423 break;
00424 }
00425
00426
00427
00428
00429
00430 if (cmapframe[mapn] < rframe)
00431 { cmap->at(mapn) = ima; cmapframe[mapn] = rframe; }
00432 }
00433
00434 break;
00435 default:
00436 LERROR("Bogus action %d -- IGNORING.", raction);
00437 break;
00438 }
00439
00440 recnb ++; if (recnb > NBCMAP2 * 2) break;
00441 }
00442 }
00443
00444
00445
00446
00447
00448