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 "Component/ModelManager.H"
00039 #include "Component/OptionManager.H"
00040 #include "Devices/FrameGrabberConfigurator.H"
00041
00042 #include "Media/FrameSeries.H"
00043
00044 #include "Image/ColorOps.H"
00045 #include "Image/ShapeOps.H"
00046 #include "Image/Image.H"
00047 #include "Image/Layout.H"
00048 #include "Raster/Raster.H"
00049
00050 #include "SIFT/Keypoint.H"
00051 #include "SIFT/VisualObject.H"
00052 #include "SIFT/VisualObjectMatch.H"
00053
00054 #include "Transport/FrameInfo.H"
00055 #include "Util/Pause.H"
00056 #include "Util/Timer.H"
00057 #include "Util/Types.H"
00058 #include "Util/csignals.H"
00059 #include "Util/log.H"
00060 #include <math.h>
00061 #include <cstdio>
00062 #include "Robots/Beobot2/Navigation/FOE_Navigation/FoeDetector.H"
00063
00064
00065 #define DOT_NUM 200 // 200 1000
00066
00067 #define WIDTH 320 // 320 640
00068 #define HEIGHT 240 // 240 480
00069 #define FOE_X 2*WIDTH/4 // W/4
00070 #define FOE_Y 2*HEIGHT/4 // 2H/4 +4
00071
00072 #define DOT_VEL 2.0/80.0 // Shuo: .035
00073
00074
00075
00076
00077 #define DOT_ORG_DSIZE .02 // .04
00078 #define DOT_DSIZE .07 // .035
00079 #define MIN_DOT_SIZE 1
00080 #define MAX_DOT_SIZE 5
00081 #define ABS_MAX_DSIZE 50
00082 #define NFRAME 60
00083
00084 #define HAVE_MOTION 1
00085 #define HAVE_TEMP_SGRAD 1
00086 #define HAVE_SPAT_SGRAD 1
00087
00088 #define NUM_PYR_LEVEL 2 // 3 for 640x480
00089 #define NUM_DIRS 8
00090 #define NUM_SPEEDS 3
00091
00092
00093 std::vector<Point2D<int> > getGT(std::string gtFilename);
00094
00095 Image<byte> calculateShift
00096 (Image<byte> lum, Image<byte> prevLum, nub::ref<OutputFrameSeries> ofs);
00097
00098
00099 Image<byte> getFoeDots
00100 (uint step, bool haveMotion, bool haveTempSGrad, bool haveSpatSGrad,
00101 float dx, float dy, float dotOrgDSize);
00102
00103 Image<byte> getPlanarMotionStimuli
00104 (Image<byte> temp, uint step, float dx, float dy);
00105
00106 Image<byte> getBarStimuli(uint step);
00107 Image<byte> getShapeStimuli(uint step);
00108 Image<byte> getApertureProblemStimuli(uint step);
00109
00110
00111
00112 Image<byte> getCleanFOE
00113 (uint step, uint totalStep, uint mag, float dx, float dy, Image<byte> image);
00114
00115 Image<byte> getPlanarMotionImage
00116 (uint step, uint totalStep, float dx, float dy, Image<byte> image);
00117
00118 Image<byte> shiftImage(SIFTaffine aff, Image<byte> ref, Image<byte> tst);
00119
00120 Image<byte> getImage
00121 (std::string stimuli, std::vector<std::string> args,
00122 nub::ref<FoeDetector> fd, uint step);
00123
00124
00125 std::vector<Point2D<float> > dots;
00126 std::vector<float> dotSizes;
00127
00128 std::vector<Point2D<float> > pdots;
00129 std::vector<float> pdotSizes;
00130
00131
00132 int main(const int argc, const char **argv)
00133 {
00134 MYLOGVERB = LOG_INFO;
00135
00136 volatile int signum = 0;
00137 catchsignals(&signum);
00138
00139 ModelManager manager("Test Motion Energy");
00140
00141 nub::ref<InputFrameSeries> ifs(new InputFrameSeries(manager));
00142 manager.addSubComponent(ifs);
00143
00144 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00145 manager.addSubComponent(ofs);
00146
00147 nub::ref<FoeDetector> fd(new FoeDetector(manager));
00148 manager.addSubComponent(fd);
00149
00150 if (manager.parseCommandLine((const int)argc, (const char**)argv,
00151 "<stimuli> <options>", 0, 9) == false)
00152 return(1);
00153
00154 fd->reset(NUM_PYR_LEVEL, NUM_DIRS, NUM_SPEEDS);
00155
00156 std::string stimuli("Image");
00157 if(manager.numExtraArgs() > 0)
00158 stimuli = manager.getExtraArgAs<std::string>(0);
00159 LINFO("Stimuli: %s", stimuli.c_str());
00160
00161 manager.start();
00162
00163 Timer timer(1000000);
00164 timer.reset();
00165 int frame = 0;
00166
00167 PauseWaiter p;
00168
00169 uint step; step = 0;
00170
00171
00172
00173
00174
00175
00176 std::string gtFilename
00177 ("/lab/tmpib/u/siagian/neuroscience/Data/FOE/driving_nat_Browning.txt");
00178 std::vector<Point2D<int> > gt = getGT(gtFilename);
00179 int ldpos = gtFilename.find_last_of('.');
00180 std::string prefix = gtFilename.substr(0, ldpos);
00181
00182
00183 rutz::shared_ptr<XWinManaged> win;
00184
00185 float totalErr = 0.0;
00186
00187 std::vector<std::string> args;
00188 for(uint i = 0; i < manager.numExtraArgs(); i++)
00189 args.push_back(manager.getExtraArgAs<std::string>(i));
00190
00191 Image<byte> prevLum;
00192 Image<PixRGB<byte> > prevImage;
00193 Image<PixRGB<byte> > prevImage2;
00194 while (1)
00195 {
00196 if (signum != 0)
00197 {
00198 LINFO("quitting because %s was caught", signame(signum));
00199 break;
00200 }
00201
00202 if (ofs->becameVoid())
00203 {
00204 LINFO("quitting because output stream was closed or became void");
00205 break;
00206 }
00207
00208 if (p.checkPause())
00209 continue;
00210
00211 const FrameState is = ifs->updateNext();
00212 if (is == FRAME_COMPLETE) break;
00213
00214 Image< PixRGB<byte> > input = ifs->readRGB();
00215 if(frame == 0)
00216 {
00217 uint width = input.getWidth();
00218 uint height = input.getHeight();
00219 win.reset(new XWinManaged(Dims(width, height), 0, 0, "GT"));
00220 }
00221
00222
00223 if (!input.initialized()) break;
00224 Image<byte> lum = luminance(input);
00225 Point2D<float> pshift(0.0,0.0);
00226 if(step != 0)
00227 {
00228
00229 lum = calculateShift(lum,prevLum, ofs);
00230 }
00231 if( manager.numExtraArgs() > 0)
00232 lum = getImage(stimuli, args, fd, step);
00233
00234
00235 prevImage2 = prevImage;
00236 prevImage = input;
00237
00238 if (!lum.initialized()) break; step++;
00239
00240
00241 Point2D<int> foe = fd->getFoe(lum, FOE_METHOD_TEMPLATE, false);
00242
00243 LINFO("[%d]Foe: %d %d", frame, foe.i, foe.j);
00244
00245
00246 if(!stimuli.compare("ShowRF"))
00247 {
00248 uint rfI = 44;
00249 uint rfJ = 152;
00250 lum.setVal(rfI, rfJ, 300.0F);
00251 drawRect(lum, Rectangle::tlbrI(144,36,159,51), byte(255));
00252 drawRect(lum, Rectangle::tlbrI(148,40,155,47), byte(255));
00253
00254 drawRect(lum, Rectangle::tlbrI(rfJ-8, rfI-8, rfJ+8, rfI+8), byte(255));
00255 drawRect(lum, Rectangle::tlbrI(rfJ-16,rfI-16,rfJ+16,rfI+16), byte(255));
00256 }
00257
00258 ofs->writeGrayLayout(fd->getMTfeaturesDisplay(lum), "MT Features",
00259 FrameInfo("motion energy output images", SRC_POS));
00260
00261
00262 if(frame >= 4)
00263 {
00264 float err = foe.distance(gt[frame-2]);
00265 totalErr += err;
00266 LINFO("Foe: %d %d: GT: %d %d --> %f --> avg: %f",
00267 foe.i, foe.j, gt[frame-2].i, gt[frame-2].j,
00268 err, totalErr/(frame-3));
00269
00270 Image<PixRGB<byte> > simg = prevImage2;
00271 drawCross(simg, foe , PixRGB<byte>(0,255,0), 10, 2);
00272 drawCross(simg, gt[frame-2], PixRGB<byte>(255,0,0), 10, 2);
00273 win->drawImage(simg,0,0);
00274
00275 }
00276
00277
00278
00279 const FrameState os = ofs->updateNext();
00280
00281 Raster::waitForKey();
00282
00283 if (os == FRAME_FINAL)
00284 break;
00285
00286 prevLum = lum;
00287 frame++;
00288 }
00289
00290 LINFO("%d frames in %gs (%.2ffps)\n",
00291 frame, timer.getSecs(), frame / timer.getSecs());
00292
00293
00294 manager.stop();
00295
00296
00297 return 0;
00298
00299 }
00300
00301
00302 std::vector<Point2D<int> > getGT(std::string gtFilename)
00303 {
00304 std::vector<Point2D<int> > gt;
00305
00306 FILE *fp; char inLine[200];
00307
00308 LINFO("ground truth file: %s",gtFilename.c_str());
00309 if((fp = fopen(gtFilename.c_str(),"rb")) == NULL)
00310 { LINFO("not found"); return gt; }
00311
00312
00313 uint nFrames = 0;
00314 while(fgets(inLine, 200, fp) != NULL)
00315 {
00316 int x, y;
00317 sscanf(inLine, "%d %d", &x, &y);
00318 LDEBUG("[%3d] x: %d y: %d", nFrames, x, y);
00319 gt.push_back(Point2D<int>(x,y));
00320
00321 nFrames++;
00322 }
00323 return gt;
00324 }
00325
00326
00327 Image<byte> getImage
00328 (std::string stimuli, std::vector<std::string> args,
00329 nub::ref<FoeDetector> fd, uint step)
00330 {
00331 Image<byte> lum;
00332
00333
00334 if(!stimuli.compare("Image"))
00335 {
00336 float di = 0.0; float dj = 0.0;
00337
00338 if(args.size() > 2)
00339 {
00340 di = atof(args[1].c_str());
00341 dj = atof(args[2].c_str());
00342
00343 }
00344 LDEBUG("di: %f, dj: %f", di, dj);
00345 }
00346 else if(!stimuli.compare("BarStimuli"))
00347 lum = getBarStimuli(step);
00348 else if(!stimuli.compare("ApertureProblem"))
00349 lum = getApertureProblemStimuli(step);
00350 else if(!stimuli.compare("CleanFoe"))
00351 {
00352 uint total = 30;
00353 if(args.size() > 1)
00354 total = uint(atoi(args[1].c_str()));
00355 float dx = 0.0;
00356 float dy = 0.0;
00357 if(args.size() > 3)
00358 {
00359 dx = atof(args[2].c_str());
00360 dy = atof(args[3].c_str());
00361 }
00362 lum = getCleanFOE(step, total, 2.0, dx, dy, lum);
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 uint dir = 0.0; float speed = 0.0;
00373 if(args.size() > 5)
00374 {
00375 dir = uint(atoi(args[4].c_str()));
00376 speed = atof(args[5].c_str());
00377 fd->setObserverRotation(dir, speed);
00378 }
00379 }
00380 else if(!stimuli.compare("FoeDots"))
00381 {
00382 bool haveMotion = HAVE_MOTION;
00383 bool haveTempSGrad = HAVE_TEMP_SGRAD;
00384 bool haveSpatSGrad = HAVE_SPAT_SGRAD;
00385 if(args.size() > 5)
00386 {
00387 haveMotion = bool(atoi(args[1].c_str()));
00388 haveTempSGrad = bool(atoi(args[2].c_str()));
00389 haveSpatSGrad = bool(atoi(args[3].c_str()));
00390 }
00391
00392 float dx = 0.0; float dy = 0.0;
00393
00394 if(args.size() > 5)
00395 {
00396 dx = atof(args[4].c_str());
00397 dy = atof(args[5].c_str());
00398 }
00399
00400 float dotOrgDSize = DOT_ORG_DSIZE;
00401 if(args.size() > 6)
00402 {
00403 dotOrgDSize = atof(args[6].c_str());
00404 }
00405
00406
00407 uint dir = 0.0; float speed = 0.0;
00408 if(args.size() > 8)
00409 {
00410 dir = uint(atoi(args[7].c_str()));
00411 speed = atof(args[8].c_str());
00412 fd->setObserverRotation(dir, speed);
00413 }
00414
00415 LINFO("[%3d] haveMotion: %d haveTempSGrad: %d haveSpatSGrad: %d "
00416 "dx dy: %7.3f %7.3f dotOrgDSize: %f comp: %d %f",
00417 step, haveMotion, haveTempSGrad, haveSpatSGrad,
00418 dx, dy, dotOrgDSize, dir, speed);
00419 lum = getFoeDots(step, haveMotion, haveTempSGrad, haveSpatSGrad,
00420 dx, dy, dotOrgDSize);
00421
00422
00423
00424
00425
00426
00427
00428
00429 }
00430 else if(!stimuli.compare("PlanarDots"))
00431 {
00432 Image<byte> temp(WIDTH, HEIGHT, ZEROS);
00433
00434 float dx = 0.0; float dy = 0.0;
00435 if(args.size() > 2)
00436 {
00437 dx = atof(args[1].c_str());
00438 dy = atof(args[2].c_str());
00439 }
00440 lum = getPlanarMotionStimuli(temp, step, dx, dy);
00441 }
00442 else if(!stimuli.compare("PlanarImage"))
00443 {
00444 uint total = 30;
00445 float dx = 0.0; float dy = 0.0;
00446 if(args.size() > 2)
00447 {
00448 dx = atof(args[1].c_str());
00449 dy = atof(args[2].c_str());
00450 }
00451 lum = getPlanarMotionImage(step, total, dx, dy, lum);
00452 }
00453 else LFATAL("Wrong option");
00454
00455 return lum;
00456 }
00457
00458
00459 Image<byte> calculateShift(Image<byte> lum, Image<byte> prevLum,
00460 nub::ref<OutputFrameSeries> ofs)
00461 {
00462 VisualObjectMatchAlgo voma(VOMA_SIMPLE);
00463
00464
00465
00466
00467
00468
00469 rutz::shared_ptr<VisualObject> vo1(new VisualObject("lum", "", lum));
00470 rutz::shared_ptr<VisualObject> vo2(new VisualObject("plum", "", prevLum));
00471
00472
00473 VisualObjectMatch match(vo1, vo2, voma);
00474 LDEBUG("Found %u matches", match.size());
00475
00476
00477 uint np = match.prune();
00478 LDEBUG("Pruned %u outlier matches.", np);
00479
00480
00481 SIFTaffine s = match.getSIFTaffine();
00482 LDEBUG("[tstX] [ %- .3f %- .3f ] [refX] [%- .3f]", s.m1, s.m2, s.tx);
00483 LDEBUG("[tstY] = [ %- .3f %- .3f ] [refY] + [%- .3f]", s.m3, s.m4, s.ty);
00484
00485
00486 LDEBUG("getKeypointAvgDist = %f", match.getKeypointAvgDist());
00487 LDEBUG("getAffineAvgDist = %f", match.getAffineAvgDist());
00488 LDEBUG("getScore = %f", match.getScore());
00489
00490 if (match.checkSIFTaffine() == false)
00491 LINFO("### Affine is too weird -- BOGUS MATCH");
00492
00493
00494 Image< PixRGB<byte> > mimg = match.getMatchImage(1.0F);
00495 Image< PixRGB<byte> > fimg = match.getFusedImage(0.25F);
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 LINFO("Shift: %f %f", s.tx, s.ty);
00509
00510
00511
00512
00513 Image<byte> res = shiftImage(s, lum, prevLum);
00514
00515
00516
00517
00518
00519
00520
00521 return res;
00522 }
00523
00524
00525 Image<byte> shiftImage(SIFTaffine aff, Image<byte> refi, Image<byte> tsti)
00526 {
00527
00528
00529
00530
00531 uint w = refi.getWidth(), h = refi.getHeight();
00532 Image<byte> result(w, h, ZEROS);
00533 Image<byte>::const_iterator rptr = refi.begin();
00534 Image<byte>::iterator dptr = result.beginw();
00535
00536 for (uint j = 0; j < h; j ++)
00537 for (uint i = 0; i < w; i ++)
00538 {
00539 float u, v;
00540 aff.transform(float(i), float(j), u, v);
00541 byte rval = *rptr++;
00542
00543 if (tsti.coordsOk(u, v))
00544 {
00545 byte tval = tsti.getValInterp(u, v);
00546
00547 *dptr++ = tval;
00548 }
00549 else
00550
00551 *dptr++ = byte(rval);
00552 }
00553
00554 return result;
00555 }
00556
00557
00558
00559 Image<byte> getApertureProblemStimuli(uint step)
00560 {
00561 Image<byte> temp(WIDTH, HEIGHT, ZEROS);
00562
00563
00564 if(step == 0)
00565 {
00566 dots.resize(1);
00567
00568 dots[0] = Point2D<float> (WIDTH/2, HEIGHT/4);
00569 }
00570
00571 uint len = 15;
00572
00573
00574 dots[0] = Point2D<float>(dots[0].i + 2.0, dots[0].j);
00575 drawLine
00576 (temp,
00577 Point2D<int>(dots[0].i-len, dots[0].j-len),
00578 Point2D<int>(dots[0].i+len, dots[0].j+len), byte(255), 1);
00579
00580 return temp;
00581 }
00582
00583
00584 Image<byte> getShapeStimuli(uint step)
00585 {
00586 Image<byte> temp(WIDTH, HEIGHT, ZEROS);
00587
00588
00589
00590
00591
00592
00593
00594 return temp;
00595 }
00596
00597
00598 Image<byte> getBarStimuli(uint step)
00599 {
00600 Image<byte> temp(WIDTH, HEIGHT, ZEROS);
00601
00602
00603 if(step == 0)
00604 {
00605 dots.resize(4); dotSizes.resize(4);
00606
00607
00608 dots[0] = Point2D<float> (WIDTH/2, HEIGHT/4);
00609 dotSizes[0] = 1.0;
00610 dots[1] = Point2D<float> (WIDTH/4, HEIGHT/2);
00611 dotSizes[1] = 1.0;
00612 dots[2] = Point2D<float> (WIDTH/8, HEIGHT/4);
00613 dotSizes[2] = 1.0;
00614 dots[3] = Point2D<float> (WIDTH/4, HEIGHT/8);
00615 dotSizes[3] = 1.0;
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 }
00628
00629
00630 if(HAVE_MOTION)
00631 {
00632
00633 dots[0] = Point2D<float>(dots[0].i + 2.0, dots[0].j);
00634 dots[1] = Point2D<float>(dots[1].i, dots[1].j + 1.0);
00635 dots[2] = Point2D<float>(dots[2].i - 1.0, dots[2].j);
00636 dots[3] = Point2D<float>(dots[3].i, dots[3].j - 1.0);
00637
00638
00639 }
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649 drawLine
00650 (temp,
00651 Point2D<int>(dots[0].i, dots[0].j-15),
00652 Point2D<int>(dots[0].i, dots[0].j+15), byte(255), 1);
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
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 return temp;
00711 }
00712
00713
00714 Image<byte> getPlanarMotionStimuli
00715 (Image<byte> temp, uint step, float dx, float dy)
00716 {
00717
00718
00719 uint dotNum = 200;
00720
00721 float orgDotSize = 1.0;
00722
00723
00724 if(step == 0)
00725 {
00726 pdots.resize(dotNum); pdotSizes.resize(dotNum);
00727 for(uint i = 0; i < dotNum; i++)
00728 {
00729 pdots[i] = Point2D<float>
00730 (WIDTH * double(rand())/(RAND_MAX + 1.0),
00731 HEIGHT * double(rand())/(RAND_MAX + 1.0));
00732 pdotSizes[i] = orgDotSize;
00733 }
00734 }
00735
00736
00737 for(uint i = 0; i < dotNum; i++)
00738 {
00739
00740 if(!temp.getBounds().contains(Point2D<int>(pdots[i].i, pdots[i].j)))
00741 {
00742 float srx = 0.0; float sry = 0.0;
00743 float rx = WIDTH; float ry = HEIGHT;
00744 if(dx < 0.0) { srx = 7.0*WIDTH/8.0; rx = WIDTH/8; }
00745 else if(dx > 0.0){ srx = 0.0; rx = WIDTH/8; }
00746
00747 if(dy < 0.0) { sry = 7.0*HEIGHT/8.0; ry = HEIGHT/8; }
00748 else if(dy > 0.0){ sry = 0.0; ry = HEIGHT/8; }
00749
00750 float sx = rx * double(rand())/(RAND_MAX + 1.0) + srx;
00751 float sy = ry * double(rand())/(RAND_MAX + 1.0) + sry;
00752
00753 pdots[i] = Point2D<float>(sx,sy);
00754 pdotSizes[i] = orgDotSize;
00755 LDEBUG("new dots[%3d]: %7.3f %7.3f", i, sx, sy);
00756 }
00757 else
00758 {
00759 Point2D<int> pt(pdots[i].i, pdots[i].j);
00760 LDEBUG("[%3d] it's ok: (%7.3f %7.3f) -> %3d %3d",
00761 i, pdots[i].i, pdots[i].j, pt.i, pt.j);
00762 }
00763 }
00764
00765
00766 if(dx != 0.0 || dy != 0.0)
00767 for(uint i = 0; i < dotNum; i++)
00768 {
00769 pdots[i] = Point2D<float>(pdots[i].i + dx,
00770 pdots[i].j + dy);
00771 }
00772
00773
00774 for(uint i = 0; i < dotNum; i++)
00775 {
00776 LDEBUG("[%d] loc: %10.3f %10.3f: size: %7.3f",
00777 i, pdots[i].i, pdots[i].j, pdotSizes[i]);
00778 drawDisk(temp,Point2D<int>(pdots[i].i, pdots[i].j),
00779 pdotSizes[i],byte(255));
00780
00781 }
00782 return temp;
00783 }
00784
00785
00786 Image<byte> orgPlanarImage;
00787 Image<byte> getPlanarMotionImage
00788 (uint step, uint totalStep, float dx, float dy, Image<byte> image)
00789 {
00790
00791 step = step % totalStep;
00792
00793
00794 if(step == 0)
00795 {
00796 orgPlanarImage = image;
00797 }
00798 image = orgPlanarImage;
00799
00800 uint width = image.getWidth();
00801 uint height = image.getHeight();
00802 float scale = 1.25;
00803 Image<byte> temp = rescale(image, scale*width, scale*height);
00804 float nwidth = temp.getWidth();
00805 float nheight = temp.getHeight();
00806
00807 float sleft = 0.0; if(dx < 0.0) sleft = nwidth - 1 - width;
00808 float stop = 0.0; if(dy < 0.0) stop = nheight - 1 - height;
00809
00810 float left = sleft + dx*step;
00811 float top = stop + dy*step;
00812
00813
00814
00815
00816 Rectangle r =
00817 Rectangle::tlbrI(top, left, top+height-1, left+width-1);
00818
00819
00820
00821
00822
00823
00824
00825
00826 Image<byte> result = crop(temp, r);
00827
00828 return result;
00829 }
00830
00831
00832 Image<byte> getFoeDots
00833 (uint step, bool haveMotion, bool haveTempSGrad, bool haveSpatSGrad,
00834 float dx, float dy, float dotOrgDSize)
00835 {
00836
00837
00838 Image<byte> temp(WIDTH, HEIGHT, ZEROS);
00839
00840 float orgDotSize = 1.0;
00841
00842
00843 if(step == 0)
00844 {
00845 dots.resize(DOT_NUM); dotSizes.resize(DOT_NUM);
00846 for(uint i = 0; i < DOT_NUM; i++)
00847 {
00848 dots[i] = Point2D<float>
00849 (WIDTH * double(rand())/(RAND_MAX + 1.0),
00850 HEIGHT * double(rand())/(RAND_MAX + 1.0));
00851
00852
00853
00854
00855 dotSizes[i] = orgDotSize;
00856 }
00857 }
00858
00859
00860 for(uint i = 0; i < DOT_NUM; i++)
00861 {
00862
00863
00864 if(!temp.getBounds().contains(Point2D<int>(dots[i].i, dots[i].j)))
00865 {
00866 dots[i] = Point2D<float>
00867 (WIDTH * double(rand())/(RAND_MAX + 1.0),
00868 HEIGHT * double(rand())/(RAND_MAX + 1.0) );
00869
00870
00871 dotSizes[i] = orgDotSize;
00872 }
00873 }
00874
00875
00876 for(uint i = 0; i < DOT_NUM; i++)
00877 {
00878 if(haveTempSGrad && haveSpatSGrad)
00879 {
00880 float dist = sqrt(pow((dots[i].i - FOE_X), 2.0) +
00881 pow((dots[i].j - FOE_Y), 2.0) );
00882 if(haveMotion)
00883 {
00884 dotSizes[i] = dotOrgDSize * dist;
00885 }
00886
00887 else
00888 {
00889 if(step == 0)
00890 {
00891 dotSizes[i] = dotOrgDSize * dist;
00892 }
00893 else
00894 {
00895
00896 if(dotSizes[i] < ABS_MAX_DSIZE)
00897 {
00898 dotSizes[i] = (1.0 + DOT_DSIZE) *
00899 dotOrgDSize * dist;
00900 }
00901
00902 }
00903 }
00904 }
00905 else if(haveTempSGrad && !haveSpatSGrad)
00906 {
00907
00908 float ds = MAX_DOT_SIZE - MIN_DOT_SIZE;
00909 dotSizes[i] = step*ds/(NFRAME - 1.0)+ double(MIN_DOT_SIZE);
00910 }
00911 else if(!haveTempSGrad && haveSpatSGrad)
00912 {
00913 float dist = sqrt(pow((dots[i].i - FOE_X), 2.0) +
00914 pow((dots[i].j - FOE_Y), 2.0) );
00915 dotSizes[i] = dotOrgDSize * dist;
00916 }
00917
00918 }
00919
00920
00921 if(haveMotion)
00922 for(uint i = 0; i < DOT_NUM; i++)
00923 {
00924 dots[i] = Point2D<float>
00925 (dots[i].i + DOT_VEL * (dots[i].i - FOE_X),
00926 dots[i].j + DOT_VEL * (dots[i].j - FOE_Y));
00927 }
00928
00929
00930 if(dx != 0.0 || dy != 0.0)
00931 for(uint i = 0; i < DOT_NUM; i++)
00932 {
00933 dots[i] = Point2D<float>(dots[i].i + dx, dots[i].j + dy);
00934 }
00935
00936
00937 for(uint i = 0; i < DOT_NUM; i++)
00938 {
00939
00940
00941 drawDisk(temp,Point2D<int>(dots[i].i, dots[i].j),dotSizes[i],byte(255));
00942
00943 }
00944
00945
00946
00947
00948 return temp;
00949 }
00950
00951
00952
00953
00954
00955 Image<byte> orgImage;
00956 Image<byte> getCleanFOE
00957 (uint step, uint totalStep, uint mag, float dx, float dy, Image<byte> image)
00958 {
00959
00960 step = step % totalStep;
00961
00962
00963 if(step == 0)
00964 {
00965 orgImage = image;
00966 return image;
00967 }
00968 image = orgImage;
00969
00970 uint width = image.getWidth();
00971 uint height = image.getHeight();
00972
00973 float nsize = (step/(totalStep - 1.0));
00974 float scale = 1.0 / (1.0 - nsize*1.0/mag);
00975 Image<byte> temp = rescale(image, scale*width, scale*height);
00976 float nwidth = temp.getWidth();
00977 float nheight = temp.getHeight();
00978
00979 float px = float(FOE_X)/float(width);
00980 float py = float(FOE_Y)/float(height);
00981
00982 float foeX = px*nwidth;
00983 float foeY = py*nheight;
00984
00985 float left = foeX - float(FOE_X) + dx*step;
00986 float top = foeY - float(FOE_Y) + dy*step;
00987
00988
00989
00990
00991 Rectangle r =
00992 Rectangle::tlbrI(top, left, top+height-1, left+width-1);
00993
00994 LINFO("[%3d/%3d] FOE(%7.3f %7.3f) %f p(%7.3f %7.3f) [[%7.3f %7.3f]] "
00995 "[%3d %3d %3d %3d] temp(%3d %3d) ((%3d %3d))",
00996 step, totalStep,
00997 foeX,foeY, scale, px, py, top, left,
00998 r.top(), r.left(), r.bottomI(), r.rightI(),
00999 temp.getWidth(), temp.getHeight(),
01000 r.width(),r.height());
01001 Image<byte> result = crop(temp, r);
01002
01003 return result;
01004 }
01005
01006
01007
01008
01009
01010