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/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
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
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
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
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
00095 resetNumSegment(nSegment);
00096
00097
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
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
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
00116 if (fgets(inLine, 200, fp) == NULL) LFATAL("fgets failed");
00117
00118 Timer timer(1000000);
00119 timer.reset();
00120
00121
00122 while(fgets(inLine, 200, fp) != NULL)
00123 {
00124 int snum; char lName[200];
00125
00126
00127 sscanf(inLine, "%d %s", &snum, lName);
00128 LDEBUG("[%d] landmark name: %s", snum, lName);
00129
00130
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
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
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
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
00185 if( itsSegRecInfo.reset(gistFName.c_str()))
00186 {
00187
00188
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
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
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
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
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
00287 for(int i = 0; i < nSegment; i++)
00288 {
00289 for(uint j = 0; j < landmarkDB->getNumSegLandmark(i); j++)
00290 {
00291
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
00298 std::string lmfName =
00299 landmarkDBfolder + std::string("/") +
00300 lmkName + std::string(".lmk");
00301 LDEBUG("%s", lmfName.c_str());
00302
00303
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
00325 Image<double> in;
00326 if(itsSegRecInfo.isPCA) in = matrixMult(itsPcaIcaMatrix, cgist);
00327 else in = cgist;
00328
00329
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
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
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
00373
00374
00375 LINFO("Combine landmarkDB & tempLandmarkDB");
00376 Raster::waitForKey();
00377 itsLandmarkDB = combineLandmarkDBs(itsLandmarkDB, itsTempLandmarkDB);
00378 itsLandmarkDB->setWindow(itsWin);
00379
00380
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
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
00406 itsLandmarkDB->setSession(sessionFName, true);
00407
00408 }
00409
00410
00411 rutz::shared_ptr<LandmarkDB> Environment::combineLandmarkDBs
00412 ( rutz::shared_ptr<LandmarkDB> lmks1, rutz::shared_ptr<LandmarkDB> lmks2)
00413 {
00414
00415 uint nSegment = lmks1->getNumSegment();
00416 rutz::shared_ptr<LandmarkDB> resLmks(new LandmarkDB(nSegment));
00417
00418
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
00426
00427
00428
00429 if(nlmk1 > 0 && nlmk2 == 0)
00430 {
00431 LINFO("Lmks2[%d] is empty; add all Lmks1 landmarks", i);
00432
00433
00434 for(uint j = 0; j < nlmk1; j++)
00435 {
00436 resLmks->addLandmark(i,lmks1->getLandmark(i,j));
00437 }
00438 }
00439
00440 else if(nlmk1 == 0 && nlmk2 > 0)
00441 {
00442 LINFO("Lmks1[%d] is empty; add all Lmks2 landmarks", i);
00443
00444
00445 for(uint j = 0; j < nlmk2; j++)
00446 {
00447 resLmks->addLandmark(i,lmks2->getLandmark(i,j));
00448 }
00449 }
00450
00451 else
00452 {
00453
00454
00455
00456
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
00468 for(uint j = 0; j < nlmk2; j++)
00469 {
00470 LINFO("checking lmks2[%d][%d]", i, j);
00471
00472
00473 std::vector<uint> mIndex;
00474 for(uint k = 0; k < nlmk1; k++)
00475 {
00476 if(!lmks1appended[k])
00477 {
00478
00479
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
00488
00489
00490
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
00501 }
00502 }
00503 }
00504
00505
00506 if(mIndex.size() == 0)
00507 {
00508 LINFO("match not found - adding Lmks2[%d]", j);
00509
00510
00511 resLmks->addLandmark(i, lmks2->getLandmark(i,j));
00512
00513 }
00514 else
00515 {
00516
00517
00518 for(uint k = 1; k < mIndex.size(); k++)
00519 {
00520
00521 if(!lmks1added[mIndex[0]])
00522 {
00523
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
00534 resLmks->addLandmark(i, resLmk);
00535
00536
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
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
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
00578 resLmks->addLandmark(i, resLmk);
00579
00580
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
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
00600 }
00601 }
00602
00603
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
00631
00632
00633