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 #include "Beobot/Landmark.H"
00043 #include "Channels/ChannelOpts.H"
00044 #include "Component/GlobalOpts.H"
00045 #include "Component/ModelManager.H"
00046 #include "Component/ModelOptionDef.H"
00047 #include "Component/OptionManager.H"
00048 #include "GUI/XWinManaged.H"
00049 #include "Gist/FFN.H"
00050 #include "Gist/trainUtils.H"
00051 #include "Image/ColorOps.H"
00052 #include "Image/CutPaste.H"
00053 #include "Image/DrawOps.H"
00054 #include "Image/MathOps.H"
00055 #include "Image/Pixels.H"
00056 #include "Image/ShapeOps.H"
00057 #include "Image/Transforms.H"
00058 #include "Media/MPEGStream.H"
00059 #include "Media/MediaOpts.H"
00060 #include "Media/MediaSimEvents.H"
00061 #include "Neuro/GistEstimator.H"
00062 #include "Neuro/InferoTemporal.H"
00063 #include "Neuro/NeuroOpts.H"
00064 #include "Neuro/NeuroSimEvents.H"
00065 #include "Neuro/Retina.H"
00066 #include "Neuro/ShapeEstimator.H"
00067 #include "Neuro/ShapeEstimatorModes.H"
00068 #include "Neuro/SpatialMetrics.H"
00069 #include "Neuro/StdBrain.H"
00070 #include "Neuro/gistParams.H"
00071 #include "Neuro/VisualCortex.H"
00072 #include "Raster/Raster.H"
00073 #include "SIFT/CameraIntrinsicParam.H"
00074 #include "SIFT/Histogram.H"
00075 #include "SIFT/Keypoint.H"
00076 #include "SIFT/VisualObject.H"
00077 #include "SIFT/VisualObjectDB.H"
00078 #include "Simulation/SimEventQueueConfigurator.H"
00079 #include "Util/Timer.H"
00080
00081 #include <iostream>
00082 #include <fstream>
00083
00084
00085 #include "SIFT/SIFTegomotion.H"
00086
00087 #define DB_NAME "out_database"
00088
00089 #define W_ASPECT_RATIO 320 // ideal minimum width for display
00090 #define H_ASPECT_RATIO 240 // ideal minimum height for display
00091
00092 FeedForwardNetwork *ffn_place;
00093 double **gistW = NULL;
00094
00095 CloseButtonListener wList;
00096 rutz::shared_ptr<XWinManaged> salWin;
00097 rutz::shared_ptr<XWinManaged> objWin;
00098 rutz::shared_ptr<XWinManaged> trajWin;
00099
00100 int wDisp, hDisp, sDisp, scaleDisp;
00101 int wDispWin, hDispWin;
00102
00103
00104 int pcaW = 16, pcaH = 5;
00105 int winBarW = 5, winBarH = 25;
00106
00107
00108 int numObj = 0;
00109
00110
00111 void setupDispWin (int w, int h);
00112 Image< PixRGB<byte> > getSalDispImg (Image< PixRGB<byte> > img, Image<float> roiImg,
00113 Image< PixRGB<byte> > objImg, Image< PixRGB<byte> > objImg2);
00114 void processSalCue (Image<PixRGB<byte> > inputImg,
00115 nub::soft_ref<StdBrain> brain, Point2D<int> winner, int fNum,
00116 std::vector< rutz::shared_ptr<Landmark> >& landmarks,
00117 const Image<float>& semask, const std::string& selabel);
00118 void getGistFileList (std::string fName, std::vector<std::string>& tag,
00119 std::vector<int>& start, std::vector<int>& num);
00120 Image< PixRGB<byte> > getTrajImg (std::vector<Image <double> > traj, int w, int h);
00121
00122
00123
00124
00125
00126
00127 int main(const int argc, const char **argv)
00128 {
00129 MYLOGVERB = LOG_INFO;
00130
00131
00132 ModelManager manager("Egomotion Model");
00133
00134
00135
00136 manager.allowOptions(OPTEXP_ALL & (~OPTEXP_SAVE));
00137
00138
00139 nub::soft_ref<SimEventQueueConfigurator>
00140 seqc(new SimEventQueueConfigurator(manager));
00141 manager.addSubComponent(seqc);
00142
00143 nub::soft_ref<InputMPEGStream>
00144 ims(new InputMPEGStream(manager, "Input MPEG Stream", "InputMPEGStream"));
00145 manager.addSubComponent(ims);
00146
00147 nub::soft_ref<StdBrain> brain(new StdBrain(manager));
00148 manager.addSubComponent(brain);
00149
00150 nub::ref<SpatialMetrics> metrics(new SpatialMetrics(manager));
00151 manager.addSubComponent(metrics);
00152
00153 manager.exportOptions(true);
00154 metrics->setFOAradius(30);
00155 metrics->setFoveaRadius(30);
00156 manager.setOptionValString(&OPT_MaxNormType, "FancyOne");
00157 manager.setOptionValString(&OPT_UseRandom, "false");
00158
00159 manager.setOptionValString(&OPT_IORtype, "Disc");
00160 manager.setOptionValString(&OPT_RawVisualCortexChans,"OIC");
00161
00162
00163
00164
00165 manager.setOptionValString(&OPT_ShapeEstimatorMode, "FeatureMap");
00166 manager.setOptionValString(&OPT_ShapeEstimatorSmoothMethod, "Chamfer");
00167
00168
00169
00170
00171
00172
00173
00174
00175 REQUEST_OPTIONALIAS_NEURO(manager);
00176
00177
00178 if (manager.parseCommandLine(argc, argv, "<*.mpg or *_gistList.txt>",
00179 1, 1) == false)
00180 return(1);
00181
00182 nub::soft_ref<SimEventQueue> seq = seqc->getQ();
00183
00184
00185
00186 bool isGistListInput = false;
00187 int ifLen = manager.getExtraArg(0).length();
00188 if(ifLen > 13 &&
00189 manager.getExtraArg(0).find("_gistList.txt",ifLen - 13) != std::string::npos)
00190 isGistListInput = true;
00191
00192
00193
00194 manager.setOptionValString(&OPT_InputMPEGStreamPreload, "true");
00195
00196
00197 std::vector<std::string> tag;
00198 std::vector<int> start;
00199 std::vector<int> num;
00200 if(isGistListInput)
00201 {
00202 LINFO("we have a gistList input");
00203 getGistFileList(manager.getExtraArg(0).c_str(), tag, start, num);
00204 }
00205 else
00206 {
00207 LINFO("we have an mpeg input");
00208 ims->setFileName(manager.getExtraArg(0));
00209 manager.setOptionValString(&OPT_InputFrameDims,
00210 convertToString(ims->peekDims()));
00211 }
00212
00213
00214 double rtdelay = 33.3667/1000.0;
00215 double fdelay = rtdelay * 3;
00216 (void)fdelay;
00217
00218
00219 manager.start();
00220
00221
00222 rutz::shared_ptr<Landmark> scene(new Landmark());
00223 scene->setMatchWin(objWin);
00224
00225
00226 rutz::shared_ptr<CameraIntrinsicParam>
00227 cip(new CameraIntrinsicParam(435.806712867904707, 438.523234664943345,
00228 153.585228257964644, 83.663180940275609, 0.0));
00229 scene->setCameraIntrinsicParam(cip);
00230
00231
00232 SimTime prevstime = SimTime::ZERO(); uint fNum = 0;
00233 Image< PixRGB<byte> > inputImg;
00234 Image< PixRGB<byte> > dispImg;
00235 int w = 0;
00236 int h = 0;
00237 unsigned int cLine = 0;
00238 int cIndex = start[0];
00239 std::string folder = "";
00240 std::string::size_type sPos = manager.getExtraArg(0).rfind("/",ifLen);
00241 if(sPos != std::string::npos)
00242 folder = manager.getExtraArg(0).substr(0,sPos+1);
00243 std::vector<Image<double> > traj;
00244 while(1)
00245 {
00246
00247
00248 if (fNum == 0 ||
00249 (seq->now() - 0.5 * (prevstime - seq->now())).secs() - fNum * fdelay > fdelay)
00250 {
00251
00252 std::string fName;
00253 if(isGistListInput)
00254 {
00255 if (cLine >= tag.size()) break;
00256
00257
00258 char tNumStr[100]; sprintf(tNumStr,"%06d",cIndex);
00259 fName = folder + tag[cLine] + std::string(tNumStr) + ".ppm";
00260
00261 inputImg = Raster::ReadRGB(fName);
00262 cIndex++;
00263
00264 if(cIndex >= start[cLine] + num[cLine])
00265 {
00266 cLine++;
00267 if (cLine < tag.size()) cIndex = start[cLine];
00268 }
00269
00270
00271 int fNameLen = fName.length();
00272 unsigned int uPos = fName.rfind("_",fNameLen);
00273 fName = fName.substr(0,uPos)+ ".ppm";
00274 }
00275 else
00276 {
00277 fName = manager.getExtraArg(0);
00278 inputImg = ims->readRGB();
00279 if (inputImg.initialized() == false) break;
00280
00281 inputImg = crop(inputImg,
00282 Rectangle::tlbrI(0,25,inputImg.getHeight()-1, inputImg.getWidth()-25));
00283 cIndex = fNum+1;
00284 }
00285
00286
00287
00288 if (fNum == 0)
00289 {
00290 w = inputImg.getWidth(); h = inputImg.getHeight();
00291 setupDispWin(w, h); LINFO("w: %d, h: %d",w, h);
00292 }
00293
00294 dispImg = inputImg;
00295 salWin->drawImage(dispImg,0,0);
00296 LINFO("\nnew frame :%d",fNum);
00297
00298
00299
00300
00301
00302 rutz::shared_ptr<SimEventInputFrame>
00303 e(new SimEventInputFrame(brain.get(), GenericFrame(inputImg), 0));
00304 seq->post(e);
00305
00306
00307 std::string viewName(sformat("view%07d", fNum));
00308 rutz::shared_ptr<VisualObject>
00309 cv(new VisualObject(viewName, "", inputImg));
00310 rutz::shared_ptr<VisualObjectMatch> cmatch = scene->build(cv, fNum);
00311
00312
00313 if(fNum != 0)
00314 {
00315 rutz::shared_ptr<SIFTegomotion>
00316 egm(new SIFTegomotion(cmatch, cip, objWin));
00317
00318
00319
00320
00321 traj.push_back(egm->getItsVel());
00322 egm->print(traj[traj.size() -1] ,"final velocity");
00323 trajWin->drawImage(getTrajImg(traj, 5*w, 2*h),0,0);
00324
00325 }
00326
00327
00328 fNum++;
00329 }
00330
00331
00332 prevstime = seq->now();
00333 const SimStatus status = seq->evolve();
00334
00335
00336 if (SeC<SimEventWTAwinner> e = seq->check<SimEventWTAwinner>(0))
00337 {
00338 const Point2D<int> winner = e->winner().p;
00339 LINFO("Frame: %d, winner: (%d,%d)", fNum, winner.i, winner.j);
00340
00341 Image<float> semask; std::string selabel;
00342 if (SeC<SimEventShapeEstimatorOutput>
00343 e = seq->check<SimEventShapeEstimatorOutput>(0))
00344 { semask = e->smoothMask(); selabel = e->winningLabel(); }
00345
00346
00347
00348
00349 if (SIM_BREAK == status)
00350 break;
00351 }
00352 }
00353
00354
00355
00356
00357
00358
00359 manager.stop();
00360
00361
00362 return 0;
00363 }
00364
00365
00366
00367 void processSalCue(const Image<PixRGB<byte> > inputImg,
00368 nub::soft_ref<StdBrain> brain, Point2D<int> winner, int fNum,
00369 std::vector< rutz::shared_ptr<Landmark> >& landmarks,
00370 const Image<float>& semask, const std::string& selabel)
00371 {
00372
00373
00374
00375
00376 Image<float> roiImg;
00377 Image<PixRGB<byte> > objImgSE;
00378 Point2D<int> objOffsetSE;
00379 if (semask.initialized())
00380 {
00381 roiImg = semask * luminance(inputImg);
00382
00383 float mn, mx; getMinMax(semask,mn,mx);
00384 Rectangle r = findBoundingRect(semask, mx*.05f);
00385 Image<PixRGB<byte> > objImgSE = crop(inputImg, r);
00386 objOffsetSE = Point2D<int>(r.left(),r.top());
00387 }
00388 else
00389 {
00390 LINFO("SE Smooth Mask not yet initialized");
00391 roiImg = luminance(inputImg);
00392 objImgSE = inputImg;
00393 objOffsetSE = Point2D<int>(0,0);
00394 }
00395
00396
00397
00398 Rectangle roi =
00399 Rectangle::tlbrI(winner.j - 50, winner.i - 50,
00400 winner.j + 50, winner.i + 50);
00401 roi = roi.getOverlap(inputImg.getBounds());
00402 LINFO("[%d,%d,%d,%d]",roi.top(),roi.left(),roi.bottomI(),roi.rightI());
00403 Image<PixRGB<byte> > objImgWIN = crop(inputImg, roi);
00404 Point2D<int> objOffsetWIN(roi.left(),roi.top());
00405
00406
00407
00408 LINFO("TOP LEFT at: SE:(%d,%d) WIN:(%d,%d)",
00409 objOffsetSE.i , objOffsetSE.j,
00410 objOffsetWIN.i , objOffsetWIN.j);
00411
00412
00413 drawCircle(roiImg, winner, 10, 0.0f, 1);
00414 drawPoint(roiImg, winner.i, winner.j, 0.0f);
00415 LINFO("Frame: %d, winner: (%d,%d) in %s", fNum, winner.i, winner.j,
00416 selabel.c_str());
00417 salWin->drawImage(getSalDispImg(inputImg,roiImg,objImgWIN,objImgSE),0,0);
00418
00419 Raster::waitForKey();
00420
00421
00422 Image<PixRGB<byte> > objImg(objImgSE);
00423 Point2D<int> objOffset(objOffsetSE);
00424
00425
00426 LFATAL("fixme using a SimReq");
00427
00428 std::vector<float> fvec;
00429
00430
00431
00432 rutz::shared_ptr<VisualObject>
00433 obj(new VisualObject("NewObject", "NewObject",
00434 objImg, winner - objOffset, fvec));
00435
00436 std::string objName(sformat("obj%07d", numObj));
00437 obj->setName(objName);
00438 obj->setImageFname(objName + ".png");
00439 numObj++;
00440
00441
00442 int trackAccepted = 0;
00443 LINFO("we have: %"ZU" landmarks to match", landmarks.size());
00444 for(uint i = 0; i < landmarks.size(); i++)
00445 {
00446 LINFO("tracking landmark number: %d",i);
00447 rutz::shared_ptr<VisualObjectMatch> cmatch =
00448 landmarks[i]->build(obj, objOffset, fNum);
00449 if(cmatch.is_valid() && cmatch->getScore() > 3.0)
00450 trackAccepted++;
00451 }
00452
00453
00454 if(trackAccepted == 0)
00455 {
00456
00457 LINFO("create a new Landmark number %"ZU,landmarks.size());
00458 std::string lmName(sformat("landmark%07"ZU, landmarks.size()));
00459 rutz::shared_ptr<Landmark>
00460 newlm(new Landmark(obj, objOffset, fNum, lmName));
00461 newlm->setMatchWin(objWin);
00462 landmarks.push_back(newlm);
00463 Raster::waitForKey();
00464 }
00465 else if(trackAccepted > 1)
00466 {
00467 LINFO("May have: %d objects jumbled together", trackAccepted);
00468 }
00469 }
00470
00471
00472 void getGistFileList(std::string fName, std::vector<std::string>& tag,
00473 std::vector<int>& start, std::vector<int>& num)
00474 {
00475 char comment[200]; FILE *fp; char inLine[100];
00476
00477
00478 if((fp = fopen(fName.c_str(),"rb")) == NULL)
00479 LFATAL("samples file: %s not found",fName.c_str());
00480 LINFO("fName: %s",fName.c_str());
00481
00482
00483 int nSamples; if (fgets(inLine, 1000, fp) == NULL) LFATAL("fgets failed"); sscanf(inLine, "%d %s", &nSamples, comment);
00484
00485
00486 int tNcat; if (fgets(inLine, 1000, fp) == NULL) LFATAL("fgets failed"); sscanf(inLine, "%d %s", &tNcat, comment);
00487
00488
00489 char gtOpt[100]; if (fgets(inLine, 1000, fp) == NULL) LFATAL("fgets failed"); sscanf(inLine, "%s %s", gtOpt, comment);
00490
00491
00492 if (fgets(inLine, 1000, fp) == NULL) LFATAL("fgets failed");
00493
00494 char cName[100]; char ext[100]; int cStart, cNum; int gTruth;
00495 while(fgets(inLine, 1000, fp) != NULL)
00496 {
00497
00498 sscanf(inLine, "%s %d %d %d %s", cName, &cStart, &cNum, &gTruth, ext);
00499 LINFO(" sName: %s %d %d %d %s",cName, cStart, cNum, gTruth, ext);
00500
00501 tag.push_back(cName);
00502 start.push_back(cStart);
00503 num.push_back(cNum);
00504 }
00505 fclose(fp);
00506 }
00507
00508
00509
00510 void setupDispWin(int w, int h)
00511 {
00512 salWin.reset(new XWinManaged(Dims(2*w, 2*h), 2*w, 0, "Saliency Related" ));
00513 wList.add(*salWin);
00514
00515 objWin.reset(new XWinManaged(Dims(2*w, 2*h), 0, 0, "Object Match" ));
00516 wList.add(*objWin);
00517
00518 trajWin.reset(new XWinManaged(Dims(5*w, 2*h), 0, 0, "Trajectory" ));
00519 wList.add(*objWin);
00520 }
00521
00522
00523
00524 Image< PixRGB<byte> > getSalDispImg (Image< PixRGB<byte> > img,
00525 Image<float> roiImg,
00526 Image< PixRGB<byte> > objImg,
00527 Image< PixRGB<byte> > objImg2)
00528 {
00529 int w = img.getWidth(), h = img.getHeight();
00530 Image< PixRGB<byte> > salDispImg(2*w,2*h,ZEROS);
00531
00532 inplacePaste(salDispImg, img, Point2D<int>(0, 0));
00533 Image< PixRGB<byte> > t = makeRGB(roiImg,roiImg,roiImg);
00534 inplacePaste(salDispImg, t, Point2D<int>(0, h));
00535 inplacePaste(salDispImg, objImg, Point2D<int>(w, 0));
00536 inplacePaste(salDispImg, objImg2, Point2D<int>(w, h));
00537
00538 return salDispImg;
00539 }
00540
00541
00542
00543 Image< PixRGB<byte> > getTrajImg (std::vector<Image <double> > traj, int w, int h)
00544 {
00545 Image< PixRGB<byte> > trajImg(w, h, ZEROS);
00546
00547 int sX = 10; int sY = h/2;
00548
00549
00550 double scale = 5.0;
00551 double locX = double(sX);
00552 double locY = double(sY);
00553
00554
00555 for(uint i = 0; i < traj.size(); i++)
00556 {
00557 double dX = traj[i].getVal(0,2)*scale;
00558 double dY = -traj[i].getVal(0,0)*scale;
00559 LINFO("%d. %f,%f -> dx: %f, dy: %f ", i, traj[i].getVal(0,2), traj[i].getVal(0,0),
00560 dX,dY);
00561
00562 drawDisk(trajImg, Point2D<int>(int(locX),int(locY)), 2, PixRGB<byte>(255,0,0));
00563 drawLine (trajImg,
00564 Point2D<int>(int(locX),int(locY)),
00565 Point2D<int>(int(locX + dX),int(locY + dY)),
00566 PixRGB<byte>(255,255,255),1);
00567 locX = locX + dX;
00568 locY = locY + dY;
00569 }
00570
00571 return trajImg;
00572 }
00573
00574
00575
00576
00577
00578