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 "Beobot/LandmarkDB.H"
00039 #include "Image/DrawOps.H"
00040 #include "Image/CutPaste.H"
00041 #include "Util/Timer.H"
00042
00043 #include <cstdio>
00044
00045
00046 LandmarkDB::LandmarkDB(uint nSegment):
00047 itsScenes(),
00048 itsLandmarks(),
00049 itsActiveLmkList(),
00050 itsSkipList(),
00051 itsSessionNames(),
00052 itsSessionLandmarks()
00053 {
00054 if(nSegment > 0) resize(nSegment);
00055 }
00056
00057
00058 LandmarkDB::~LandmarkDB()
00059 { }
00060
00061
00062 void LandmarkDB::build
00063 ( std::vector<rutz::shared_ptr<VisualObject> > &inputVO,
00064 std::vector<Point2D<int> > &objOffset, uint fNum, uint currSegNum,
00065 rutz::shared_ptr<VisualObject> scene)
00066 {
00067 ASSERT(currSegNum < itsLandmarks.size());
00068 LINFO("BEFORE lmks[%d].sz: %"ZU, currSegNum,
00069 itsLandmarks[currSegNum].size());
00070
00071
00072 itsScenes.push_back(scene);
00073 int imgW = scene->getImage().getWidth();
00074 int imgH = scene->getImage().getHeight();
00075 float imgD = sqrt(imgW*imgW + imgH*imgH);
00076 Dims sDims = scene->getImage().getDims();
00077
00078
00079 uint onobj = inputVO.size();
00080 kpFilter(inputVO, objOffset);
00081
00082
00083
00084 uint nobj = inputVO.size(); if(nobj == 0) return;
00085 uint nlmk = itsLandmarks[currSegNum].size();
00086 LINFO("get scores: num objects: %d, num landmarks: %d", nobj, nlmk);
00087 std::vector<std::vector<rutz::shared_ptr<VisualObjectMatch> > >
00088 resMatch(nobj);
00089 std::vector<std::vector<bool> > inDB(nobj);
00090 std::vector<std::vector<bool> > inTDB(nobj);
00091 std::vector<std::vector<int> > tIndex(nobj);
00092 std::vector<std::vector<float> > scores(nobj);
00093 std::vector<std::vector<float> > siftscores(nobj);
00094 std::vector<std::vector<float> > sdiffscores(nobj);
00095 for(uint i = 0; i < nobj; i++)
00096 {
00097
00098 for(uint j = 0; j < nlmk; j++)
00099 {
00100 if(itsActiveLmkList[currSegNum][j])
00101 {
00102 bool indb; bool intdb; int tindex;
00103 rutz::shared_ptr<VisualObjectMatch> cmatch =
00104 itsLandmarks[currSegNum][j]
00105 ->buildCheck(inputVO[i], objOffset[i], fNum,
00106 indb, intdb, tindex);
00107
00108 LINFO("[%d] Match obj[%d] with lmk[%d][%d]: {%d %d %d}",
00109 fNum, i, currSegNum, j, indb, intdb, tindex);
00110
00111 inDB[i].push_back(indb);
00112 inTDB[i].push_back(intdb);
00113 tIndex[i].push_back(tindex);
00114 resMatch[i].push_back(cmatch);
00115
00116
00117 float siftscore = 0.0f;
00118 if(indb || intdb) siftscore = cmatch->getScore();
00119
00120
00121 float dscore = 0.0;
00122 if(indb || intdb)
00123 dscore = getOffsetDistScore
00124 (itsLandmarks[currSegNum][j], indb, intdb, tindex,
00125 inputVO[i], objOffset[i], sDims, cmatch);
00126
00127
00128 float oscore = 0.0;
00129 if(indb || intdb) oscore = getOverlapScore(cmatch);
00130
00131
00132 float sdist = 0.0f; float salscore = 0.0f;
00133 float sdiff = cmatch->getSalDiff();
00134 if(indb || intdb)
00135 {
00136 sdist = cmatch->getSalDist();
00137 sdist = 1.0 - sdist/imgD;
00138 salscore = sdist * sdiff;
00139 }
00140
00141 float score = salscore;
00142 scores[i].push_back(score);
00143 siftscores[i].push_back(siftscore);
00144 sdiffscores[i].push_back(sdiff);
00145 LINFO("match obj[%d] & lmks[%d][%d] sift[%f %f %f] sal[%f %f]",
00146 i, currSegNum, j, siftscore, dscore, oscore,
00147 sdist, sdiff);
00148
00149
00150 }
00151 else
00152 {
00153
00154 inDB[i].push_back(false);
00155 inTDB[i].push_back(false);
00156 tIndex[i].push_back(-1);
00157 resMatch[i].push_back(rutz::shared_ptr<VisualObjectMatch>());
00158 scores[i].push_back(0.0f);
00159 siftscores[i].push_back(0.0f);
00160 sdiffscores[i].push_back(0.0f);
00161 }
00162
00163 }
00164 }
00165
00166
00167
00168
00169
00170 for(uint i = 0; i < nobj; i++)
00171 {
00172 bool matched = false;
00173
00174 for(uint j = 0; j < nlmk; j++) if(scores[i][j] > 0.0) matched = true;
00175
00176
00177 if(!matched)
00178 {
00179 LINFO("object %d not matched", i);
00180
00181 for(uint j = 0; j < nlmk; j++)
00182 {
00183 if(itsActiveLmkList[currSegNum][j])
00184 {
00185
00186 bool indb; bool intdb; int tindex = -1;
00187 rutz::shared_ptr<VisualObject> lobj
00188 = itsLandmarks[currSegNum][j]->getLatestObject
00189 (indb, intdb, tindex);
00190
00191 LINFO("got latest object of lmk[][%d]", j);
00192
00193 const std::vector<float>& feat1 = lobj->getFeatures();
00194 const std::vector<float>& feat2 = inputVO[i]->getFeatures();
00195
00196
00197 float cval = 0.0;
00198 for(uint k = 0; k < feat1.size(); k++)
00199 {
00200 float val = pow(feat1[k] - feat2[k], 2.0); cval += val;
00201 }
00202 cval = sqrt(cval/feat1.size());
00203 float sscore = 1.0F - cval;
00204
00205 if(sscore > .80)
00206 {
00207 LINFO("obj[%d] lmk[%d] good match (%f) check SIFT",
00208 i, j, sscore);
00209
00210 uint lfNum =
00211 itsLandmarks[currSegNum][j]->getLatestFNum();
00212
00213
00214 LINFO("matching scenes: %d and %d", lfNum, fNum);
00215 rutz::shared_ptr<VisualObject> a = itsScenes[lfNum];
00216 rutz::shared_ptr<VisualObject> b = itsScenes[fNum];
00217
00218
00219 float kpAvgDist, afAvgDist, score;
00220 bool isSIFTaffine; SIFTaffine siftAffine;
00221 VisualObjectMatchAlgo voma(VOMA_SIMPLE);
00222
00223
00224 Timer tim(1000000); tim.reset();
00225 rutz::shared_ptr<VisualObjectMatch>
00226 matchRes(new VisualObjectMatch(a, b, voma));
00227 uint64 t = tim.get();
00228
00229
00230 uint orgSize = matchRes->size();
00231 tim.reset();
00232 uint np = matchRes->prune();
00233 uint t2 = tim.get();
00234
00235 LINFO("Found %u matches (%s & %s) in %.3fms:"
00236 " pruned %u in %.3fms",
00237 orgSize, a->getName().c_str(),
00238 b->getName().c_str(), float(t) * 0.001F,
00239 np, float(t2) * 0.001F);
00240
00241
00242 kpAvgDist = matchRes->getKeypointAvgDist();
00243 afAvgDist = matchRes->getAffineAvgDist();
00244 score = matchRes->getScore();
00245 isSIFTaffine = matchRes->checkSIFTaffine
00246 (M_PI/4,5.0F,0.25F);
00247 siftAffine = matchRes->getSIFTaffine();
00248 LINFO("kpAvgDist = %.4f|affAvgDist = %.4f|"
00249 " score: %.4f|aff? %d",
00250 kpAvgDist, afAvgDist, score, isSIFTaffine);
00251
00252 if (!isSIFTaffine)
00253 LINFO("### Affine is too weird -- BOGUS MATCH");
00254 else
00255 {
00256
00257 LINFO("[testX] [ %- .3f %- .3f ] [refX] [%- .3f]",
00258 siftAffine.m1, siftAffine.m2, siftAffine.tx);
00259 LINFO("[testY]= [ %- .3f %- .3f ] [refY] + [%- .3f]",
00260 siftAffine.m3, siftAffine.m4, siftAffine.ty);
00261 }
00262
00263 bool isSIFTfit = (isSIFTaffine && (score > 2.5) &&
00264 (matchRes->size() > 3));
00265 LINFO("OD isSIFTfit %d", isSIFTfit);
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 if(isSIFTfit)
00279 {
00280
00281 Point2D<int> loffset = itsLandmarks[currSegNum][j]
00282 ->getLatestOffsetCoords();
00283 Point2D<int> salpt1 = lobj->getSalPoint() + loffset;
00284 Point2D<int> salpt2 = inputVO[i]->getSalPoint() +
00285 objOffset[i];
00286 LINFO("loffset: %d %d", loffset.i, loffset.j);
00287
00288
00289 float u, v; siftAffine.transform
00290 (salpt1.i, salpt1.j, u, v);
00291 float dist = salpt2.distance
00292 (Point2D<int>(int(u+0.5F), int(v+0.5F)));
00293 LINFO("pos1: (%d,%d) -> (%f,%f) & "
00294 "pos2: (%d,%d): dist: %f",
00295 salpt1.i, salpt1.j, u, v,
00296 salpt2.i, salpt2.j, dist);
00297
00298 float sdist = 1.0 - dist/imgD;
00299
00300 if(dist < 10.0F)
00301 {
00302 inDB[i][j] = indb;
00303 inTDB[i][j] = intdb;
00304 tIndex[i][j] = tindex;
00305 scores[i][j] = (sdist * sscore);
00306 siftscores[i][j] = (score);
00307 sdiffscores[i][j] = (sscore);
00308 }
00309 }
00310 }
00311 else{ LINFO("score too low: %f",sscore); }
00312 }
00313 }
00314 }
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 LINFO("skipping: ");
00329 for(int i = 0; i < int(onobj - nobj); i++)
00330 LINFO("%d %s", i, itsSkipList[itsSkipList.size()-1-i]->getName().c_str());
00331
00332
00333
00334 std::vector<bool> inserted(nobj);
00335 std::vector<bool> lmatched(nlmk);
00336 for(uint i = 0; i < nobj; i++) inserted[i] = false;
00337 for(uint j = 0; j < nlmk; j++) lmatched[j] = false;
00338
00339
00340 std::vector<float> ratio(nobj);
00341 for(uint i = 0; i < nobj; i++) ratio[i] = 0.0;
00342 bool done = false; if(nlmk == 0) done = true;
00343 while(!done)
00344 {
00345
00346 float mratio; int mind; std::vector<int> mlist;
00347 findBestMatch(scores, ratio, inserted, lmatched, mratio, mind, mlist);
00348
00349
00350 if(mind == -1) done = true;
00351 else
00352 {
00353 int ilbest = mlist[0];
00354
00355 if(mlist.size() > 1)
00356 {
00357 LINFO("transfer");
00358
00359
00360
00361
00362
00363
00364
00365 int ilmax = -1; int maxlsize = -1;
00366 for(uint j = 0; j < mlist.size(); j++)
00367 {
00368
00369 int clsize =
00370 itsLandmarks[currSegNum][mlist[j]]->numObjects() +
00371 itsLandmarks[currSegNum][mlist[j]]->numTempObjects();
00372
00373 LINFO("lsize[%d]: %d", mlist[j], clsize);
00374
00375 if(clsize > maxlsize){ ilmax = mlist[j]; maxlsize = clsize; }
00376 }
00377 ilbest = ilmax;
00378 LINFO("ilbest: %d", ilbest);
00379
00380
00381
00382
00383
00384 for(uint j = 0; j < mlist.size(); j++)
00385 {
00386
00387
00388 if(mlist[j] != ilbest)
00389 {
00390
00391 LINFO("transf lmk[][%d] to lmk[][%d]", mlist[j], ilbest);
00392
00393 itsLandmarks[currSegNum][ilbest]->transferEvidence
00394 (itsLandmarks[currSegNum][mlist[j]],
00395 inDB[mind][mlist[j]], inTDB[mind][mlist[j]],
00396 tIndex[mind][mlist[j]], resMatch[mind][mlist[j]]);
00397 }
00398 }
00399 }
00400
00401
00402 LINFO("Inserting obj %d to landmark[%d][%d]",
00403 mind, currSegNum, ilbest);
00404 itsLandmarks[currSegNum][ilbest]
00405 ->build(inputVO[mind], objOffset[mind], fNum,
00406 inDB[mind][ilbest], inTDB[mind][ilbest],
00407 tIndex[mind][ilbest], resMatch[mind][ilbest]);
00408
00409
00410 inserted[mind] = true;
00411 lmatched[mlist[0]] = true;
00412 }
00413 }
00414
00415
00416 for(uint i = 0; i < nobj; i++)
00417 {
00418 if(!inserted[i])
00419 {
00420 LINFO("create landmark %"ZU, itsLandmarks[currSegNum].size());
00421 std::string
00422 lmName(sformat("landmark%07"ZU, itsLandmarks[currSegNum].size()));
00423 rutz::shared_ptr<Landmark> newlm
00424 (new Landmark(inputVO[i], objOffset[i], fNum, lmName));
00425 newlm->setMatchWin(itsWin);
00426 itsLandmarks[currSegNum].push_back(newlm);
00427 itsActiveLmkList[currSegNum].push_back(true);
00428 }
00429 }
00430
00431
00432 for(uint j = 0; j < nlmk; j++)
00433 {
00434
00435 int clsize =
00436 itsLandmarks[currSegNum][j]->numObjects() +
00437 itsLandmarks[currSegNum][j]->numTempObjects();
00438
00439 if(clsize == 0) itsActiveLmkList[currSegNum][j] = false;
00440 }
00441
00442 LINFO("AFTER lmks[%d].sz: %"ZU, currSegNum, itsLandmarks[currSegNum].size());
00443
00444
00445 classifyInactiveLandmarks(fNum, NFDIFF);
00446 }
00447
00448
00449 void LandmarkDB::kpFilter
00450 ( std::vector<rutz::shared_ptr<VisualObject> > &inputVO,
00451 std::vector<Point2D<int> > &objOffset)
00452 {
00453 LINFO(" BEFORE kpFilter: %"ZU, inputVO.size());
00454
00455
00456 std::vector<rutz::shared_ptr<VisualObject> >::iterator
00457 voitr = inputVO.begin();
00458 std::vector<Point2D<int> >::iterator obitr = objOffset.begin();
00459
00460 uint i = 0;
00461 while (voitr < inputVO.end())
00462 {
00463
00464 if((*voitr)->numKeypoints() <= 5)
00465 {
00466 LINFO("skip: %s (%d kp)", (*voitr)->getName().c_str(),
00467 (*voitr)->numKeypoints());
00468 itsSkipList.push_back((*voitr));
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 voitr = inputVO.erase(voitr);
00482 obitr = objOffset.erase(obitr);
00483 }
00484 else{ voitr++; obitr++; }
00485 i++;
00486 }
00487 LINFO(" AFTER kpFilter: %"ZU, inputVO.size());
00488 }
00489
00490
00491 float LandmarkDB::getOffsetDistScore
00492 ( rutz::shared_ptr<Landmark> landmark, int indb, int intdb, int tindex,
00493 rutz::shared_ptr<VisualObject> vo, Point2D<int> offset, Dims sDims,
00494 rutz::shared_ptr<VisualObjectMatch> cmatch)
00495 {
00496 float dscore = 0.0;
00497
00498 Point2D<int> objOffset2;
00499 if(indb)
00500 objOffset2 = landmark->getOffsetCoords(tindex);
00501 else
00502 objOffset2 = landmark->getTempOffsetCoords(tindex);
00503 bool isODmatch = (vo == cmatch->getVoRef());
00504 Point2D<int> diff;
00505 if(isODmatch)
00506 {
00507 diff = cmatch->getSpatialDist(offset, objOffset2);
00508
00509 }
00510 else
00511 {
00512 diff = cmatch->getSpatialDist(objOffset2, offset);
00513
00514 }
00515 float dist = diff.distance(Point2D<int>(0,0));
00516
00517
00518 if(dist <= 25.0)
00519 dscore = 1.0 - (dist/25.0) * .02;
00520
00521 else if(dist > 25.0 && dist <= 200.0)
00522 dscore = .98 - ((dist - 25.0)/175.0)* .97;
00523
00524 else
00525 dscore = .01;
00526 LINFO("dist: (%d,%d): %f", diff.i, diff.j, dist);
00527
00528 return dscore;
00529 }
00530
00531
00532 float LandmarkDB::getOverlapScore
00533 (rutz::shared_ptr<VisualObjectMatch> cmatch)
00534 {
00535 float oscore = 0.0;
00536
00537 int area1 = cmatch->getVoRef()->getImage().getSize();
00538 int area2 = cmatch->getVoTest()->getImage().getSize();
00539 Rectangle rovl = cmatch->getOverlapRect();
00540
00541 if(!rovl.isValid()) return oscore;
00542
00543 float ovl = float(rovl.width() * rovl.height());
00544 oscore = (ovl/area1 + ovl/area2)/2.0;
00545 LINFO("area1: %d, area2: %d, ovl: %f, oscore: %f",
00546 area1, area2, ovl, oscore);
00547 return oscore;
00548 }
00549
00550
00551 void LandmarkDB::printScores
00552 ( std::vector<rutz::shared_ptr<VisualObject> > inputVO,
00553 int currSegNum, std::vector<std::vector<float> > inscores)
00554 {
00555 int printlimit = 25;
00556 uint nobj = inputVO.size();
00557 uint nlmk = itsActiveLmkList[currSegNum].size();
00558 LINFO("nobj: %d nlmk: %d", nobj, nlmk);
00559
00560
00561 printf(" ");
00562 int lcount = 0;
00563 for(uint j = 0; j < nlmk; j++)
00564 {
00565 if(itsActiveLmkList[currSegNum][j] && lcount < printlimit)
00566 {
00567 printf("%6d",j);
00568 lcount++;
00569 }
00570 }
00571 printf("\n");
00572 for(uint i = 0; i < nobj; i++)
00573 {
00574 int len = inputVO[i]->getName().length();
00575 printf("%10s", inputVO[i]->getName().substr(len-10).c_str());
00576 lcount = 0;
00577 for(uint j = 0; j < nlmk; j++)
00578 {
00579 if(itsActiveLmkList[currSegNum][j] && lcount < printlimit)
00580 {
00581 printf("%6.2f", inscores[i][j]);
00582 lcount++;
00583 }
00584 }
00585 printf("\n");
00586 }
00587 printf("\n");
00588 }
00589
00590
00591 void LandmarkDB::findBestMatch
00592 (std::vector<std::vector<float> > scores, std::vector<float> &ratio,
00593 std::vector<bool> &inserted, std::vector<bool> &lmatched,
00594 float &mratio, int &mind, std::vector<int> &mlist)
00595 {
00596
00597 for(uint i = 0; i < scores.size(); i++)
00598 {
00599 ratio[i] = 0.0;
00600
00601 bool hasMatch = false;
00602 for(uint j = 0; j < scores[i].size(); j++)
00603 if(scores[i][j] > 0.0 && !lmatched[j]) hasMatch = true;
00604
00605
00606 if(!inserted[i] && hasMatch)
00607 {
00608
00609 float max = 0.0f; float max2 = 0.0f;
00610 for(uint j = 0; j < scores[i].size(); j++)
00611 {
00612 if(scores[i][j] > max)
00613 { max2 = max; max = scores[i][j]; }
00614 else if(scores[i][j] > max2)
00615 { max2 = scores[i][j]; }
00616 }
00617 if(max2 < .25) ratio[i] = max/.25;
00618 else ratio[i] = max/max2;
00619 }
00620 LINFO("ratio[%d]: %f", i, ratio[i]);
00621 }
00622
00623
00624 mratio = 0.0; mind = -1;
00625 for(uint i = 0; i < ratio.size(); i++)
00626 {
00627 if(!inserted[i])
00628 {
00629 if(ratio[i] > mratio)
00630 { mratio = ratio[i]; mind = i; }
00631 }
00632 }
00633 if(mind == -1) { LINFO("no more matches"); return; }
00634
00635
00636 for(uint j = 0; j < scores[mind].size(); j++)
00637 {
00638
00639 if(!lmatched[j] && scores[mind][j] > 0.0)
00640 mlist.push_back(j);
00641 }
00642 LINFO("max ratio: %f obj[%d]: %"ZU" matches", mratio, mind, mlist.size());
00643 }
00644
00645
00646 void LandmarkDB::classifyInactiveLandmarks(uint fNum, uint nfDiff, bool print)
00647 {
00648
00649 for(uint i = 0; i < itsLandmarks.size(); i++)
00650 for(uint j = 0; j < itsLandmarks[i].size(); j++)
00651 {
00652 if(itsActiveLmkList[i][j] &&
00653 ((itsLandmarks[i][j]->getLatestFNum() + nfDiff) < fNum))
00654 {
00655
00656 itsLandmarks[i][j]->moveLatestTempVisualObjectToDB();
00657 itsActiveLmkList[i][j] = false;
00658
00659 if(print) LINFO("made landmark [%d][%d] inactive", i, j);
00660 }
00661
00662 if(itsActiveLmkList[i][j] && print)
00663 LINFO("landmark[%3d %3d] active: %5d,%5d: %3d + %3d = %3d", i, j,
00664 itsLandmarks[i][j]->getVisualObjectFNum(0),
00665 itsLandmarks[i][j]->getLatestFNum(),
00666 itsLandmarks[i][j]->numObjects(),
00667 itsLandmarks[i][j]->numTempObjects(),
00668 itsLandmarks[i][j]->numObjects() +
00669 itsLandmarks[i][j]->numTempObjects());
00670 else if(itsLandmarks[i][j]->numObjects() > 0 && print)
00671 LINFO("landmark[%3d %3d] inactive: %5d,%5d: %3d + %3d = %3d", i, j,
00672 itsLandmarks[i][j]->getVisualObjectFNum(0),
00673 itsLandmarks[i][j]->getLatestFNum(),
00674 itsLandmarks[i][j]->numObjects(),
00675 itsLandmarks[i][j]->numTempObjects(),
00676 itsLandmarks[i][j]->numObjects() +
00677 itsLandmarks[i][j]->numTempObjects());
00678 else if(print)
00679 LINFO("landmark[%3d %3d] inactive: -1, -1: %3d + %3d = %3d", i, j,
00680 itsLandmarks[i][j]->numObjects(),
00681 itsLandmarks[i][j]->numTempObjects(),
00682 itsLandmarks[i][j]->numObjects() +
00683 itsLandmarks[i][j]->numTempObjects());
00684 }
00685
00686 }
00687
00688
00689 void LandmarkDB::finishBuild(uint rframe)
00690 {
00691
00692 classifyInactiveLandmarks(rframe, 0, true);
00693 pruneLandmarks();
00694
00695
00696
00697 }
00698
00699
00700 void LandmarkDB::pruneLandmarks()
00701 {
00702
00703 for(uint i = 0; i < itsLandmarks.size(); i++)
00704 {
00705 std::vector< rutz::shared_ptr<Landmark> >::iterator itr =
00706 itsLandmarks[i].begin();
00707 uint ct = 0; uint orgCt = 0;
00708
00709 while (itr < itsLandmarks[i].end())
00710 {
00711 uint numObjects = (*itr)->numObjects();
00712 uint numTempObjects = (*itr)->numTempObjects();
00713 uint numTotal = numObjects + numTempObjects;
00714
00715 int range = 0; int start = -1; int end = -1;
00716 if(numObjects > 0)
00717 {
00718 start = (*itr)->getVisualObjectFNum(0);
00719 end = (*itr)->getLatestFNum();
00720 range = end - start;
00721 }
00722
00723
00724
00725
00726
00727
00728 if (((range <= 20) && (numTotal >= 8)) ||
00729 ((range > 20) && (numTotal >= 5)) )
00730 {
00731
00732 std::string lmName(sformat("landmark%07u", ct));
00733 LINFO("include: %s [%d %d: %d] (%d + %d = %d): %s",
00734 (*itr)->getName().c_str(), start, end, range,
00735 numObjects, numTempObjects, numTotal, lmName.c_str());
00736 (*itr)->setName(lmName);
00737 ++ itr;
00738 ct++;
00739 }
00740 else
00741 {
00742 LINFO("Landmark[%d][%d] is too small: [%d %d: %d] %d + %d = %d",
00743 i, orgCt, start, end, range,
00744 numObjects, numTempObjects, numTotal);
00745
00746 itr = itsLandmarks[i].erase(itr);
00747 }
00748 orgCt++;
00749 }
00750 }
00751 }
00752
00753
00754 void LandmarkDB::display()
00755 {
00756
00757 if(itsWin.is_invalid()) { LINFO("no window display"); return; }
00758
00759 Dims d = itsWin->getDims();
00760 int w = d.w(), h = d.h();
00761 int nSegment = itsLandmarks.size();
00762
00763
00764 for(int i = 0; i < nSegment; i ++)
00765 {
00766
00767 int size = itsLandmarks[i].size();
00768 printf("segment [%4d] has: %d landmarks\n",i,size);
00769 for(int j = 0; j < size; j++)
00770 {
00771
00772 int nObjects = itsLandmarks[i][j]->numObjects();
00773 int nTObjects = itsLandmarks[i][j]->numTempObjects();
00774 printf(" lm[%4d][%4d] has %d vo + %d temp = %d\n", i, j,
00775 nObjects, nTObjects, nObjects + nTObjects);
00776
00777
00778 for(int k = 0; k < nObjects; k++)
00779 {
00780 printf("image %4d: %s ", k, itsLandmarks[i][j]
00781 ->getObject(k)->getName().c_str());
00782 Image<PixRGB<byte> > tIma(w,h,ZEROS);
00783
00784 Point2D<int> salpt =
00785 itsLandmarks[i][j]->getObject(k)->getSalPoint();
00786 Point2D<int> offset =
00787 itsLandmarks[i][j]->getOffsetCoords(k);
00788
00789 inplacePaste
00790 (tIma, itsLandmarks[i][j]->getObject(k)
00791 ->getKeypointImage(1.0F,0.0F), offset);
00792 drawDisk(tIma, salpt+offset, 3, PixRGB<byte>(255,255,0));
00793
00794 itsWin->drawImage(tIma,0,0);
00795 Raster::waitForKey();
00796 }
00797 }
00798 }
00799 }
00800
00801
00802 void LandmarkDB::printSkiplist()
00803 {
00804 Dims d = itsWin->getDims();
00805 int w = d.w(), h = d.h();
00806
00807
00808 LINFO("skipping %"ZU" images", itsSkipList.size());
00809 for(uint i = 0; i < itsSkipList.size(); i ++)
00810 {
00811 Image<PixRGB<byte> > tIma(w,h,ZEROS);
00812 inplacePaste
00813 (tIma,itsSkipList[i]->getKeypointImage(1.0F,0.0F), Point2D<int>(0, 0));
00814 itsWin->drawImage(tIma,0,0);
00815 LINFO("Image %d: %s has %d kp", i,
00816 itsSkipList[i]->getName().c_str(), itsSkipList[i]->numKeypoints());
00817 Raster::waitForKey();
00818 }
00819 }
00820
00821
00822 void LandmarkDB::setSession(std::string sessionFName, bool sort)
00823 {
00824
00825 FILE *fp; char inLine[100];
00826 if((fp = fopen(sessionFName.c_str(),"rb")) == NULL)
00827 LFATAL("session file: %s not found", sessionFName.c_str());
00828 LINFO("session file name: %s",sessionFName.c_str());
00829
00830
00831 itsSessionNames.clear();
00832 itsSessionLength.clear();
00833
00834
00835 while(fgets(inLine, 1000, fp) != NULL)
00836 {
00837
00838 char sName[100]; int cStart, cNum; int gTruth;
00839 sscanf(inLine, "%s %d %d %d", sName, &cStart, &cNum, &gTruth);
00840 LDEBUG("%20s: %d: %d - %d: %d", sName, gTruth, cNum, cStart, cNum - cStart);
00841 itsSessionNames.push_back(std::string(sName));
00842 itsSessionLength.push_back(cNum - cStart);
00843 }
00844 fclose(fp);
00845
00846
00847 if(sort) sortLandmarks();
00848
00849
00850 setSessionInfo();
00851 }
00852
00853
00854 void LandmarkDB::sortLandmarks()
00855 {
00856 for(uint i = 0; i < itsLandmarks.size(); i++)
00857 for(uint j = 0; j < itsLandmarks[i].size(); j++)
00858 itsLandmarks[i][j]->sort(itsSessionNames);
00859 }
00860
00861
00862 void LandmarkDB::setSessionInfo()
00863 {
00864
00865 for(uint i = 0; i < itsLandmarks.size(); i++)
00866 for(uint j = 0; j < itsLandmarks[i].size(); j++)
00867 itsLandmarks[i][j]->setSessionInfo();
00868
00869
00870 setSessionLandmarks();
00871
00872
00873 setLocationRange();
00874 }
00875
00876
00877 void LandmarkDB::setSessionLandmarks()
00878 {
00879 LINFO("set");
00880 uint nses = itsSessionNames.size();
00881 if(nses == 0) return;
00882
00883 uint nseg = itsLandmarks.size();
00884 itsSessionLandmarks.resize(nses);
00885 for(uint i = 0; i < nses; i++)
00886 {
00887 std::string session = itsSessionNames[i];
00888 LDEBUG("[%d] session: %s", i, session.c_str());
00889
00890
00891 itsSessionLandmarks[i].resize(nseg);
00892 for(uint j = 0; j < nseg; j++)
00893 {
00894 uint nlmk = itsLandmarks[j].size();
00895 LDEBUG("itsLmk[%d]: %d", j, nlmk);
00896 for(uint k = 0; k < nlmk; k++)
00897 {
00898 LDEBUG("check: itsLmk[%d][%d] ", j, k);
00899 if(itsLandmarks[j][k]->haveSessionVO(session))
00900 {
00901 itsSessionLandmarks[i][j].push_back
00902 (itsLandmarks[j][k]);
00903 LDEBUG("match");
00904 }
00905 }
00906 }
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916 }
00917 }
00918
00919
00920 void LandmarkDB::setLocationRange()
00921 {
00922 LINFO("set");
00923
00924
00925 uint nseg = itsLandmarks.size();
00926 itsLandmarkLocationRange.resize(nseg);
00927 for(uint i = 0; i < nseg; i++)
00928 {
00929
00930 uint nlmk = itsLandmarks[i].size();
00931 itsLandmarkLocationRange[i].resize(nlmk);
00932 for(uint j = 0; j < nlmk; j++)
00933 {
00934 uint nsession = itsLandmarks[i][j]->getNumSession();
00935
00936 float mfltrav = 1.0;
00937 float mlltrav = 0.0;
00938 for(uint k = 0; k < nsession; k++)
00939 {
00940
00941 std::pair<uint,uint> r =
00942 itsLandmarks[i][j]->getSessionIndexRange(k);
00943
00944 float fltrav = getLenTrav(i, j, r.first);
00945 float lltrav = getLenTrav(i, j, r.second);
00946
00947 if(mfltrav > fltrav) mfltrav = fltrav;
00948 if(mlltrav < lltrav) mlltrav = lltrav;
00949
00950 LDEBUG("[%d][%d]f-l: %f %f, m_f-l: %f %f",
00951 i, j, fltrav, lltrav, mfltrav, mlltrav);
00952 }
00953
00954 LDEBUG("m_f-l: %f %f", mfltrav, mlltrav);
00955
00956 itsLandmarkLocationRange[i][j] =
00957 std::pair<float,float>(mfltrav, mlltrav);
00958 }
00959 }
00960 }
00961
00962
00963 float LandmarkDB::getLenTrav(uint snum, uint lnum, uint index)
00964 {
00965
00966 std::string sname =
00967 itsLandmarks[snum][lnum]->getObject(index)->getName();
00968 LDEBUG("session name: %s", sname.c_str());
00969 sname = sname.substr(0, sname.find_last_of('_'));
00970 sname = sname.substr(0, sname.find_last_of('_'));
00971 sname = sname.substr(0, sname.find_last_of('_'));
00972
00973 uint i = 0;
00974
00975 while((i < itsSessionNames.size()) &&
00976 (sname != itsSessionNames[i]) ) i++;
00977
00978
00979 if(i < itsSessionNames.size())
00980 {
00981 float slen = float(itsSessionLength[i]);
00982 float fNum = float(itsLandmarks[snum][lnum]->
00983 getVisualObjectFNum(index));
00984 LDEBUG("session name: %s: %f/%f = %f",
00985 itsSessionNames[i].c_str(), fNum, slen, fNum/slen);
00986 return fNum/slen;
00987 }
00988 else LFATAL("Session not in list: %s (%s)", sname.c_str(),
00989 itsLandmarks[snum][lnum]->getObject(index)->getName().c_str());
00990 return -1.0F;
00991 }
00992
00993
00994
00995
00996
00997