00001 /*!@file Beobot/Environment.C all the information describing 00002 an environment */ 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Christian Siagian <siagian@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Beobot/Environment.C $ 00035 // $Id: Environment.C 14116 2010-10-08 08:34:50Z siagian $ 00036 // 00037 00038 #include "Beobot/Environment.H" 00039 #include "Image/MatrixOps.H" 00040 #include "Util/Timer.H" 00041 00042 #include <sys/stat.h> 00043 #include <errno.h> 00044 00045 #define LANDMARK_DB_FOLDER_NAME "LandmarkDB" 00046 00047 // ###################################################################### 00048 Environment::Environment(std::string envFName): 00049 itsLandmarkDB(new LandmarkDB()), 00050 itsTopologicalMap(new TopologicalMap()), 00051 itsSegmentRecognizer(new FeedForwardNetwork()), 00052 itsSegmentHistogram(new Histogram()) 00053 { 00054 // check if the file does not exist or it's a blank entry 00055 FILE *fp; if((fp = fopen(envFName.c_str(),"rb")) == NULL) 00056 { 00057 LINFO("Environment file %s not found",envFName.c_str()); 00058 LINFO("Create a blank environment"); 00059 00060 // have to reset landmarkDB size by calling resetLandmarkDB 00061 00062 } 00063 else 00064 { 00065 LINFO("Loading Environment file %s",envFName.c_str()); 00066 load(envFName); 00067 } 00068 } 00069 00070 // ###################################################################### 00071 bool Environment::isBlank() 00072 { 00073 return (itsLandmarkDB->getNumSegment() == 0); 00074 } 00075 00076 // ###################################################################### 00077 bool Environment::load(std::string fName) 00078 { 00079 FILE *fp; char inLine[200]; char comment[200]; 00080 00081 // open the file 00082 LINFO("Environment file: %s",fName.c_str()); 00083 if((fp = fopen(fName.c_str(),"rb")) == NULL) 00084 { LINFO("not found"); return false; } 00085 std::string path = ""; 00086 std::string::size_type spos = fName.find_last_of('/'); 00087 if(spos != std::string::npos) path = fName.substr(0, spos+1); 00088 00089 // get the number of segments 00090 uint nSegment; 00091 if (fgets(inLine, 200, fp) == NULL) LFATAL("fgets failed"); sscanf(inLine, "%s %d", comment, &nSegment); 00092 LINFO("Segment: %d", nSegment); 00093 00094 // clear and resize the landmarkDB and segment histogram 00095 resetNumSegment(nSegment); 00096 00097 // get the map file name 00098 char mapcharFName[200]; 00099 if (fgets(inLine, 200, fp) == NULL) LFATAL("fgets failed"); sscanf(inLine, "%s %s", comment, mapcharFName); 00100 LINFO("Map file: %s", mapcharFName); 00101 itsTopologicalMap->read(path + std::string(mapcharFName)); 00102 00103 // get the segment recognizer file name 00104 char segRecFName[200]; 00105 if (fgets(inLine, 200, fp) == NULL) LFATAL("fgets failed"); sscanf(inLine, "%s %s", comment, segRecFName); 00106 LINFO("Segment Recognizer file: %s", segRecFName); 00107 setupSegmentRecognizer(path+std::string(segRecFName)); 00108 00109 // get the landmarkDB folder name 00110 char landmarkDBFolderName[200]; 00111 if (fgets(inLine, 200, fp) == NULL) LFATAL("fgets failed"); sscanf(inLine, "%s %s", comment, 00112 landmarkDBFolderName); 00113 LINFO("landmarkDB Folder Name: %s", landmarkDBFolderName); 00114 00115 // skip the column headers 00116 if (fgets(inLine, 200, fp) == NULL) LFATAL("fgets failed"); 00117 00118 Timer timer(1000000); 00119 timer.reset(); 00120 00121 // populate the landmarks to the database 00122 while(fgets(inLine, 200, fp) != NULL) 00123 { 00124 int snum; char lName[200]; 00125 00126 // get the landmark file 00127 sscanf(inLine, "%d %s", &snum, lName); 00128 LDEBUG("[%d] landmark name: %s", snum, lName); 00129 00130 // add it to the proper segment 00131 rutz::shared_ptr<Landmark> lmk(new Landmark(std::string(lName))); 00132 std::string lmkName 00133 (sformat("%s%s/%s", path.c_str(), landmarkDBFolderName, lName)); 00134 //rutz::shared_ptr<Landmark> lmk(new Landmark(lmkName)); 00135 if (!lmk->loadFrom(lmkName)) LFATAL("invalid landmark file"); 00136 itsLandmarkDB->addLandmark(snum, lmk); 00137 LINFO("Added lmks[%3d][%3d]: %5d objects", snum, 00138 itsLandmarkDB->getNumSegLandmark(snum)-1, lmk->numObjects()); 00139 } 00140 fclose(fp); 00141 LINFO("time: %f", timer.get()/1000.0); 00142 timer.reset(); 00143 00144 // set sessions that has the number of frames 00145 int ldpos = fName.find_last_of('.'); 00146 std::string sessionFName = 00147 fName.substr(0, ldpos) + std::string("_sessions.txt"); 00148 LINFO("session name: %s", sessionFName.c_str()); 00149 itsLandmarkDB->setSession(sessionFName, false); 00150 00151 // report landmark database size 00152 std::vector<uint> segVoCount(nSegment); uint tLmkCount = 0; 00153 for(uint i = 0; i < nSegment; i++) 00154 { 00155 uint nLmk = itsLandmarkDB->getNumSegLandmark(i); 00156 LINFO("segment[%d] has: %d landmarks ", i, nLmk); 00157 segVoCount[i] = 0; 00158 tLmkCount += nLmk; 00159 for(uint j = 0; j < nLmk; j++) 00160 { 00161 uint nObj = itsLandmarkDB->getLandmark(i,j)->numObjects(); 00162 segVoCount[i] += nObj; 00163 LINFO(" lmk[%d][%d] has %d vo", i, j, nObj); 00164 } 00165 } 00166 00167 uint tVoCount = 0; 00168 for(uint i = 0; i < nSegment; i++) 00169 { 00170 LINFO("Lmks[%d]: %d lmk (%d VO)", 00171 i, itsLandmarkDB->getNumSegLandmark(i), segVoCount[i]); 00172 tVoCount += segVoCount[i]; 00173 } 00174 LINFO("%d landmarks, %d Visual Objects", tLmkCount, tVoCount); 00175 00176 LINFO("time: %f", timer.get()/1000.0); 00177 00178 return true; 00179 } 00180 00181 // ###################################################################### 00182 void Environment::setupSegmentRecognizer(std::string gistFName) 00183 { 00184 // get segment classifier parameters 00185 if( itsSegRecInfo.reset(gistFName.c_str())) 00186 { 00187 // instantiate a 3-layer feed-forward network 00188 // initialize with the provided parameters 00189 itsSegmentRecognizer->init3L 00190 (itsSegRecInfo.h1Name, itsSegRecInfo.h2Name, itsSegRecInfo.oName, 00191 itsSegRecInfo.redFeatSize, itsSegRecInfo.h1size, 00192 itsSegRecInfo.h2size, itsSegRecInfo.nOutput, 0.0, 0.0); 00193 00194 // setup the PCA eigenvector 00195 itsPcaIcaMatrix = setupPcaIcaMatrix 00196 (itsSegRecInfo.trainFolder+itsSegRecInfo.evecFname, 00197 itsSegRecInfo.oriFeatSize, itsSegRecInfo.redFeatSize); 00198 } 00199 else 00200 LINFO("Segment classifier file: %s not found", gistFName.c_str()); 00201 } 00202 00203 // ###################################################################### 00204 void Environment::resetNumSegment(uint nSegment) 00205 { 00206 itsLandmarkDB->resize(nSegment); 00207 itsSegmentHistogram->resize(nSegment); 00208 } 00209 00210 // ###################################################################### 00211 void Environment::setCurrentSegment(uint currSegNum) 00212 { 00213 ASSERT(currSegNum < uint(itsSegmentHistogram->getSize())); 00214 itsSegmentHistogram->clear(); 00215 itsSegmentHistogram->addValue(currSegNum, 1.0); 00216 itsCurrentSegment = currSegNum; 00217 } 00218 00219 // ###################################################################### 00220 bool Environment::save 00221 (std::string fName, std::string tfName, std::string envPrefix) 00222 { 00223 bool ts = save(itsTempLandmarkDB, tfName, envPrefix); 00224 bool s = save(itsLandmarkDB, fName, envPrefix); 00225 return (ts && s); 00226 } 00227 00228 // ###################################################################### 00229 bool Environment::save(std::string fName, std::string envPrefix) 00230 { 00231 return save(itsLandmarkDB, fName, envPrefix); 00232 } 00233 00234 // ###################################################################### 00235 bool Environment::save(rutz::shared_ptr<LandmarkDB> landmarkDB, 00236 std::string fName, std::string envPrefix) 00237 { 00238 // open an environment file 00239 FILE * envFile = fopen(fName.c_str(), "wt"); 00240 int nSegment = landmarkDB->getNumSegment(); 00241 00242 if (envFile!=NULL) 00243 { 00244 LINFO("saving environment to %s", fName.c_str()); 00245 00246 // get the directory name - include the "/" 00247 int lspos = fName.find_last_of('/'); 00248 int ldpos = fName.find_last_of('.'); 00249 std::string filepathstr = fName.substr(0, lspos+1); 00250 LINFO("path: %s", filepathstr.c_str()); 00251 00252 std::string lmfprefix = 00253 fName.substr(lspos+1, ldpos - lspos - 1); 00254 LINFO("prefix: %s", lmfprefix.c_str()); 00255 00256 std::string segnum(sformat("segment#: %d\n",nSegment)); 00257 fputs (segnum.c_str(), envFile); 00258 00259 std::string mapFileStr = 00260 envPrefix + std::string(".tmap"); 00261 std::string mapInfo(sformat("mapFile: %s\n", mapFileStr.c_str())); 00262 fputs (mapInfo.c_str(), envFile); 00263 00264 std::string gistFileStr = 00265 envPrefix + std::string("_GIST_train.txt"); 00266 std::string gistInfo(sformat("gistFile: %s\n", gistFileStr.c_str())); 00267 fputs (gistInfo.c_str(), envFile); 00268 00269 // create a landmarkDB folder 00270 std::string landmarkDBfolder = 00271 filepathstr + LANDMARK_DB_FOLDER_NAME; 00272 if (mkdir(landmarkDBfolder.c_str(), 0777) == -1 && errno != EEXIST) 00273 { 00274 LFATAL("Cannot create landmarkDB folder: %s", 00275 landmarkDBfolder.c_str()); 00276 } 00277 LINFO("creating landmarkDB folder: %s", landmarkDBfolder.c_str()); 00278 00279 std::string landmarkDBfolderInfo 00280 (sformat("LandmarkDBFolderName: %s\n", LANDMARK_DB_FOLDER_NAME)); 00281 fputs (landmarkDBfolderInfo.c_str(), envFile); 00282 00283 std::string header("Segment Landmark Name\n"); 00284 fputs (header.c_str(), envFile); 00285 00286 // re-create if we are adding from the previous one 00287 for(int i = 0; i < nSegment; i++) 00288 { 00289 for(uint j = 0; j < landmarkDB->getNumSegLandmark(i); j++) 00290 { 00291 // file name (no .lmk extension) 00292 std::string lmkName 00293 (sformat("%s_%03d_%03d", lmfprefix.c_str(), i, j)); 00294 LDEBUG("landmark name: %s", lmkName.c_str()); 00295 landmarkDB->getLandmark(i,j)->setName(lmkName); 00296 00297 // full name (path + file name + .lmk) 00298 std::string lmfName = 00299 landmarkDBfolder + std::string("/") + 00300 lmkName + std::string(".lmk"); 00301 LDEBUG("%s", lmfName.c_str()); 00302 00303 // save the info and write the name 00304 landmarkDB->getLandmark(i,j)->saveTo(lmfName); 00305 fputs (sformat("%-14d %s.lmk\n", i, lmkName.c_str()).c_str(), 00306 envFile); 00307 } 00308 } 00309 fclose (envFile); 00310 } 00311 else return false; 00312 00313 return true; 00314 } 00315 00316 // ###################################################################### 00317 Environment::~Environment() 00318 { 00319 } 00320 00321 // ###################################################################### 00322 rutz::shared_ptr<Histogram> Environment::classifySegNum(Image<double> cgist) 00323 { 00324 // reduce feature dimension (if available) 00325 Image<double> in; 00326 if(itsSegRecInfo.isPCA) in = matrixMult(itsPcaIcaMatrix, cgist); 00327 else in = cgist; 00328 00329 // analyze the gist features to recognize the segment 00330 Image<double> res = itsSegmentRecognizer->run3L(in); 00331 00332 itsSegmentHistogram->clear(); 00333 00334 float vMax = 0.0; int segMax = 0; 00335 for(int i = 0; i < itsSegmentHistogram->getSize(); i++) 00336 { 00337 float cVal = res[Point2D<int>(0,i)]; 00338 LDEBUG("seg[%3d]: %.4f",i, cVal); 00339 if(cVal > vMax){ vMax = cVal; segMax = i; } 00340 itsSegmentHistogram->addValue(i, cVal); 00341 } 00342 LDEBUG("predicted segment number %d: %f", segMax, vMax); 00343 itsCurrentSegment = segMax; 00344 00345 return itsSegmentHistogram; 00346 } 00347 00348 // ###################################################################### 00349 void Environment::startBuild() 00350 { 00351 // to store the currently build landmarkDB 00352 itsTempLandmarkDB.reset(new LandmarkDB(itsLandmarkDB->getNumSegment())); 00353 itsTempLandmarkDB->setWindow(itsWin); 00354 } 00355 00356 // ###################################################################### 00357 void Environment::build 00358 ( std::vector<rutz::shared_ptr<VisualObject> > &inputVO, 00359 std::vector<Point2D<int> > &objOffset, uint fNum, 00360 rutz::shared_ptr<VisualObject> scene) 00361 { 00362 // build the landmarkDB 00363 itsTempLandmarkDB->build 00364 (inputVO, objOffset, fNum, itsCurrentSegment, scene); 00365 } 00366 00367 // ###################################################################### 00368 void Environment::finishBuild 00369 (std::string envFName, std::string sessionPrefix, uint rframe) 00370 { 00371 itsTempLandmarkDB->finishBuild(rframe); 00372 //itsTempLandmarkDB->display(); 00373 00374 // combine with the actual landmark Database 00375 LINFO("Combine landmarkDB & tempLandmarkDB"); 00376 Raster::waitForKey(); 00377 itsLandmarkDB = combineLandmarkDBs(itsLandmarkDB, itsTempLandmarkDB); 00378 itsLandmarkDB->setWindow(itsWin); 00379 00380 // get the directory name - include the "/" 00381 int lspos = envFName.find_last_of('/'); 00382 int ldpos = envFName.find_last_of('.'); 00383 std::string path = envFName.substr(0, lspos+1); 00384 LINFO("path: %s", path.c_str()); 00385 00386 std::string envPrefix = envFName.substr(lspos+1, ldpos - lspos - 1); 00387 LINFO("prefix: %s", envPrefix.c_str()); 00388 00389 // append the session to the session list 00390 std::string sessionFName = path + envPrefix + sformat("_sessions.txt"); 00391 FILE *rFile = fopen(sessionFName.c_str(), "at"); 00392 if (rFile != NULL) 00393 { 00394 LINFO("appending session to %s", sessionFName.c_str()); 00395 std::string line = 00396 sformat("%-20s %-10d %-10d %-10d\n", 00397 sessionPrefix.c_str(), 0, rframe, itsCurrentSegment); 00398 fputs(line.c_str(), rFile); 00399 fclose (rFile); 00400 } 00401 else LINFO("can't create file: %s", sessionFName.c_str()); 00402 00403 Raster::waitForKey(); 00404 00405 // reset the session related information and sort the landmarks as well 00406 itsLandmarkDB->setSession(sessionFName, true); 00407 //itsLandmarkDB->display(); 00408 } 00409 00410 // ###################################################################### 00411 rutz::shared_ptr<LandmarkDB> Environment::combineLandmarkDBs 00412 ( rutz::shared_ptr<LandmarkDB> lmks1, rutz::shared_ptr<LandmarkDB> lmks2) 00413 { 00414 // NOTE: we are NOT creating DEEP COPY of landmarks 00415 uint nSegment = lmks1->getNumSegment(); 00416 rutz::shared_ptr<LandmarkDB> resLmks(new LandmarkDB(nSegment)); 00417 00418 // go through all segments 00419 for(uint i= 0; i < nSegment; i++) 00420 { 00421 uint nlmk1 = lmks1->getNumSegLandmark(i); 00422 uint nlmk2 = lmks2->getNumSegLandmark(i); 00423 LINFO("segment %d: lmks1[]: %d lmks2[]: %d",i, nlmk1, nlmk2); 00424 00425 // if both lmks1 and lmks2 has no landmarks 00426 // it will go through without consequences 00427 00428 // if only lmks2 has no landmarks in this segment 00429 if(nlmk1 > 0 && nlmk2 == 0) 00430 { 00431 LINFO("Lmks2[%d] is empty; add all Lmks1 landmarks", i); 00432 00433 // just push in all the landmarks in lmks1 00434 for(uint j = 0; j < nlmk1; j++) 00435 { 00436 resLmks->addLandmark(i,lmks1->getLandmark(i,j)); 00437 } 00438 } 00439 // if only lmks1 has no landmarks in this segment 00440 else if(nlmk1 == 0 && nlmk2 > 0) 00441 { 00442 LINFO("Lmks1[%d] is empty; add all Lmks2 landmarks", i); 00443 00444 // just push in all the landmarks in lmks2 00445 for(uint j = 0; j < nlmk2; j++) 00446 { 00447 resLmks->addLandmark(i,lmks2->getLandmark(i,j)); 00448 } 00449 } 00450 // else we have some combining to do 00451 else 00452 { 00453 // match lmk2 with lmk1 00454 00455 // create a temporary storage for each landmark in lmks1 00456 // indicating whether they have been added in or not 00457 std::vector<bool> lmks1added(nlmk1); 00458 std::vector<bool> lmks1appended(nlmk1); 00459 std::vector<int> lmks1pos (nlmk1); 00460 for(uint j = 0; j < nlmk1; j++) 00461 { 00462 lmks1added[j] = false; 00463 lmks1appended[j] = false; 00464 lmks1pos [j] = -1; 00465 } 00466 00467 // for each of the landmarks in the lmks2 00468 for(uint j = 0; j < nlmk2; j++) 00469 { 00470 LINFO("checking lmks2[%d][%d]", i, j); 00471 00472 // for each of the landmark in lmks1 00473 std::vector<uint> mIndex; 00474 for(uint k = 0; k < nlmk1; k++) 00475 { 00476 if(!lmks1appended[k]) 00477 { 00478 // check for number of matches of objects in landmarks 00479 // relax the distance of the sal point to 15.0 pixels 00480 uint nMatch = 00481 lmks1->getLandmark(i,k)->numMatch 00482 (lmks2->getLandmark(i,j), 15.0F); 00483 uint nObj1 = lmks1->getLandmark(i,k)->numObjects(); 00484 uint nObj2 = lmks2->getLandmark(i,j)->numObjects(); 00485 float mPntg = float(nMatch)/nObj2; 00486 00487 // check if match goes pass any of the thresholds: 00488 // nmatches <= 5, pntg >= 50% 00489 // nmatches 5 < x <= 10 pntg >= 25% 00490 // nmatches > 10 00491 bool combine = false; 00492 if((nMatch > 1 && nMatch <= 5 && mPntg >= .50) || 00493 (nMatch > 5 && nMatch <= 10 && mPntg >= .25) || 00494 (nMatch > 10)) 00495 { 00496 combine = true; mIndex.push_back(k); 00497 LINFO("<%d> lmks1[%d][%d](%d)-lmks2[%d][%d](%d)=" 00498 " %d/%d = %f", combine, 00499 i, k, nObj1, i, j, nObj2, nMatch, nObj2, mPntg); 00500 //if(combine) Raster::waitForKey(); 00501 } 00502 } 00503 } 00504 00505 // if we don't have any matches for lmks2[j] 00506 if(mIndex.size() == 0) 00507 { 00508 LINFO("match not found - adding Lmks2[%d]", j); 00509 00510 // add it to resulting DB: Not DEEP copy 00511 resLmks->addLandmark(i, lmks2->getLandmark(i,j)); 00512 //Raster::waitForKey(); 00513 } 00514 else 00515 { 00516 // if > 1 lmks2[j] matches 00517 // then we have to append all the matches first 00518 for(uint k = 1; k < mIndex.size(); k++) 00519 { 00520 // if the landmark of lmks1 is not added yet 00521 if(!lmks1added[mIndex[0]]) 00522 { 00523 // create a blank one to add both entries 00524 rutz::shared_ptr<Landmark> resLmk(new Landmark()); 00525 std::string resLmkName 00526 (sformat("Comb1_%d-1_%d", mIndex[0], mIndex[k])); 00527 resLmk->setName(resLmkName); 00528 resLmk->setMatchWin 00529 (lmks1->getLandmark(i,mIndex[0])->getMatchWin()); 00530 resLmk->combine(lmks1->getLandmark(i,mIndex[0]), 00531 lmks1->getLandmark(i,mIndex[k])); 00532 00533 // add the combination to the result landmark DB 00534 resLmks->addLandmark(i, resLmk); 00535 00536 // note that lmks1[mIndex] is in the result lmks 00537 lmks1added[mIndex[0]] = true; 00538 lmks1pos [mIndex[0]] = 00539 resLmks->getNumSegLandmark(i) - 1; 00540 00541 LINFO("NEW COMBO Landmark: %s", resLmkName.c_str()); 00542 } 00543 else 00544 { 00545 // otherwise append it to the end of the combined lmk 00546 std::string resLmkName = 00547 resLmks->getLandmark(i,lmks1pos[mIndex[0]])-> 00548 getName()+std::string(sformat(",1_%d", mIndex[k])); 00549 resLmks->getLandmark(i,lmks1pos[mIndex[0]])-> 00550 setName(resLmkName); 00551 resLmks->getLandmark(i,lmks1pos[mIndex[0]])-> 00552 append(lmks1->getLandmark(i,mIndex[k])); 00553 00554 LINFO("APP COMBO Landmark: %s",resLmkName.c_str()); 00555 } 00556 00557 lmks1added[mIndex[k]] = true; 00558 lmks1pos [mIndex[k]] = resLmks->getNumSegLandmark(i)-1; 00559 lmks1appended[mIndex[k]] = true; 00560 LINFO("append: lmks1[%d & %d]", mIndex[0], mIndex[k]); 00561 } 00562 00563 // combining lmks2[j] and lmks1[mIndex[0]] 00564 LINFO("Combolmk:[lmks1[%d] - lmks2[%d]]", mIndex[0], j); 00565 if(!lmks1added[mIndex[0]]) 00566 { 00567 rutz::shared_ptr<Landmark> resLmk(new Landmark()); 00568 std::string resLmkName 00569 (sformat("Comb1_%d-2_%d", mIndex[0], j)); 00570 resLmk->setName(resLmkName); 00571 resLmk->setMatchWin(lmks1->getLandmark(i,mIndex[0])-> 00572 getMatchWin()); 00573 resLmk->combine 00574 (lmks1->getLandmark(i,mIndex[0]), 00575 lmks2->getLandmark(i,j)); 00576 00577 // add the combination to the result landmark DB 00578 resLmks->addLandmark(i, resLmk); 00579 00580 // note that lmks1[mIndex[0]] is in the result lmks 00581 lmks1added[mIndex[0]] = true; 00582 lmks1pos [mIndex[0]] = resLmks->getNumSegLandmark(i)-1; 00583 00584 LINFO("NEW COMB Landmark: %s", resLmkName.c_str()); 00585 } 00586 else 00587 { 00588 // otherwise append it to the end of the combined lmk 00589 std::string resLmkName = 00590 resLmks->getLandmark(i,lmks1pos[mIndex[0]])->getName() 00591 + std::string(sformat(",2_%d",j)); 00592 resLmks->getLandmark(i,lmks1pos[mIndex[0]])-> 00593 setName(resLmkName); 00594 resLmks->getLandmark(i,lmks1pos[mIndex[0]])-> 00595 append(lmks2->getLandmark(i,j)); 00596 00597 LINFO("APP COMBO Landmark: %s", resLmkName.c_str()); 00598 } 00599 //Raster::waitForKey(); 00600 } 00601 } 00602 00603 // add the rest of the landmarks in lmks1 to the resulting lmks 00604 for(uint k = 0; k < nlmk1; k++) 00605 { 00606 if(!lmks1added[k]) 00607 { 00608 LINFO("adding lmks1[%d][%d] to the reslmks", i, k); 00609 resLmks->addLandmark(i,lmks1->getLandmark(i,k)); 00610 } 00611 } 00612 } 00613 } 00614 00615 LINFO("done combining"); 00616 for(uint i= 0; i < nSegment; i++) 00617 { 00618 for(uint j = 0; j < resLmks->getNumSegLandmark(i); j++) 00619 { 00620 LINFO("res[%d][%d]: %s",i,j, 00621 resLmks->getLandmark(i,j)->getName().c_str()); 00622 } 00623 } 00624 00625 Raster::waitForKey(); 00626 return resLmks; 00627 } 00628 00629 // ###################################################################### 00630 /* So things look consistent in everyone's emacs... */ 00631 /* Local Variables: */ 00632 /* indent-tabs-mode: nil */ 00633 /* End: */