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 #include "Beobot/Landmark.H"
00041 #include "Util/Timer.H"
00042 #include "Raster/Raster.H"
00043 #include "Image/CutPaste.H"
00044 #include "Image/DrawOps.H"
00045 #include "Image/MathOps.H"
00046
00047 #include <iostream>
00048 #include <list>
00049 #include <fstream>
00050
00051 #define FWAIT_NUM 5U
00052 #define MIN_LINKS 3U
00053 #define NUM_FRAME_LOOKBACK 10
00054
00055
00056 Landmark::Landmark(const std::string& name):
00057 itsName(name),
00058 itsVoma (new VisualObjectMatchAlgo(VOMA_SIMPLE)),
00059
00060 itsVisualObjectDB(new VisualObjectDB()),
00061 itsOffsetCoords(),
00062 itsVisualObjectFNum(),
00063 itsTempVisualObjectDB(new VisualObjectDB()),
00064 itsTempOffsetCoords(),
00065 itsTempVisualObjectFNum(),
00066 itsKPtrackers(),
00067 itsCip()
00068 {
00069
00070
00071 itsLatestVisualObjectFNum = 0;
00072 itsLatestTempVisualObjectFNum = 0;
00073 }
00074
00075
00076 Landmark::Landmark(rutz::shared_ptr<VisualObject>& obj,
00077 Point2D<int> objOffset, uint fNum,
00078 const std::string& name):
00079 itsName(name),
00080 itsVoma (new VisualObjectMatchAlgo(VOMA_SIMPLE)),
00081
00082 itsVisualObjectDB(new VisualObjectDB()),
00083 itsOffsetCoords(),
00084 itsVisualObjectFNum(),
00085 itsTempVisualObjectDB(new VisualObjectDB()),
00086 itsTempOffsetCoords(),
00087 itsTempVisualObjectFNum(),
00088 itsKPtrackers(),
00089 itsCip()
00090 {
00091 itsLatestVisualObjectFNum = fNum;
00092 itsLatestTempVisualObjectFNum = 0;
00093 init(obj, objOffset, fNum);
00094 }
00095
00096
00097 void Landmark::init(rutz::shared_ptr<VisualObject>& obj,
00098 Point2D<int> objOffset, uint fNum)
00099 {
00100
00101
00102
00103 addObject(obj, objOffset, fNum);
00104
00105
00106 for(uint i = 0; i < obj->numKeypoints(); i++)
00107 {
00108 rutz::shared_ptr<KeypointTracker>
00109 newKPtracker(new KeypointTracker(sformat("KPtrk%d_%d", fNum, i)));
00110 newKPtracker->add(obj->getKeypoint(i), objOffset, fNum);
00111 itsKPtrackers.push_back(newKPtracker);
00112 }
00113 LINFO("there are %"ZU" keypoints tracked", itsKPtrackers.size());
00114 }
00115
00116
00117 bool Landmark::loadFrom(const std::string& fname)
00118 {
00119
00120 bool succeed = false;
00121
00122
00123
00124
00125
00126
00127 const char *fn = fname.c_str();
00128 LINFO("Loading Visual Object database: '%s'...", fn);
00129
00130 std::ifstream inf(fn);
00131 if (inf.is_open() == false)
00132 { LERROR("Cannot open '%s' -- USING EMPTY", fn); succeed = false; }
00133 else
00134 {
00135
00136 std::string name;
00137 std::getline(inf, name);
00138
00139 itsVisualObjectDB->setName(name);
00140
00141 uint size; inf>>size;
00142 itsVisualObjectDB->clearObjects(size);
00143
00144 uint count = 0;
00145 while (count < size)
00146 {
00147 rutz::shared_ptr<VisualObject> newvo(new VisualObject());
00148
00149
00150 newvo->createVisualObject(inf, *newvo, false);
00151
00152 std::string iname = newvo->getImageFname();
00153
00154
00155 std::string::size_type spos = fname.find_last_of('/');
00156 std::string filePath("");
00157 if(spos != std::string::npos)
00158 filePath = fname.substr(0,spos+1);
00159 std::string fiName = filePath + iname;
00160 newvo->setImageFname(fiName);
00161 newvo->loadImage();
00162
00163 itsVisualObjectDB->setObject(count, newvo);
00164 count++;
00165 LDEBUG("[%d] %s ", count, fiName.c_str());
00166 }
00167
00168 inf.close();
00169 LINFO("Done. Loaded %u VisualObjects.", numObjects());
00170 succeed = true;
00171 }
00172
00173
00174
00175
00176
00177
00178 if(succeed)
00179 {
00180
00181 itsName = itsVisualObjectDB->getName();
00182
00183
00184
00185 for(uint i = 0; i < itsVisualObjectDB->numObjects(); i++)
00186 {
00187 std::string tName = itsVisualObjectDB->getObject(i)->getName();
00188 int ioff, joff, fNum;
00189 std::string temp;
00190
00191
00192
00193 LDEBUG("tName: %s", tName.c_str());
00194 int lupos = tName.find_last_of('_');
00195 temp = tName.substr(lupos+1, tName.length()-lupos-1);
00196 tName = tName.substr(0, lupos);
00197 fNum = atoi(temp.c_str());
00198
00199 lupos = tName.find_last_of('_');
00200 temp = tName.substr(lupos+1, tName.length()-lupos-1);
00201 tName = tName.substr(0, lupos);
00202 joff = atoi(temp.c_str());
00203
00204 lupos = tName.find_last_of('_');
00205 temp = tName.substr(lupos+1, tName.length()-lupos-1);
00206 tName = tName.substr(0, lupos);
00207 ioff = atoi(temp.c_str());
00208
00209 tName = tName.substr(0, lupos);
00210
00211 LDEBUG("[%3d] %30s: (%3d %3d) fnum: %5d",
00212 i, tName.c_str(), ioff, joff, fNum);
00213
00214 itsOffsetCoords.push_back(Point2D<int>(ioff, joff));
00215 itsVisualObjectFNum.push_back(fNum);
00216
00217 itsVisualObjectDB->getObject(i)->setName(tName);
00218
00219 }
00220 return true;
00221 }
00222 else return false;
00223 }
00224
00225
00226 void Landmark::setSessionInfo()
00227 {
00228 itsSession.clear();
00229 itsSessionIndexRange.clear();
00230 ASSERT(itsVisualObjectDB->numObjects() > 0);
00231
00232 std::string lname; uint sind = 0, eind = 0;
00233 for(uint i = 0; i < itsVisualObjectDB->numObjects(); i++)
00234 {
00235
00236
00237 std::string sname = itsVisualObjectDB->getObject(i)->getName();
00238 sname = sname.substr(0, sname.find_last_of('_'));
00239 sname = sname.substr(0, sname.find_last_of('_'));
00240 sname = sname.substr(0, sname.find_last_of('_'));
00241
00242
00243 if(i != 0 && sname.compare(lname))
00244 {
00245 itsSessionIndexRange.push_back(std::pair<uint,uint>(sind,eind));
00246 itsSession.push_back(lname);
00247 sind = i;
00248 }
00249 lname = sname;
00250 eind = i;
00251 }
00252
00253
00254 itsSessionIndexRange.push_back(std::pair<uint,uint>(sind,eind));
00255 itsSession.push_back(lname);
00256
00257
00258 uint nSession = itsSession.size();
00259 for(uint i = 0; i < nSession; i++)
00260 LDEBUG("session[%3d] %30s: [%4d %4d]", i, itsSession[i].c_str(),
00261 itsSessionIndexRange[i].first, itsSessionIndexRange[i].second);
00262
00263
00264 computeSalientFeatures();
00265 }
00266
00267
00268 void Landmark::computeSalientFeatures()
00269 {
00270 uint nObject = numObjects();
00271 if (nObject == 0) return;
00272 uint nFeatures = itsVisualObjectDB->getObject(0)->numFeatures();
00273 itsSalientFeatures.resize(nFeatures);
00274
00275
00276 for(uint i = 0; i < nFeatures; i++)
00277 {
00278 Image<double> temp(1,nObject, NO_INIT);
00279 Image<double>::iterator aptr = temp.beginw(), stop = temp.endw();
00280
00281 uint j = 0;
00282 while (aptr != stop)
00283 {
00284 *aptr++ = itsVisualObjectDB->getObject(j)->getFeature(i); j++;
00285 }
00286 double tMean = mean(temp);
00287 double tStdev = stdev(temp);
00288 LDEBUG("[%5d] m: %f s: %f", i, tMean, tStdev);
00289
00290 itsSalientFeatures[i] = std::pair<double,double>(tMean, tStdev);
00291 }
00292 }
00293
00294
00295 float Landmark::matchSalientFeatures(rutz::shared_ptr<VisualObject> object)
00296 {
00297
00298
00299
00300 std::vector<float> objFeat = object->getFeatures();
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 float cval = 0.0;
00322
00323 std::vector<float>::iterator aptr = objFeat.begin(), stop = objFeat.end();
00324 std::vector<std::pair<double,double> >::iterator
00325 bptr = itsSalientFeatures.begin();
00326 while (aptr != stop)
00327 {
00328 float val = pow(*aptr++ - (*bptr).first, 2.0F); bptr++;
00329 cval += val;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339 cval = sqrt(cval/objFeat.size());
00340
00341
00342
00343 return cval;
00344 }
00345
00346
00347 bool Landmark::saveTo(const std::string& fname)
00348 {
00349
00350 itsVisualObjectDB->setName(itsName);
00351
00352 uint nObjects = itsVisualObjectDB->numObjects();
00353 std::vector<std::string> tNames(nObjects);
00354
00355
00356
00357 for(uint i = 0; i < nObjects; i ++)
00358 {
00359 int ioff, joff, fNum;
00360 ioff = itsOffsetCoords[i].i;
00361 joff = itsOffsetCoords[i].j;
00362 fNum = itsVisualObjectFNum[i];
00363
00364 std::string orgName = itsVisualObjectDB->getObject(i)->getName();
00365 tNames[i] = orgName;
00366 LDEBUG("%s__%d_%d_%d", orgName.c_str(), ioff, joff, fNum);
00367 std::string
00368 appName(sformat("%s_%d_%d_%d",
00369 orgName.c_str(), ioff, joff, fNum));
00370
00371 itsVisualObjectDB->getObject(i)->setName(std::string(appName));
00372 }
00373
00374
00375 bool retVal = itsVisualObjectDB->saveTo(fname);
00376
00377
00378 for(uint i = 0; i < nObjects; i ++)
00379 {
00380 itsVisualObjectDB->getObject(i)->setName(tNames[i]);
00381 }
00382 return retVal;
00383 }
00384
00385
00386 Landmark::~Landmark()
00387 { }
00388
00389
00390
00391 rutz::shared_ptr<VisualObjectMatch>
00392 Landmark::build(rutz::shared_ptr<VisualObject> obj,
00393 Point2D<int> objOffset, uint fNum)
00394 {
00395
00396 if(numObjects() == 0)
00397 {
00398 init(obj, objOffset, fNum);
00399 return rutz::shared_ptr<VisualObjectMatch>();
00400 }
00401 else
00402 return input(obj, objOffset, fNum);
00403 }
00404
00405
00406
00407
00408 rutz::shared_ptr<VisualObjectMatch>
00409 Landmark::build(rutz::shared_ptr<VisualObject> obj, uint fNum)
00410 {
00411 return build(obj, Point2D<int>( 0, 0), fNum);
00412 }
00413
00414
00415
00416
00417
00418 rutz::shared_ptr<VisualObjectMatch>
00419 Landmark::buildCheck(rutz::shared_ptr<VisualObject> obj,
00420 Point2D<int> objOffset, uint fNum,
00421 bool &inDB, bool &inTDB, int &tIndex)
00422 {
00423
00424 if(numObjects() == 0)
00425 {
00426
00427 inDB = false; inTDB = false;
00428 return rutz::shared_ptr<VisualObjectMatch>();
00429 }
00430 else
00431 return inputCheck(obj, objOffset, fNum, inDB, inTDB, tIndex);
00432 }
00433
00434
00435
00436 rutz::shared_ptr<VisualObjectMatch>
00437 Landmark::buildCheck(rutz::shared_ptr<VisualObject> obj, uint fNum,
00438 bool &inDB, bool &inTDB, int &tIndex)
00439 {
00440 return buildCheck(obj, Point2D<int>( 0, 0), fNum,
00441 inDB, inTDB, tIndex);
00442 }
00443
00444
00445
00446
00447 rutz::shared_ptr<VisualObjectMatch>
00448 Landmark::build(rutz::shared_ptr<VisualObject> obj,
00449 Point2D<int> objOffset, uint fNum,
00450 bool inDB, bool inTDB, int tIndex,
00451 rutz::shared_ptr<VisualObjectMatch> cmatch)
00452 {
00453
00454 if(numObjects() == 0)
00455 {
00456 init(obj, objOffset, fNum);
00457 return rutz::shared_ptr<VisualObjectMatch>();
00458 }
00459 else
00460 return input(obj, objOffset, fNum, inDB, inTDB, tIndex, cmatch);
00461 }
00462
00463
00464
00465
00466 rutz::shared_ptr<VisualObjectMatch>
00467 Landmark::build(rutz::shared_ptr<VisualObject> obj, uint fNum,
00468 bool inDB, bool inTDB, int tIndex,
00469 rutz::shared_ptr<VisualObjectMatch> cmatch)
00470 {
00471 return build(obj, Point2D<int>(0,0), fNum, inDB, inTDB, tIndex, cmatch);
00472 }
00473
00474
00475
00476 rutz::shared_ptr<VisualObjectMatch>
00477 Landmark::input(rutz::shared_ptr<VisualObject> obj,
00478 Point2D<int> objOffset, uint fNum)
00479 {
00480 Image<PixRGB<byte> > objImg = obj->getImage();
00481 int objW = objImg.getDims().w();
00482 int objH = objImg.getDims().h();
00483
00484 Rectangle objRect(objOffset, objImg.getDims());
00485 LINFO("%s (sal:[%d %d]) info: at [%d, %d, %d, %d]: %d by %d",
00486 obj->getName().c_str(), obj->getSalPoint().i, obj->getSalPoint().j,
00487 objOffset.i, objOffset.j,
00488 objOffset.i+objW-1, objOffset.j + objH-1, objW, objH);
00489
00490
00491
00492 rutz::shared_ptr<VisualObjectMatch> cmatch;
00493 int mInd = findDBmatch(obj, cmatch, NUM_FRAME_LOOKBACK);
00494 LINFO("found DB match: %d", mInd);
00495
00496
00497 if(mInd == -1)
00498 {
00499 int mtInd = findTempDBmatch(obj, cmatch, NUM_FRAME_LOOKBACK);
00500 LINFO("found TDB match: %d",mtInd);
00501
00502
00503 if(mtInd != -1)
00504 {
00505
00506 moveTempVisualObjectToDB(mtInd);
00507 LINFO("now have %d objects",
00508 itsVisualObjectDB->numObjects());
00509 }
00510 else
00511 {
00512
00513 LINFO("not adding %s (%d) to landmark %s",
00514 obj->getName().c_str(), fNum, itsName.c_str());
00515 return cmatch;
00516 }
00517 }
00518
00519
00520 if(obj->getSalPoint().i == -1 && obj->getSalPoint().j == -1)
00521 cmatch = cropInputImage(obj, objOffset, mInd, cmatch);
00522
00523
00524 LINFO("put to temp holding first");
00525 tAddObject(obj, objOffset, fNum);
00526
00527
00528
00529
00530 return cmatch;
00531 }
00532
00533
00534
00535 rutz::shared_ptr<VisualObjectMatch>
00536 Landmark::inputCheck(rutz::shared_ptr<VisualObject> obj,
00537 Point2D<int> objOffset, uint fNum,
00538 bool &inDB, bool &inTDB, int &tIndex)
00539 {
00540 Image<PixRGB<byte> > objImg = obj->getImage();
00541 int objW = objImg.getDims().w();
00542 int objH = objImg.getDims().h();
00543
00544 Rectangle objRect(objOffset, objImg.getDims());
00545 LINFO("%s (sal:[%d %d]) info: at [%d, %d, %d, %d]: %d by %d",
00546 obj->getName().c_str(), obj->getSalPoint().i, obj->getSalPoint().j,
00547 objOffset.i, objOffset.j,
00548 objOffset.i+objW-1, objOffset.j + objH-1, objW, objH);
00549
00550
00551
00552 rutz::shared_ptr<VisualObjectMatch> cmatch;
00553 int mInd = findDBmatch(obj, cmatch, NUM_FRAME_LOOKBACK);
00554 LINFO("find DB match: %d", mInd);
00555
00556
00557 if(mInd == -1)
00558 {
00559 inDB = false;
00560 int mtInd = findTempDBmatch(obj, cmatch, NUM_FRAME_LOOKBACK);
00561 LINFO("found match at temp: %d",mtInd);
00562
00563
00564 if(mtInd != -1) { inTDB = true; tIndex = mtInd; }
00565 else
00566 {
00567
00568 inTDB = false; tIndex = -1;
00569 LINFO("cannot add %s (%d) to landmark %s",
00570 obj->getName().c_str(), fNum, itsName.c_str());
00571 return cmatch;
00572 }
00573 }
00574
00575 else { inDB = true; inTDB = false; tIndex = mInd; }
00576
00577 return cmatch;
00578 }
00579
00580
00581
00582
00583 rutz::shared_ptr<VisualObjectMatch>
00584 Landmark::input(rutz::shared_ptr<VisualObject> obj,
00585 Point2D<int> objOffset, uint fNum,
00586 bool inDB, bool inTDB, int tIndex,
00587 rutz::shared_ptr<VisualObjectMatch> cmatch)
00588 {
00589 Image<PixRGB<byte> > objImg = obj->getImage();
00590 int objW = objImg.getDims().w();
00591 int objH = objImg.getDims().h();
00592
00593 Rectangle objRect(objOffset, objImg.getDims());
00594 LINFO("%s (sal:[%d %d]) at [%d, %d, %d, %d]: %d by %d: {%d %d %d}",
00595 obj->getName().c_str(), obj->getSalPoint().i, obj->getSalPoint().j,
00596 objOffset.i, objOffset.j,
00597 objOffset.i+objW-1, objOffset.j + objH-1, objW, objH,
00598 inDB, inTDB,tIndex);
00599
00600
00601 if(!inDB && !inTDB)
00602 {
00603
00604 return rutz::shared_ptr<VisualObjectMatch>();
00605 }
00606
00607
00608 if(!inDB && inTDB)
00609 {
00610
00611 moveTempVisualObjectToDB(tIndex);
00612 LINFO("now have %d objects", itsVisualObjectDB->numObjects());
00613 }
00614
00615
00616 if(obj->getSalPoint().i == -1 && obj->getSalPoint().j == -1)
00617 cmatch = cropInputImage(obj, objOffset, tIndex, cmatch);
00618
00619
00620 LINFO("put to temp holding first");
00621 tAddObject(obj, objOffset, fNum);
00622
00623
00624 return rutz::shared_ptr<VisualObjectMatch>();
00625 }
00626
00627
00628 rutz::shared_ptr<VisualObjectMatch> Landmark::cropInputImage
00629 ( rutz::shared_ptr<VisualObject> &obj, Point2D<int> &objOffset,
00630 int mInd, rutz::shared_ptr<VisualObjectMatch> cmatch)
00631 {
00632 const Image<PixRGB<byte> > objImg = obj->getImage();
00633
00634
00635 Rectangle tempR = cmatch->getOverlapRect();
00636 LINFO("getOverlapRect [ %d, %d, %d, %d ]",
00637 tempR.top(), tempR.left(), tempR.bottomI(), tempR.rightI());
00638 tempR = tempR.getOverlap(objImg.getBounds());
00639
00640
00641
00642 Dims prevDims =
00643 itsVisualObjectDB->getObject(mInd)->getImage().getDims();
00644 if((tempR.width() > 1.05 * prevDims.w()) ||
00645 (tempR.height() > 1.05 * prevDims.h()) )
00646 {
00647 LINFO("%d by %d vs %d by %d resize window manually",
00648 tempR.width(),tempR.height(), prevDims.w(), prevDims.h());
00649
00650 Point2D<int> nPt(int(-cmatch->getSIFTaffine().tx),
00651 int(-cmatch->getSIFTaffine().ty) );
00652
00653 tempR = Rectangle(nPt, prevDims).getOverlap(objImg.getBounds());
00654 LINFO(" at [%d, %d, %d, %d]: %d by %d",
00655 nPt.i , nPt.j,
00656 nPt.i + prevDims.w() - 1, nPt.j + prevDims.h() - 1,
00657 prevDims.w(), prevDims.h());
00658 }
00659
00660
00661 Image< PixRGB<byte> > cImg = crop(objImg, tempR);
00662 objOffset.i += tempR.left();
00663 objOffset.j += tempR.top();
00664 LINFO("Overlap object: (%d,%d)", objOffset.i, objOffset.j);
00665
00666 std::string wName = obj->getName() + std::string("-SAL");
00667 std::string wfName = wName + std::string(".png");
00668 obj.reset(new VisualObject(wName, wfName, cImg));
00669
00670
00671 bool isSIFTfit;
00672 rutz::shared_ptr<VisualObjectMatch>
00673 cmatch2 = match(itsVisualObjectDB->getObject(mInd), obj, isSIFTfit);
00674 return cmatch2;
00675 }
00676
00677
00678 void Landmark::transferEvidence
00679 ( rutz::shared_ptr<Landmark> landmark2,
00680 bool indb2, bool intdb2, int tIndex2,
00681 rutz::shared_ptr<VisualObjectMatch> cmatch)
00682 {
00683 rutz::shared_ptr<VisualObject> object2;
00684 Point2D<int> objOffset2;
00685 uint fnum2;
00686
00687 LINFO("{%d, %d, %d}", indb2, intdb2, tIndex2);
00688
00689
00690 if(indb2)
00691 {
00692 object2 = landmark2->getObject(tIndex2);
00693 objOffset2 = landmark2->getOffsetCoords(tIndex2);
00694 fnum2 = landmark2->getVisualObjectFNum(tIndex2);
00695
00696 addObject(object2, objOffset2, fnum2);
00697 }
00698 else if(intdb2)
00699 {
00700 object2 = landmark2->getTempObject(tIndex2);
00701 objOffset2 = landmark2->getTempOffsetCoords(tIndex2);
00702 fnum2 = landmark2->getTempVisualObjectFNum(tIndex2);
00703
00704 addObject(object2, objOffset2, fnum2);
00705 }
00706
00707
00708 if(indb2 || intdb2)
00709 landmark2->cleanDelete(indb2, intdb2, tIndex2);
00710 }
00711
00712
00713 void Landmark::cleanDelete(bool indb, bool intdb, int tIndex)
00714 {
00715 if(indb)
00716 {
00717 LINFO("in db");
00718 if(numTempObjects() == 0 ||
00719 itsLatestTempVisualObjectFNum < itsVisualObjectFNum[tIndex])
00720 {
00721 LINFO(" none to move in temp");
00722 eraseObject(tIndex);
00723 eraseOffsetCoords(tIndex);
00724 eraseVisualObjectFNum(tIndex);
00725 }
00726 else
00727 {
00728 LINFO(" something to move in temp");
00729
00730
00731 uint fnum = itsVisualObjectFNum[tIndex];
00732 uint ltfnum = itsLatestTempVisualObjectFNum;
00733
00734 int rindex = -1;
00735 for(uint fn = fnum+1; fn <= ltfnum; fn++)
00736 {
00737 for(int i = int(itsTempVisualObjectFNum.size()-1); i >= 0; i--)
00738 {
00739 uint cn = itsTempVisualObjectFNum[i];
00740 if(cn == fn)
00741 {
00742 rindex = i;
00743 LINFO("rind: %d i: %d cn: %d fn: %d", rindex, i, cn, fn);
00744 i = 0; fn = ltfnum+1;
00745 }
00746 }
00747 }
00748
00749 if(rindex != -1)
00750 {
00751 LINFO("before: fnum: %d",itsVisualObjectFNum[tIndex]);
00752 itsVisualObjectDB->setObject
00753 (tIndex, itsTempVisualObjectDB->getObject(rindex));
00754 itsOffsetCoords[tIndex] = itsTempOffsetCoords[rindex];
00755 itsVisualObjectFNum[tIndex] = itsTempVisualObjectFNum[rindex];
00756 LINFO("after : fnum: %d",itsVisualObjectFNum[tIndex]);
00757
00758 LINFO("before: T: %d", numTempObjects());
00759 eraseTempObject(rindex);
00760 eraseTempOffsetCoords(rindex);
00761 eraseTempVisualObjectFNum(rindex);
00762 LINFO("after : T: %d", numTempObjects());
00763 }
00764
00765
00766 itsLatestTempVisualObjectFNum = 0;
00767 for(uint i = 0; i < itsTempVisualObjectFNum.size(); i++)
00768 {
00769 if(itsLatestTempVisualObjectFNum < itsTempVisualObjectFNum[i])
00770 itsLatestTempVisualObjectFNum = itsTempVisualObjectFNum[i];
00771 }
00772 }
00773
00774
00775 itsLatestVisualObjectFNum = 0;
00776 for(uint i = 0; i < itsVisualObjectFNum.size(); i++)
00777 {
00778 if(itsLatestVisualObjectFNum < itsVisualObjectFNum[i])
00779 itsLatestVisualObjectFNum = itsVisualObjectFNum[i];
00780 }
00781 }
00782 else if(intdb)
00783 {
00784 LINFO("intdb");
00785
00786 eraseTempObject(tIndex);
00787 eraseTempOffsetCoords(tIndex);
00788 eraseTempVisualObjectFNum(tIndex);
00789
00790
00791 itsLatestTempVisualObjectFNum = 0;
00792 for(uint i = 0; i < itsTempVisualObjectFNum.size(); i++)
00793 {
00794 if(itsLatestTempVisualObjectFNum < itsTempVisualObjectFNum[i])
00795 itsLatestTempVisualObjectFNum = itsTempVisualObjectFNum[i];
00796 }
00797 }
00798 }
00799
00800
00801
00802 Point2D<int> Landmark::getPosition()
00803 {
00804 uint last = numObjects() - 1;
00805
00806
00807
00808 std::vector<rutz::shared_ptr<Keypoint> > activeKP = getActiveKeypoints();
00809 LINFO("have %"ZU" active keypoints", activeKP.size());
00810
00811
00812 rutz::shared_ptr<KeypointTracker> fittestKPtr = getFittestKPtr();
00813 std::vector<rutz::shared_ptr<Keypoint> >
00814 fKP = fittestKPtr->getKeypoints();
00815
00816
00817 Point2D<int> res = fittestKPtr->getAbsLoc();
00818 LINFO("%s: (%d,%d)", fittestKPtr->getName().c_str(), res. i, res.j);
00819
00820
00821 if(itsMatchWin.is_valid())
00822 {
00823
00824 int w = itsMatchWin->getDims().w()/2;
00825 int h = itsMatchWin->getDims().h()/2;
00826 Image< PixRGB<byte> > tImg(w,h,ZEROS);
00827 Image< PixRGB<byte> > oImg =
00828 itsVisualObjectDB->getObject(last)->getImage();
00829 for(uint i = 0; i < fKP.size(); i++)
00830 {
00831 const float x = fKP[i]->getX();
00832 const float y = fKP[i]->getY();
00833 Point2D<int> loc(int(x + 0.5F), int(y + 0.5F));
00834 drawDisk(oImg, loc, 2, PixRGB<byte>(255,0,0));
00835 LINFO("Loc: (%d,%d)",loc.i,loc.j);
00836 }
00837 inplacePaste(tImg, oImg, Point2D<int>(0, 0));
00838 itsMatchWin->drawImage(tImg,w,h);
00839 }
00840
00841 return res;
00842 }
00843
00844
00845
00846
00847 Point2D<int> Landmark::getVelocity()
00848 {
00849
00850 if(numObjects() == 1)
00851 return Point2D<int>(0,0);
00852
00853
00854
00855 return Point2D<int>(0,0);
00856 }
00857
00858
00859
00860
00861 std::vector<rutz::shared_ptr<Keypoint> > Landmark::getActiveKeypoints()
00862 {
00863
00864 uint last = numObjects() - 1;
00865 uint fNum = itsVisualObjectFNum[last];
00866 uint sfNum = itsVisualObjectFNum[0];
00867 uint dfnum = fNum - sfNum;
00868 dfnum+=0;
00869 LINFO("fNum: %d, sfNum: %d, dfnum: %d",fNum, sfNum, dfnum);
00870
00871 std::vector<rutz::shared_ptr<Keypoint> > res;
00872
00873
00874
00875 for(uint i = 0; i < itsKPtrackers.size(); i++)
00876 {
00877
00878 if((itsKPtrackers[i]->hasKeypointInFrame(fNum)) &&
00879 (itsKPtrackers[i]->numKeypoints() > dfnum ||
00880 itsKPtrackers[i]->numKeypoints() >= MIN_LINKS))
00881 {
00882 res.push_back(itsKPtrackers[i]->getKeypointInFrame(fNum));
00883
00884
00885
00886
00887 }
00888
00889 }
00890
00891
00892 if(itsMatchWin.is_valid())
00893 {
00894
00895 int w = itsMatchWin->getDims().w()/2;
00896 int h = itsMatchWin->getDims().h()/2;
00897 Image< PixRGB<byte> > tImg(w,h,ZEROS);
00898 Image< PixRGB<byte> >
00899 oImg = itsVisualObjectDB->getObject(last)->getImage();
00900 for(uint i = 0; i < res.size(); i++)
00901 {
00902 const float x = res[i]->getX();
00903 const float y = res[i]->getY();
00904 Point2D<int> loc(int(x + 0.5F), int(y + 0.5F));
00905 drawDisk(oImg, loc, 2, PixRGB<byte>(255,0,0));
00906
00907 }
00908 inplacePaste(tImg, oImg, Point2D<int>(0, 0));
00909 itsMatchWin->drawImage(tImg,w,h);
00910 }
00911
00912 return res;
00913 }
00914
00915
00916
00917 rutz::shared_ptr<KeypointTracker> Landmark::getFittestKPtr()
00918 {
00919
00920 uint last = numObjects() - 1;
00921 uint fNum = itsVisualObjectFNum[last];
00922
00923 rutz::shared_ptr<KeypointTracker> res;
00924 uint maxLength = 0U;
00925
00926
00927 for(uint i = 0; i < itsKPtrackers.size(); i++)
00928 {
00929 if((itsKPtrackers[i]->hasKeypointInFrame(fNum)) &&
00930 (itsKPtrackers[i]->numKeypoints() > maxLength))
00931 {
00932 res = itsKPtrackers[i];
00933 maxLength = itsKPtrackers[i]->numKeypoints();
00934 }
00935 }
00936
00937 LINFO("%s: %d", res->getName().c_str(), res->numKeypoints());
00938 return res;
00939 }
00940
00941
00942
00943 void Landmark::temporalPrune(uint index)
00944 {
00945 rutz::shared_ptr<VisualObject> pObj =
00946 itsVisualObjectDB->getObject(index);
00947
00948
00949 LDEBUG("pObj[%d] BEFORE numFeatures: %d", index, pObj->numKeypoints());
00950
00951
00952 std::vector< rutz::shared_ptr<Keypoint> > prunedfKp;
00953
00954
00955 for(uint i = 0; i < itsKPtrackers.size(); i++)
00956 {
00957
00958 if(itsKPtrackers[i]->hasKeypointInFrame(index))
00959 {
00960
00961 rutz::shared_ptr<Keypoint> kp =
00962 itsKPtrackers[i]->getKeypointInFrame(index);
00963 prunedfKp.push_back(kp);
00964 }
00965 }
00966
00967
00968 rutz::shared_ptr<VisualObject> prunedfObj
00969 (new VisualObject(pObj->getName(),
00970 pObj->getImageFname(), pObj->getImage(),
00971 pObj->getSalPoint(),
00972 pObj->getFeatures(), prunedfKp));
00973 LDEBUG("PRUNED numFeatures: %d",prunedfObj->numKeypoints());
00974 itsVisualObjectDB->setObject(index, prunedfObj);
00975 LDEBUG("fAFTER numFeatures: %d", pObj->numKeypoints());
00976
00977
00978 }
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028 void Landmark::trackKeypoints(rutz::shared_ptr<VisualObjectMatch> match,
01029 int mInd)
01030 {
01031 uint last = itsVisualObjectDB->numObjects() - 1;
01032 uint fNum = itsVisualObjectFNum[last];
01033 rutz::shared_ptr<VisualObject> voTst = itsVisualObjectDB->getObject(last);
01034 rutz::shared_ptr<VisualObject> voRef = itsVisualObjectDB->getObject(mInd);
01035
01036 LINFO("we are comparing frames %d and %d",mInd, last);
01037 LINFO("ref->size %d, tst->size: %d match->size: %d, kp->size: %"ZU" ",
01038 voRef->numKeypoints(), voTst->numKeypoints(),
01039 match->size(), itsKPtrackers.size());
01040
01041
01042 std::vector<bool> voTstkpIsAdded;
01043 for(uint i = 0; i < voTst->numKeypoints(); i++)
01044 voTstkpIsAdded.push_back(false);
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061 for(uint i = 0; i < match->size(); i++)
01062 {
01063
01064
01065
01066 for(uint j = 0; j < itsKPtrackers.size(); j++)
01067 {
01068
01069 if(itsKPtrackers[j]->hasKeypointInFrame(mInd) &&
01070 (*match)[i].refkp == itsKPtrackers[j]->getKeypointInFrame(mInd))
01071 {
01072
01073 itsKPtrackers[j]->add((*match)[i].tstkp,
01074 itsOffsetCoords[last],
01075 itsVisualObjectFNum[last]);
01076
01077
01078 for(uint k = 0; k < voTst->numKeypoints(); k++)
01079 {
01080 if((*match)[i].tstkp == voTst->getKeypoint(k))
01081 {
01082 voTstkpIsAdded[k] = true;
01083
01084 }
01085 }
01086 }
01087 }
01088 }
01089
01090
01091 uint nAdded = 0U;
01092 for(uint i = 0; i < voTst->numKeypoints(); i++)
01093 {
01094 if(!voTstkpIsAdded[i])
01095 {
01096 rutz::shared_ptr<KeypointTracker>
01097 newKPtracker(new KeypointTracker
01098 (sformat("KPtrk%d_%d", fNum, nAdded)));
01099 newKPtracker->add(voTst->getKeypoint(i),
01100 itsOffsetCoords[last],
01101 itsVisualObjectFNum[last]);
01102 itsKPtrackers.push_back(newKPtracker);
01103 nAdded++;
01104
01105 }
01106 }
01107
01108
01109
01110 uint ndel = 0U;
01111 if(fNum >= FWAIT_NUM)
01112 {
01113 uint pfNum = fNum - FWAIT_NUM;
01114
01115
01116 std::vector<rutz::shared_ptr<KeypointTracker> >::iterator
01117 itr = itsKPtrackers.begin();
01118 while (itr < itsKPtrackers.end())
01119 {
01120
01121 if((*itr)->isInactiveSince((pfNum+1)) &&
01122 (*itr)->numKeypoints() < MIN_LINKS)
01123 {
01124 itr = itsKPtrackers.erase(itr); ++ ndel;
01125 }
01126 else ++ itr;
01127
01128 }
01129 LINFO("we pruned %d inactive tracker from frame %d", ndel, pfNum);
01130
01131
01132 LINFO(":{}: %d",pfNum);
01133 int pfNumInd = getFNumIndex(pfNum);
01134
01135 if(pfNumInd != -1)
01136 {
01137 LINFO("BEFORE(%d) -> %d numFeatures: %d", pfNum, pfNumInd,
01138 itsVisualObjectDB->getObject(pfNumInd)->numKeypoints());
01139 temporalPrune(pfNumInd);
01140 LINFO("AFTER (%d) -> %d numFeatures: %d", pfNum, pfNumInd,
01141 itsVisualObjectDB->getObject(pfNumInd)->numKeypoints());
01142
01143 }
01144 else
01145 {
01146 LINFO("skipping %d -> %d", pfNum, pfNumInd);
01147 Raster::waitForKey();
01148 }
01149 }
01150 else
01151 LINFO("we pruned 0 inactive trackers");
01152
01153 LINFO("we added %d tracker for frame %d", nAdded, fNum);
01154 LINFO("there are %"ZU" keypoints being tracked", itsKPtrackers.size());
01155
01156
01157
01158
01159 }
01160
01161
01162 int Landmark::getFNumIndex(uint fNum)
01163 {
01164 uint cInd = itsVisualObjectDB->numObjects() - 1;
01165 uint cfNum = itsVisualObjectFNum[cInd];
01166
01167
01168
01169 while (fNum <= cfNum && cInd >= 0)
01170 {
01171
01172 if(fNum == cfNum) return cInd;
01173 if(cInd == 0) return -1;
01174 cInd --;
01175 cfNum = itsVisualObjectFNum[cInd];
01176 }
01177
01178 return -1;
01179 }
01180
01181
01182 Rectangle Landmark::getObjectRect(uint index)
01183 {
01184 rutz::shared_ptr<VisualObject>
01185 vo = itsVisualObjectDB->getObject(index);
01186 Dims voDims = vo->getImage().getDims();
01187 return Rectangle(itsOffsetCoords[index], voDims);
01188 }
01189
01190
01191 rutz::shared_ptr<VisualObjectMatch>
01192 Landmark::match(rutz::shared_ptr<VisualObject> a,
01193 rutz::shared_ptr<VisualObject> b, bool &isFit,
01194 float maxPixDist, float minfsim,
01195 float minscore, uint minmatch,
01196 float maxRotate, float maxScale, float maxShear,
01197 bool showMatch)
01198 {
01199
01200 Timer tim(1000000); tim.reset();
01201 rutz::shared_ptr<VisualObjectMatch>
01202 matchRes(new VisualObjectMatch(a, b, *itsVoma));
01203 uint64 t = tim.get();
01204
01205
01206 uint orgSize = matchRes->size();
01207 tim.reset();
01208 uint np = matchRes->prune();
01209 uint t2 = tim.get();
01210
01211 LDEBUG("Found %u matches for (%s & %s) in %.3fms: pruned %u in %.3fms",
01212 orgSize, a->getName().c_str(),
01213 b->getName().c_str(), float(t) * 0.001F,
01214 np, float(t2) * 0.001F);
01215
01216
01217 float kpAvgDist = matchRes->getKeypointAvgDist();
01218 float afAvgDist = matchRes->getAffineAvgDist();
01219 float score = matchRes->getScore();
01220 bool isSIFTaffine = matchRes->
01221 checkSIFTaffine(maxRotate, maxScale, maxShear);
01222 LDEBUG("maxPixDist: %f minfsim: %f minscore: %f minmatch: %d "
01223 "maxRotate: %f maxScale: %f maxShear: %f",
01224 maxPixDist, minfsim, minscore, minmatch,
01225 maxRotate, maxScale, maxShear);
01226 LDEBUG("kpAvgDist = %.4f|affAvgDist = %.4f|score: %.4f|aff? %d",
01227 kpAvgDist, afAvgDist, score, isSIFTaffine);
01228
01229 if (!isSIFTaffine) LDEBUG("### bad Affine -- BOGUS MATCH");
01230 else if(matchRes->size() >= minscore)
01231 {
01232
01233 SIFTaffine s = matchRes->getSIFTaffine();
01234 LDEBUG("[tstX] [ %- .3f %- .3f ] [refX] [%- .3f]", s.m1, s.m2, s.tx);
01235 LDEBUG("[tstY] = [ %- .3f %- .3f ] [refY] + [%- .3f]", s.m3, s.m4, s.ty);
01236 }
01237
01238
01239 bool isSIFTfit = (isSIFTaffine && (score >= minscore) &&
01240 (matchRes->size() >= minmatch));
01241 LDEBUG("isSIFTfit: %d: (%d && (%f >= %f) && (%d >= %d)) ", isSIFTfit,
01242 isSIFTaffine, score, minscore, matchRes->size(), minmatch);
01243
01244
01245
01246 bool isSalfit = false;
01247 bool salAvailable =
01248 (a->getSalPoint().isValid() && a->getSalPoint().isValid());
01249 if(isSIFTfit && salAvailable)
01250 {
01251 float sdiff = matchRes->getSalDiff();
01252 float sdist = matchRes->getSalDist();
01253
01254
01255
01256 if(sdist <= maxPixDist && sdiff >= minfsim) isSalfit = true;
01257 LDEBUG("isSalFit: %d: (%f <= %f && %f >= %f", isSalfit,
01258 sdist, maxPixDist, sdiff, minfsim);
01259 }
01260 else isSalfit = true;
01261
01262 isFit = isSIFTfit && isSalfit;
01263 LDEBUG("isFit? %d", isFit);
01264
01265
01266 if(showMatch && itsMatchWin.is_valid() &&
01267 a->getImage().initialized() && b->getImage().initialized())
01268 {
01269 int w = itsMatchWin->getDims().w()/2;
01270 int h = itsMatchWin->getDims().h()/2;
01271
01272
01273 Image< PixRGB<byte> > mImg = matchRes->getMatchImage(1.0F);
01274 Image< PixRGB<byte> > fImg = matchRes->getFusedImage(0.25F);
01275 Image< PixRGB<byte> > tImg(2*w,2*h,ZEROS);
01276
01277 inplacePaste(tImg, mImg, Point2D<int>(0, 0));
01278 inplacePaste(tImg, fImg, Point2D<int>(w, 0));
01279
01280 itsMatchWin->drawImage(tImg,0,0);
01281 }
01282 return matchRes;
01283 }
01284
01285
01286 void Landmark::addObject(rutz::shared_ptr<VisualObject> obj,
01287 Point2D<int> objOffset, uint fNum)
01288 {
01289
01290 if (itsVisualObjectDB->addObject(obj))
01291 {
01292
01293 itsVisualObjectFNum.push_back(fNum);
01294 itsOffsetCoords.push_back(objOffset);
01295 if(itsLatestVisualObjectFNum < fNum)
01296 itsLatestVisualObjectFNum = fNum;
01297
01298 if(obj->getSalPoint().i != -1)
01299 LINFO("Added SAL VisualObject '%s' as part of %s evidence.",
01300 obj->getName().c_str(), itsName.c_str());
01301 else
01302 LINFO("Added NON_SAL VisualObject '%s' as part of %s evidence.",
01303 obj->getName().c_str(), itsName.c_str());
01304 }
01305 else
01306 LERROR("FAILED adding VisualObject '%s' to database -- IGNORING",
01307 obj->getName().c_str());
01308 }
01309
01310
01311 void Landmark::tAddObject(rutz::shared_ptr<VisualObject> obj,
01312 Point2D<int> objOffset, uint fNum)
01313 {
01314
01315 if (itsTempVisualObjectDB->addObject(obj))
01316 {
01317
01318 itsTempVisualObjectFNum.push_back(fNum);
01319 itsTempOffsetCoords.push_back(objOffset);
01320 if(itsLatestTempVisualObjectFNum < fNum)
01321 itsLatestTempVisualObjectFNum = fNum;
01322
01323 if(obj->getSalPoint().i != -1)
01324 LINFO("Added SAL VisualObject '%s' as part of %s "
01325 "temporary holding",
01326 obj->getName().c_str(), itsName.c_str());
01327 else
01328 LINFO("Added NON_SAL VisualObject '%s' as part of %s "
01329 "temporary holding",
01330 obj->getName().c_str(), itsName.c_str());
01331 }
01332 else
01333 LERROR("FAILED adding VisualObject '%s' to temp holding",
01334 obj->getName().c_str());
01335 }
01336
01337
01338 int Landmark::match
01339 ( rutz::shared_ptr<VisualObject> obj,
01340 rutz::shared_ptr<VisualObjectMatch> &cmatch, int start, int end,
01341 float maxPixDist, float minfsim, float minscore, uint minmatch,
01342 float maxRotate, float maxScale, float maxShear)
01343 {
01344 if(start == -1) start = 0; ASSERT(start >= 0);
01345 if(end == -1) end = numObjects() - 1; ASSERT(end < int(numObjects()));
01346 ASSERT(start <= end);
01347
01348
01349 int index = findDBmatch(obj, cmatch, end-start+1, true, start,
01350 maxPixDist, minfsim, minscore, minmatch,
01351 maxRotate, maxScale, maxShear);
01352 return index;
01353 }
01354
01355
01356 int Landmark::findDBmatch
01357 (rutz::shared_ptr<VisualObject> obj,
01358 rutz::shared_ptr<VisualObjectMatch> &cmatch, uint nFrames,
01359 bool isForward, int start,
01360 float maxPixDist, float minfsim, float minscore, uint minmatch,
01361 float maxRotate, float maxScale, float maxShear)
01362 {
01363
01364 if(itsVisualObjectDB->numObjects() == 0)
01365 { LINFO("%s DB is empty", itsName.c_str()); return -1; }
01366
01367
01368 int sInd, eInd, inc;
01369 ASSERT((start >= 0 && start < int(numObjects())) || start == -1);
01370 if(start == -1 &&isForward) sInd = 0;
01371 else if(start == -1 && !isForward) sInd = numObjects() - 1;
01372 else sInd = start;
01373
01374 if(isForward)
01375 { eInd = start+nFrames; inc = 1; }
01376 else
01377 { eInd = sInd - nFrames; if(eInd < -1) eInd = -1; inc = -1; }
01378 LDEBUG("Range %s DB: [%d, %d} by %d", itsName.c_str(), sInd, eInd, inc);
01379 int i = sInd; int matchInd = -1;
01380 while(i != eInd)
01381 {
01382 LDEBUG("check %s DB(%d): %s",itsName.c_str(), i,
01383 itsVisualObjectDB->getObject(i)->getName().c_str());
01384
01385
01386 bool isFit; cmatch = match(obj, itsVisualObjectDB->getObject(i), isFit,
01387 maxPixDist, minfsim, minscore, minmatch,
01388 maxRotate, maxScale, maxShear);
01389
01390
01391 if(!isFit)
01392 {
01393 cmatch = match(itsVisualObjectDB->getObject(i), obj, isFit,
01394 maxPixDist, minfsim, minscore, minmatch,
01395 maxRotate, maxScale, maxShear);
01396 }
01397
01398
01399 if(isFit) { matchInd = i; return matchInd; }
01400 i += inc;
01401 }
01402 return matchInd;
01403 }
01404
01405
01406 int Landmark::findTempDBmatch(rutz::shared_ptr<VisualObject> obj,
01407 rutz::shared_ptr<VisualObjectMatch> &cmatch,
01408 uint nFrames,
01409 float maxPixDist, float minfsim,
01410 float minscore, uint minmatch)
01411 {
01412
01413 if(itsTempVisualObjectDB->numObjects() == 0)
01414 { LINFO("TDB of %s is empty", itsName.c_str()); return -1; }
01415
01416
01417 int mtInd = -1; int mintIndex;
01418 if(itsTempVisualObjectDB->numObjects() < nFrames)
01419 mintIndex = 0;
01420 else
01421 mintIndex = itsTempVisualObjectDB->numObjects() - nFrames;
01422 LINFO("Range %s tempDB: [%d, %d]", itsName.c_str(), mintIndex,
01423 itsTempVisualObjectDB->numObjects() - 1);
01424
01425 for(int i = itsTempVisualObjectDB->numObjects() - 1; i >= mintIndex; i--)
01426 {
01427 LDEBUG("check %s tempDB(%d): %s",itsName.c_str(), i,
01428 itsTempVisualObjectDB->getObject(i)->getName().c_str());
01429
01430
01431 bool isFit;
01432 cmatch = match(obj, itsTempVisualObjectDB->getObject(i), isFit,
01433 maxPixDist, minfsim, minscore, minmatch);
01434
01435
01436 if(!isFit)
01437 {
01438 cmatch = match(itsTempVisualObjectDB->getObject(i), obj, isFit,
01439 maxPixDist, minfsim, minscore, minmatch);
01440 }
01441
01442
01443 if(isFit){ mtInd = i; return mtInd; }
01444 }
01445 return mtInd;
01446 }
01447
01448
01449 void Landmark::moveLatestTempVisualObjectToDB()
01450 {
01451 int index = itsTempVisualObjectFNum.size() - 1;
01452 if(index == -1)
01453 {
01454 LINFO("nothing to move in temp of %s", itsName.c_str());
01455 return;
01456 }
01457
01458 LINFO("moving T(%d): %s", index,
01459 itsTempVisualObjectDB->getObject(index)->getName().c_str());
01460 moveTempVisualObjectToDB(index);
01461 }
01462
01463
01464 void Landmark::moveTempVisualObjectToDB(int index)
01465 {
01466 ASSERT(index >= 0 && index < int(numTempObjects()));
01467
01468
01469 addObject(itsTempVisualObjectDB->getObject(index),
01470 itsTempOffsetCoords[index],
01471 itsTempVisualObjectFNum[index]);
01472
01473
01474 if(itsLatestVisualObjectFNum < itsTempVisualObjectFNum[index])
01475 itsLatestVisualObjectFNum = itsTempVisualObjectFNum[index];
01476
01477
01478 itsTempVisualObjectDB->eraseObject(index);
01479 itsTempOffsetCoords.erase(itsTempOffsetCoords.begin() + index);
01480 itsTempVisualObjectFNum.erase(itsTempVisualObjectFNum.begin() + index);
01481
01482
01483 itsLatestTempVisualObjectFNum = 0;
01484 for(uint i = 0; i < itsTempVisualObjectFNum.size(); i++)
01485 {
01486 if(itsLatestTempVisualObjectFNum < itsTempVisualObjectFNum[i])
01487 itsLatestTempVisualObjectFNum = itsTempVisualObjectFNum[i];
01488 }
01489 }
01490
01491
01492 uint Landmark::numMatch(rutz::shared_ptr<Landmark> lmk,
01493 float maxPixDist, float minfsim,
01494 float minscore, uint minmatch)
01495 {
01496 uint count = 0;
01497
01498
01499 for(uint i = 0; i < lmk->numObjects(); i++)
01500 {
01501 LDEBUG("checking lmk->object(%d)", i);
01502 rutz::shared_ptr<VisualObject> obj = lmk->getObject(i);
01503
01504
01505 for(uint j = 0; j < numObjects(); j++)
01506 {
01507 LDEBUG(" with object(%d)", j);
01508
01509
01510 bool isFit;
01511 rutz::shared_ptr<VisualObjectMatch> cmatch =
01512 match(obj, itsVisualObjectDB->getObject(j), isFit,
01513 maxPixDist, minfsim, minscore, minmatch);
01514
01515
01516
01517
01518 if(!isFit)
01519 {
01520 cmatch = match(itsVisualObjectDB->getObject(j), obj, isFit,
01521 maxPixDist, minfsim, minscore, minmatch);
01522
01523
01524 }
01525
01526
01527 if(isFit)
01528 {
01529 count++;
01530 LDEBUG("Match: %s(%d) & %s(%d), count: %d",
01531 lmk->getName().c_str(),i, itsName.c_str(), j, count);
01532
01533
01534 j = numObjects();
01535 }
01536 }
01537 }
01538
01539 return count;
01540 }
01541
01542
01543 void Landmark::combine(rutz::shared_ptr<Landmark> lmk1,
01544 rutz::shared_ptr<Landmark> lmk2)
01545 {
01546
01547 for(uint i = 0; i <lmk1-> numObjects(); i++)
01548 {
01549 addObject(lmk1->getObject(i),
01550 lmk1->getOffsetCoords(i),
01551 lmk1->getVisualObjectFNum(i));
01552 }
01553
01554
01555 for(uint i = 0; i <lmk2-> numObjects(); i++)
01556 {
01557 addObject(lmk2->getObject(i),
01558 lmk2->getOffsetCoords(i),
01559 lmk2->getVisualObjectFNum(i));
01560 }
01561 }
01562
01563
01564 void Landmark::append(rutz::shared_ptr<Landmark> lmk)
01565 {
01566
01567 for(uint i = 0; i <lmk->numObjects(); i++)
01568 {
01569 addObject(lmk->getObject(i),
01570 lmk->getOffsetCoords(i),
01571 lmk->getVisualObjectFNum(i));
01572 }
01573 }
01574
01575
01576 struct SortObj
01577 {
01578 SortObj() { };
01579
01580 SortObj(const rutz::shared_ptr<VisualObject> _obj,
01581 const Point2D<int> _objOffset,
01582 const uint _fNum,
01583 const uint _sNum) :
01584 obj(_obj),
01585 objOffset(_objOffset),
01586 fNum(_fNum),
01587 sNum(_sNum)
01588 { }
01589
01590 rutz::shared_ptr<VisualObject> obj;
01591 Point2D<int> objOffset;
01592 uint fNum;
01593 uint sNum;
01594
01595 bool operator < (const SortObj& rhs)
01596 {
01597 if(sNum != rhs.sNum) return sNum < rhs.sNum;
01598 else return fNum < rhs.fNum;
01599 }
01600
01601 };
01602
01603 void Landmark::sort(std::vector<std::string> sessionNames)
01604 {
01605 std::list<SortObj> tList;
01606 for(uint i = 0; i < numObjects(); i++)
01607 {
01608
01609
01610 rutz::shared_ptr<VisualObject> obj =
01611 itsVisualObjectDB->getObject(i);
01612
01613
01614 std::string sname = obj->getName();
01615 LDEBUG("session name: %s", sname.c_str());
01616 sname = sname.substr(0, sname.find_last_of('_'));
01617 sname = sname.substr(0, sname.find_last_of('_'));
01618 sname = sname.substr(0, sname.find_last_of('_'));
01619
01620 uint j = 0;
01621
01622 while((j < sessionNames.size()) && (sname != sessionNames[j])) j++;
01623 if(j == sessionNames.size())
01624 LFATAL("Session not in list: %s (%s)",
01625 sname.c_str(), obj->getName().c_str());
01626
01627 Point2D<int> objOffset = itsOffsetCoords[i];
01628 uint fNum = itsVisualObjectFNum[i];
01629
01630 LDEBUG("B[%s] [%3d,%3d] [%3d] sNum: %d", obj->getName().c_str(),
01631 objOffset.i, objOffset.j, fNum, j);
01632
01633 tList.push_back(SortObj(obj,objOffset,fNum,j));
01634 }
01635
01636 tList.sort();
01637
01638 rutz::shared_ptr<VisualObjectDB> vodb(new VisualObjectDB());
01639 std::list<SortObj>::iterator itr = tList.begin();
01640 uint ii = 0;
01641 while (itr != tList.end())
01642 {
01643 vodb->addObject((*itr).obj);
01644 itsOffsetCoords[ii] = (*itr).objOffset;
01645 itsVisualObjectFNum[ii] = (*itr).fNum;
01646 itr++; ii++;
01647 }
01648
01649 itsVisualObjectDB = vodb;
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661 }
01662
01663
01664
01665
01666
01667