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 "Media/TestImages.H"
00039
00040 #include "GUI/DebugWin.H"
00041 #include "Image/CutPaste.H"
00042 #include "Image/DrawOps.H"
00043 #include "Image/ShapeOps.H"
00044 #include "Image/Transforms.H"
00045 #include "Raster/Raster.H"
00046 #include "Util/FileUtil.H"
00047 #include "Util/sformat.H"
00048 #include <dirent.h>
00049 #include <list>
00050 #include <algorithm>
00051
00052
00053 const char* TestImages::ALOI_LUM[] = {
00054 "i110", "i120", "i130", "i140", "i150", "i160", "i170", "i180",
00055 "i190", "i210", "i230", "i250"
00056 };
00057
00058 const char *TestImages::ALOI_COL[] = {
00059 "l1c1", "l1c2", "l1c3", "l2c1", "l2c2", "l2c3", "l3c1", "l3c2",
00060 "l3c3", "l4c1", "l4c2", "l4c3", "l5c1", "l5c2", "l5c3", "l6c1",
00061 "l6c2", "l6c3", "l7c1", "l7c2", "l7c3", "l8c1", "l8c2", "l8c3"
00062 };
00063
00064 const char *TestImages::ALOI_ROT[] = {
00065 "r0", "r5", "r10", "r15", "r20", "r25", "r30", "r35", "r40", "r45", "r50",
00066 "r55", "r60", "r65", "r70", "r75", "r80", "r85", "r90", "r95", "r100",
00067 "r105", "r110", "r115", "r120", "r125", "r130", "r135", "r140", "r145",
00068 "r150", "r155", "r160", "r165", "r170", "r175", "r180", "r185", "r190",
00069 "r195", "r200", "r205", "r210", "r215", "r220", "r225", "r230", "r235",
00070 "r240", "r245", "r250", "r255", "r260", "r265", "r270", "r275", "r280",
00071 "r285", "r290", "r295", "r300", "r305", "r310", "r315", "r320", "r325",
00072 "r330", "r335", "r340", "r345", "r350", "r355"
00073 };
00074
00075
00076 TestImages::TestImages(const char* imagesPath, LIBRARY lib,
00077 const int numTraining,
00078 const int numTesting,
00079 const int numObjects) :
00080 itsImagesPath(imagesPath), itsLibType(lib),
00081 itsObjPolygon(0,std::vector<Point2D<int> >(0)), itsObjNames(0),
00082 itsSceneFilenames(0), itsObjects(0),
00083 itsScenes(0),
00084 itsTrainScenes(0),
00085 itsTestScenes(0),
00086 itsNumTraining(numTraining),
00087 itsNumTesting(numTesting),
00088 itsNumObjects(numObjects)
00089 {
00090 switch (itsLibType) {
00091 case ALOI:
00092 itsMaxLum = sizeof(ALOI_LUM)/4;
00093 itsMaxCol = sizeof(ALOI_COL)/4;
00094 itsMaxRot = sizeof(ALOI_ROT)/4;
00095 break;
00096
00097 case CSAIL:
00098 break;
00099
00100 case COIL:
00101 break;
00102
00103 case MIT_LABELME:
00104 readDir(itsImagesPath);
00105 break;
00106
00107 case CSCLAB:
00108 itsSceneId = -1;
00109 readDir(itsImagesPath);
00110 break;
00111
00112 case CALTECH256:
00113 itsSceneId = -1;
00114 readCalTech256Dir(itsImagesPath, itsNumTraining, itsNumTesting);
00115 break;
00116
00117 case IMG_DIR:
00118 readDir(itsImagesPath);
00119 break;
00120
00121 case XMLFILE:
00122 readObjXML(itsImagesPath);
00123 break;
00124
00125 default:
00126 LERROR("Unknown lib type");
00127 }
00128 }
00129
00130
00131 TestImages::~TestImages()
00132 { }
00133
00134
00135 uint TestImages::getNumObj(uint scene)
00136 {
00137 switch (itsLibType) {
00138 case ALOI:
00139 break;
00140
00141 case CSAIL:
00142 break;
00143
00144 case COIL:
00145 break;
00146
00147 case MIT_LABELME:
00148 return itsObjNames.size();
00149 break;
00150
00151 case CSCLAB:
00152 return itsObjNames.size();
00153 break;
00154
00155 case IMG_DIR:
00156 return itsSceneFilenames.size();
00157 break;
00158
00159 case XMLFILE:
00160 ASSERT(scene < itsScenes.size());
00161 return itsScenes[scene].objects.size();
00162 break;
00163
00164 default:
00165 LERROR("Unknown lib type");
00166 }
00167
00168 return 0;
00169 }
00170
00171
00172 void TestImages::readDir(const char *path)
00173 {
00174 DIR *dp = opendir(path);
00175 if (dp != NULL) {
00176 dirent *dirp;
00177 while ((dirp = readdir(dp)) != NULL ) {
00178 if (dirp->d_name[0] != '.' &&
00179 isDirectory(dirp) == false)
00180 {
00181 std::string filePath = std::string(path) + '/' +
00182 std::string(dirp->d_name);
00183 if (Raster::fileExists(filePath,RASFMT_AUTO, true))
00184 itsSceneFilenames.push_back(filePath);
00185 }
00186 }
00187 LDEBUG("%"ZU" files in the directory\n", itsSceneFilenames.size());
00188 } else LFATAL("%s is not a directory", path);
00189 }
00190
00191
00192 void TestImages::readCalTech256Dir(const char *path, const int trainingSize,
00193 const int testingSize, bool shuffle)
00194 {
00195 DIR *dp = opendir(path);
00196 int i = 0;
00197 if (dp != NULL)
00198 {
00199 dirent *dirp;
00200 while ((dirp = readdir(dp)) != NULL ) {
00201 if (dirp->d_name[0] != '.' &&
00202 isDirectory(dirp) == true)
00203 {
00204 std::string filePath = std::string(path) + '/' +
00205 std::string(dirp->d_name);
00206
00207
00208 itsSceneFilenames.clear();
00209 readDir(filePath.c_str());
00210
00211
00212
00213
00214
00215 int training = trainingSize;
00216 int testing = testingSize;
00217 if (training == -1)
00218 training = itsSceneFilenames.size()/2;
00219
00220 int scene = 0;
00221
00222 for(; scene < training && scene < (int)itsSceneFilenames.size();
00223 scene++)
00224 {
00225 SceneData sceneData;
00226 sceneData.description = std::string(dirp->d_name);
00227 sceneData.filename = itsSceneFilenames[scene];
00228 sceneData.useType = TRAIN;
00229 itsTrainScenes.push_back(sceneData);
00230 }
00231
00232 if (testing == -1)
00233 testing = itsSceneFilenames.size()/2;
00234
00235 testing += scene;
00236
00237 for(; scene<testing && scene<(int)itsSceneFilenames.size(); scene++)
00238 {
00239 SceneData sceneData;
00240 sceneData.description = std::string(dirp->d_name);
00241 sceneData.filename = itsSceneFilenames[scene];
00242 sceneData.useType = TEST;
00243 itsTestScenes.push_back(sceneData);
00244 }
00245 }
00246
00247
00248 if (itsNumObjects != -1 && i++ > itsNumObjects)
00249 break;
00250 }
00251 LDEBUG("%"ZU" scenes in the directory\n", itsSceneFilenames.size());
00252 } else LFATAL("%s is not a directory", path);
00253 }
00254
00255
00256 Image<PixRGB<byte> > TestImages::getObject(int id, int lum, int col, int rot)
00257 {
00258 std::string filename;
00259
00260 switch (itsLibType) {
00261 case ALOI:
00262 {
00263 static int idNumber = 0;
00264 static int lumNumber = 0;
00265 static int colNumber = 0;
00266 static int rotNumber = 0;
00267
00268 if (id == -1) id = idNumber++;
00269 id = (id % 1000) + 1;
00270
00271 if (lum == -1) lum = lumNumber++;
00272 if (col == -1) col = colNumber++;
00273 if (rot == -1) rot = rotNumber++;
00274
00275 if (lum > -1) {
00276 lum = lum%itsMaxLum;
00277 filename = sformat("%s/%i/%i_%s.png", itsImagesPath,
00278 id, id,ALOI_LUM[lum]);
00279 } else if (col > -1) {
00280 col = col%itsMaxCol;
00281 filename = sformat("%s/%i/%i_%s.png", itsImagesPath,
00282 id, id,ALOI_COL[col]);
00283 } else if (rot > -1) {
00284 rot = rot%itsMaxRot;
00285 filename = sformat("%s/%i/%i_%s.png", itsImagesPath,
00286 id, id,ALOI_ROT[rot]);
00287 }
00288 }
00289 break;
00290
00291 case CSAIL:
00292 break;
00293
00294 case COIL:
00295 {
00296 static int idNumber = 0;
00297 static int rotNumber = 0;
00298
00299 if (id == -1) id = idNumber++;
00300 id = id % 100 + 1;
00301
00302 if (rot == -1) rot = rotNumber += 5;
00303 else rot *= 5;
00304
00305 rot = rot % 360;
00306
00307 filename = sformat("%s/obj%i__%i.png", itsImagesPath, id, rot);
00308 }
00309 break;
00310
00311 case CSCLAB:
00312 return getCscLabObj(id);
00313 break;
00314
00315 case IMG_DIR:
00316 {
00317 static int idNumber = 0;
00318
00319 if (id == -1) id = idNumber++;
00320 id = id % itsSceneFilenames.size();
00321
00322 filename = sformat("%s/%s", itsImagesPath, itsSceneFilenames[id].c_str());
00323 }
00324 break;
00325
00326 case MIT_LABELME:
00327 return getLabelMeObj(id);
00328 break;
00329
00330 default:
00331 LERROR("Unknown lib type");
00332 }
00333
00334 return Raster::ReadRGB(filename);
00335 }
00336
00337
00338
00339 TestImages::ObjData TestImages::getObjectData(uint scene, uint obj,
00340 bool getImage)
00341 {
00342 ASSERT(scene < itsScenes.size() && obj < itsScenes[scene].objects.size());
00343
00344 ObjData objData = itsScenes[scene].objects[obj];
00345
00346 if (getImage) {
00347
00348
00349
00350 std::vector<Point2D<int> > newObjOutline;
00351
00352 if (objData.polygon.size() > 0)
00353 {
00354 Point2D<int> upperLeft = objData.polygon[0];
00355 Point2D<int> lowerRight = objData.polygon[0];
00356 for(uint i=0; i<objData.polygon.size(); i++)
00357 {
00358
00359 if (objData.polygon[i].i < upperLeft.i)
00360 upperLeft.i = objData.polygon[i].i;
00361 if (objData.polygon[i].j < upperLeft.j)
00362 upperLeft.j = objData.polygon[i].j;
00363 if (objData.polygon[i].i > lowerRight.i)
00364 lowerRight.i = objData.polygon[i].i;
00365 if (objData.polygon[i].j > lowerRight.j)
00366 lowerRight.j = objData.polygon[i].j;
00367 }
00368
00369
00370 objData.img = Raster::ReadRGB(itsScenes[scene].filename);
00371
00372 if (upperLeft.i < 0) upperLeft.i = 0;
00373 if (upperLeft.j < 0) upperLeft.j = 0;
00374 if (lowerRight.i < 0) lowerRight.i = 0;
00375 if (lowerRight.j < 0) lowerRight.j = 0;
00376 if (lowerRight.i > objData.img.getWidth())
00377 lowerRight.i = objData.img.getWidth();
00378 if (lowerRight.j > objData.img.getHeight())
00379 lowerRight.j = objData.img.getHeight();
00380
00381 objData.dims = Dims(lowerRight.i-upperLeft.i-1,
00382 lowerRight.j-upperLeft.j-1);
00383
00384 for (uint i=0; i<objData.polygon.size(); i++)
00385 newObjOutline.push_back(Point2D<int>(objData.polygon[i].i -
00386 upperLeft.i,
00387 objData.polygon[i].j -
00388 upperLeft.j));
00389
00390
00391
00392
00393 objData.img = crop(objData.img, upperLeft, objData.dims);
00394 }
00395
00396 if (!objData.filename.empty())
00397 objData.img = Raster::ReadRGB(objData.filename);
00398 }
00399 return objData;
00400 }
00401
00402
00403 TestImages::SceneData TestImages::getSceneData(uint scene, USETYPE useType)
00404 {
00405 switch (useType) {
00406 case TRAIN:
00407 ASSERT(scene < itsTrainScenes.size());
00408 return itsTrainScenes[scene];
00409 break;
00410
00411 case TEST:
00412 ASSERT(scene < itsTestScenes.size());
00413 return itsTestScenes[scene];
00414 break;
00415
00416 default:
00417 ASSERT(scene < itsScenes.size());
00418 return itsScenes[scene];
00419 break;
00420 }
00421 }
00422
00423
00424 TestImages::ObjData TestImages::getObjFromPos(uint scene,
00425 const Point2D<int> &pt)
00426 {
00427 ASSERT(scene < itsScenes.size());
00428
00429 ObjData objData;
00430 for(uint obj=0; obj<itsScenes[scene].objects.size(); obj++)
00431 {
00432 objData = itsScenes[scene].objects[obj];
00433
00434
00435 if (objData.polygon.size() > 0)
00436 {
00437 Point2D<int> upperLeft = objData.polygon[0];
00438 Point2D<int> lowerRight = objData.polygon[0];
00439
00440 for(uint i=0; i<objData.polygon.size(); i++)
00441 {
00442
00443 if (objData.polygon[i].i < upperLeft.i)
00444 upperLeft.i = objData.polygon[i].i;
00445 if (objData.polygon[i].j < upperLeft.j)
00446 upperLeft.j = objData.polygon[i].j;
00447 if (objData.polygon[i].i > lowerRight.i)
00448 lowerRight.i = objData.polygon[i].i;
00449 if (objData.polygon[i].j > lowerRight.j)
00450 lowerRight.j = objData.polygon[i].j;
00451 }
00452
00453
00454 for (int y = upperLeft.j; y < lowerRight.j; y++)
00455 for (int x = upperLeft.i; x < lowerRight.i; x++)
00456 if(pnpoly(objData.polygon, pt)) return objData;
00457 return objData;
00458 }
00459 }
00460
00461 return objData;
00462 }
00463
00464
00465 Image<PixRGB<byte> > TestImages::generateScene(uint scene)
00466 {
00467 ASSERT(scene < itsScenes.size());
00468
00469 Image<PixRGB<byte> > sceneImg;
00470 if (itsScenes[scene].filename.empty())
00471 sceneImg = Image<PixRGB<byte> >(itsScenes[scene].dims, NO_INIT);
00472 else
00473 {
00474 sceneImg = Raster::ReadRGB(itsScenes[scene].filename);
00475 sceneImg = rescale(sceneImg, itsScenes[scene].dims);
00476 }
00477
00478 for(uint obj=0; obj<itsScenes[scene].objects.size(); obj++)
00479 {
00480 ObjData objData = getObjectData(scene,obj);
00481 if (objData.dims.w() > 0 && objData.dims.h() > 0)
00482
00483 if (objData.polygon.size() > 0)
00484 {
00485 if (itsScenes[scene].filename.empty()) {
00486
00487 inplacePaste(sceneImg, objData.img, objData.polygon[0]);
00488 } else
00489 pasteImage(sceneImg, objData.img, PixRGB<byte>(0,0,0),
00490 objData.polygon[0], 0.5F);
00491 }
00492 }
00493 return sceneImg;
00494 }
00495
00496
00497 Image<PixRGB<byte> > TestImages::getCscLabObj(int id)
00498 {
00499 std::vector<Point2D<int> > objOutline = getObjPolygon(id);
00500
00501 std::string filename = std::string(itsImagesPath) + "/images/" +
00502 itsSceneFilenames[itsSceneId];
00503 filename.replace(filename.size()-4, 4, "-R.png");
00504 Image<PixRGB<byte> > objImg = Raster::ReadRGB(filename);
00505
00506
00507 Point2D<int> upperLeft = objOutline[0];
00508 Dims size(objOutline[2].i-objOutline[0].i,
00509 objOutline[2].j-objOutline[0].j);
00510
00511 return(crop(objImg, upperLeft, size));
00512 }
00513
00514
00515 Image<PixRGB<byte> > TestImages::getLabelMeObj(int id)
00516 {
00517 std::vector<Point2D<int> > objOutline = getObjPolygon(id);
00518
00519 Image<PixRGB<byte> > objImg =
00520 Raster::ReadRGB(std::string(itsImagesPath) + '/' +
00521 itsSceneFilenames[itsSceneId]);
00522
00523
00524 Point2D<int> upperLeft = objOutline[0];
00525 Point2D<int> lowerRight = objOutline[0];
00526 for(uint i=0; i<objOutline.size(); i++)
00527 {
00528
00529 if (objOutline[i].i < upperLeft.i) upperLeft.i = objOutline[i].i;
00530 if (objOutline[i].j < upperLeft.j) upperLeft.j = objOutline[i].j;
00531
00532 if (objOutline[i].i > lowerRight.i) lowerRight.i = objOutline[i].i;
00533 if (objOutline[i].j > lowerRight.j) lowerRight.j = objOutline[i].j;
00534
00535 }
00536
00537
00538 std::vector<Point2D<int> > newObjOutline;
00539 for(uint i=0; i<objOutline.size(); i++)
00540 newObjOutline.push_back(Point2D<int>(objOutline[i].i - upperLeft.i,
00541 objOutline[i].j - upperLeft.j));
00542
00543 Dims size(lowerRight.i-upperLeft.i, lowerRight.j - upperLeft.j);
00544 objImg = crop(objImg, upperLeft, size);
00545
00546
00547 for(int y=0; y<objImg.getHeight(); y++)
00548 for(int x=0; x<objImg.getWidth(); x++)
00549 {
00550 if (!pnpoly(newObjOutline, Point2D<int>(x, y)))
00551 objImg.setVal(x,y,PixRGB<byte>(0,0,0));
00552 }
00553
00554 return(objImg);
00555 }
00556
00557
00558 uint TestImages::getMaxLum()
00559 {
00560 return itsMaxLum;
00561 }
00562
00563
00564 uint TestImages::getMaxCol()
00565 {
00566 return itsMaxCol;
00567 }
00568
00569
00570 uint TestImages::getMaxRot()
00571 {
00572 switch (itsLibType){
00573 case ALOI:
00574 return itsMaxRot;
00575 case CSAIL:
00576 break;
00577 case COIL:
00578 return 360/5;
00579 default:
00580 LERROR("Unknown lib type");
00581 }
00582 return 0;
00583 }
00584
00585
00586 uint TestImages::getNumScenes(USETYPE useType)
00587 {
00588 switch (itsLibType){
00589 case MIT_LABELME:
00590 return itsSceneFilenames.size();
00591 case CALTECH256:
00592 switch (useType)
00593 {
00594 case TRAIN:
00595 return itsTrainScenes.size();
00596 break;
00597 case TEST:
00598 return itsTestScenes.size();
00599 break;
00600 default:
00601 return itsScenes.size();
00602 break;
00603 }
00604 case XMLFILE:
00605 return itsScenes.size();
00606 default:
00607 LERROR("Unknown lib type");
00608 }
00609 return 0;
00610 }
00611
00612
00613 Image<PixRGB<byte> > TestImages::getScene(uint sceneId, USETYPE useType)
00614 {
00615 switch (itsLibType){
00616 case ALOI:
00617 break;
00618 case CSAIL:
00619 break;
00620 case COIL:
00621 break;
00622 case MIT_LABELME:
00623 return getLabelMeScene(sceneId);
00624 case CSCLAB:
00625 return getCscLabScene(sceneId);
00626 case XMLFILE:
00627 ASSERT(sceneId < itsScenes.size());
00628 if ((int)itsScenes[sceneId].type.find("Embed") != -1 ||
00629 (int)itsScenes[sceneId].type.find("Array") != -1)
00630 {
00631 LDEBUG("Generating scene from objects");
00632 return generateScene(sceneId);
00633 } else {
00634 return Raster::ReadRGB(itsScenes[sceneId].filename);
00635 }
00636 case CALTECH256:
00637 switch (useType)
00638 {
00639 case TRAIN:
00640 ASSERT(sceneId < itsTrainScenes.size());
00641 return Raster::ReadRGB(itsTrainScenes[sceneId].filename);
00642 break;
00643 case TEST:
00644 ASSERT(sceneId < itsTestScenes.size());
00645 return Raster::ReadRGB(itsTestScenes[sceneId].filename);
00646 break;
00647 default:
00648 ASSERT(sceneId < itsScenes.size());
00649 return Raster::ReadRGB(itsScenes[sceneId].filename);
00650 break;
00651 }
00652 default:
00653 LERROR("Unknown lib type");
00654 }
00655
00656 return Image<PixRGB<byte> >();
00657 }
00658
00659
00660 std::string TestImages::getSceneFilename(uint sceneId)
00661 {
00662 switch (itsLibType){
00663 case ALOI:
00664 break;
00665 case CSAIL:
00666 break;
00667 case COIL:
00668 break;
00669 case MIT_LABELME:
00670 return itsSceneFilenames[sceneId];
00671 case CSCLAB:
00672 return itsSceneFilenames[sceneId];
00673 break;
00674 case XMLFILE:
00675 return itsSceneFilenames[sceneId];
00676 break;
00677 default:
00678 LERROR("Unknown lib type");
00679 }
00680
00681 return std::string();
00682 }
00683
00684
00685 Image<PixRGB<byte> > TestImages::getLabelMeScene(uint sceneId)
00686 {
00687 #ifdef HAVE_LIBXML
00688 ASSERT(sceneId < itsSceneFilenames.size());
00689
00690 xmlDocPtr doc;
00691
00692
00693 std::string xmlFile = std::string(itsImagesPath);
00694 xmlFile.insert(xmlFile.rfind("/"), "/Annotations");
00695 xmlFile += "/" + itsSceneFilenames[sceneId];
00696 xmlFile.replace(xmlFile.size()-4, 4, ".xml");
00697
00698 itsCurrentScene = Raster::ReadRGB(std::string(itsImagesPath) + '/' +
00699 itsSceneFilenames[sceneId]);
00700
00701
00702 itsObjNames.clear();
00703 itsObjPolygon.clear();
00704
00705
00706 doc = xmlReadFile(xmlFile.c_str(), NULL, 0);
00707 if (doc == NULL)
00708 {
00709 LINFO("Failed to parse %s", xmlFile.c_str());
00710 return itsCurrentScene;
00711 }
00712
00713
00714 xmlNode *root_element = xmlDocGetRootElement(doc);
00715
00716
00717 xmlNodePtr cur = root_element->xmlChildrenNode;
00718 while (cur != NULL) {
00719 if ((!xmlStrcmp(cur->name, (const xmlChar *)"object"))) {
00720
00721 xmlNodePtr object = cur->xmlChildrenNode;
00722 while(object != NULL)
00723 {
00724
00725 if ((!xmlStrcmp(object->name, (const xmlChar *)"name"))) {
00726 xmlChar* name = xmlNodeListGetString(doc, object->xmlChildrenNode, 1);
00727 if (name != NULL)
00728 {
00729 itsObjNames.push_back(std::string((const char*)name));
00730 xmlFree(name);
00731 }
00732 }
00733
00734
00735
00736 if ((!xmlStrcmp(object->name, (const xmlChar *)"polygon"))) {
00737 xmlNodePtr poly = object->xmlChildrenNode;
00738
00739 std::vector<Point2D<int> > points;
00740 while(poly != NULL)
00741 {
00742
00743 if ((!xmlStrcmp(poly->name, (const xmlChar *)"pt"))) {
00744
00745
00746
00747 int x = -1, y = -1;
00748 xmlNodePtr point = poly->xmlChildrenNode;
00749 while (point != NULL)
00750 {
00751 if ((!xmlStrcmp(point->name, (const xmlChar *)"x"))) {
00752 xmlChar* xLoc =
00753 xmlNodeListGetString(doc, point->xmlChildrenNode, 1);
00754 x = atoi((const char*)xLoc);
00755 xmlFree(xLoc);
00756 }
00757
00758 if ((!xmlStrcmp(point->name, (const xmlChar *)"y"))) {
00759 xmlChar* yLoc =
00760 xmlNodeListGetString(doc, point->xmlChildrenNode, 1);
00761 y = atoi((const char*)yLoc);
00762 xmlFree(yLoc);
00763 }
00764 point = point->next;
00765 }
00766 points.push_back(Point2D<int>(x,y));
00767 }
00768 poly = poly->next;
00769 }
00770 itsObjPolygon.push_back(points);
00771 }
00772 object = object->next;
00773 }
00774 }
00775 cur = cur->next;
00776 }
00777 xmlFreeDoc(doc);
00778 xmlCleanupParser();
00779
00780 #else
00781 LFATAL("Need xmllib to parse scene files");
00782 #endif
00783
00784 return itsCurrentScene;
00785 }
00786
00787
00788
00789 Image<PixRGB<byte> > TestImages::getCscLabScene(uint sceneId)
00790 {
00791 #ifdef HAVE_LIBXML
00792 ASSERT(sceneId < itsSceneFilenames.size());
00793
00794 xmlDocPtr doc;
00795
00796
00797 std::string xmlFile = std::string(itsImagesPath) + "/" +
00798 itsSceneFilenames[sceneId];
00799
00800 doc = xmlReadFile(xmlFile.c_str(), NULL, 0);
00801 if (doc == NULL)
00802 LFATAL("Failed to parse %s", xmlFile.c_str());
00803
00804
00805 itsObjNames.clear();
00806 itsObjPolygon.clear();
00807
00808
00809 xmlNode *root_element = xmlDocGetRootElement(doc);
00810
00811
00812 xmlNodePtr cur = root_element->xmlChildrenNode;
00813 while (cur != NULL) {
00814 if ((!xmlStrcmp(cur->name, (const xmlChar *)"Object"))) {
00815
00816 xmlChar* name = xmlGetProp(cur, (const xmlChar*)"id");
00817 itsObjNames.push_back(std::string((const char*)name));
00818 xmlFree(name);
00819
00820 xmlNodePtr object = cur->xmlChildrenNode;
00821 while(object != NULL)
00822 {
00823
00824 if ((!xmlStrcmp(object->name, (const xmlChar *)"Box")) &&
00825 !xmlStrcmp(xmlGetProp(object, (const xmlChar*)"side"),
00826 (const xmlChar*)"right"))
00827 {
00828 int left, top, width, height;
00829 xmlChar* data;
00830
00831 data = xmlGetProp(object, (const xmlChar*)"left");
00832 left = atoi((const char*)data);
00833 xmlFree(data);
00834
00835 data = xmlGetProp(object, (const xmlChar*)"top");
00836 top = atoi((const char*)data);
00837 xmlFree(data);
00838
00839 data = xmlGetProp(object, (const xmlChar*)"width");
00840 width = atoi((const char*)data);
00841 xmlFree(data);
00842
00843 data = xmlGetProp(object, (const xmlChar*)"height");
00844 height = atoi((const char*)data);
00845 xmlFree(data);
00846
00847
00848 std::vector<Point2D<int> > points;
00849 points.push_back(Point2D<int>(left, top));
00850 points.push_back(Point2D<int>(left+width, top));
00851 points.push_back(Point2D<int>(left+width, top+height));
00852 points.push_back(Point2D<int>(left, top+height));
00853 itsObjPolygon.push_back(points);
00854 }
00855 object = object->next;
00856 }
00857 }
00858 cur = cur->next;
00859 }
00860 xmlFreeDoc(doc);
00861 xmlCleanupParser();
00862
00863 #else
00864 LFATAL("Need xmllib to parse scene files");
00865 #endif
00866
00867 itsSceneId = sceneId;
00868 std::string filename = std::string(itsImagesPath) + "/images/" +
00869 itsSceneFilenames[sceneId];
00870 filename.replace(filename.size()-4, 4, "-R.png");
00871 return Raster::ReadRGB(filename);
00872 }
00873
00874
00875 const char* TestImages::getObjName(uint id)
00876 {
00877 ASSERT(id < itsObjNames.size());
00878 return itsObjNames[id].c_str();
00879 }
00880
00881
00882 std::vector<Point2D<int> > TestImages::getObjPolygon(uint id)
00883 {
00884 ASSERT(id < itsObjPolygon.size());
00885 return itsObjPolygon[id];
00886 }
00887
00888
00889 Image<byte> TestImages::getObjMask(uint obj)
00890 {
00891 std::vector<Point2D<int> > objOutline = getObjPolygon(obj);
00892 Image<byte> objMask(itsCurrentScene.getDims(), ZEROS);
00893 drawFilledPolygon(objMask, objOutline, byte(255));
00894
00895 return objMask;
00896 }
00897
00898
00899 Image<byte> TestImages::getObjMask(uint scene, uint obj)
00900 {
00901 ASSERT(scene < itsScenes.size() && obj < itsScenes[scene].objects.size());
00902
00903 SceneData sceneData = itsScenes[scene];
00904 ObjData objData = itsScenes[scene].objects[obj];
00905 std::vector<Point2D<int> > objOutline = objData.polygon;
00906
00907 Image<byte> objMask(sceneData.dims, ZEROS);
00908 LDEBUG("Mask %ix%i\n", objMask.getWidth(), objMask.getHeight());
00909 drawFilledPolygon(objMask, objOutline, byte(255));
00910
00911 return objMask;
00912 }
00913
00914
00915 Image<byte> TestImages::getObjMask(uint scene, uint obj, const Dims& sceneDims)
00916 {
00917 ASSERT(scene < itsScenes.size() && obj < itsScenes[scene].objects.size());
00918
00919 ObjData objData = itsScenes[scene].objects[obj];
00920 std::vector<Point2D<int> > objOutline = objData.polygon;
00921
00922 Image<byte> objMask(sceneDims, ZEROS);
00923 LDEBUG("Mask %ix%i\n", objMask.getWidth(), objMask.getHeight());
00924 drawFilledPolygon(objMask, objOutline, byte(255));
00925
00926 return objMask;
00927 }
00928
00929
00930 Image<byte> TestImages::getAllObjMask()
00931 {
00932 Image<byte> objMask(2560, 1920, ZEROS);
00933
00934
00935 for (int y = 0; y < objMask.getHeight(); y++)
00936 for (int x = 0; x < objMask.getWidth(); x++)
00937 {
00938 for(uint obj = 0; obj < getNumObj(); obj++)
00939 {
00940 std::vector<Point2D<int> > objOutline = getObjPolygon(obj);
00941 if (pnpoly(objOutline, Point2D<int>(x, y)))
00942 {
00943 objMask.setVal(x, y, byte(255));
00944 break;
00945 }
00946 }
00947 }
00948
00949 return(objMask);
00950 }
00951
00952
00953 void TestImages::readObjXML(const char *filename)
00954 {
00955 #ifdef HAVE_LIBXML
00956 xmlDocPtr doc;
00957
00958
00959 std::string xmlFile;
00960
00961 if (itsCurrentPath.empty())
00962 {
00963 xmlFile = std::string(filename);
00964 itsCurrentPath = xmlFile.substr(0, xmlFile.rfind('/'));
00965 } else {
00966 xmlFile = itsCurrentPath + '/' + std::string(filename);
00967 }
00968
00969
00970 LDEBUG("Reading %s", xmlFile.c_str());
00971
00972
00973 doc = xmlReadFile(xmlFile.c_str(), NULL, 0);
00974 if (doc == NULL) {
00975 LINFO("Failed to parse %s", xmlFile.c_str());
00976 return;
00977 }
00978
00979
00980 xmlNode *root_element = xmlDocGetRootElement(doc);
00981
00982
00983 xmlNodePtr cur = root_element;
00984
00985
00986 if ((!xmlStrcmp(cur->name, (const xmlChar *)"scenes")))
00987 cur = root_element->xmlChildrenNode;
00988
00989 while (cur != NULL) {
00990
00991 if ((!xmlStrcmp(cur->name, (const xmlChar *)"dir"))) {
00992 xmlChar* incPath = xmlGetProp(cur, (const xmlChar*)"path");
00993 LDEBUG("Setting Path to %s", (const char *)incPath);
00994 itsCurrentPath = std::string((const char *)incPath);
00995 xmlFree(incPath);
00996 }
00997
00998
00999 if ((!xmlStrcmp(cur->name, (const xmlChar *)"include"))) {
01000 xmlChar* incFileName = xmlGetProp(cur, (const xmlChar*)"filename");
01001 LDEBUG("Including file %s", (const char *)incFileName);
01002 readObjXML((const char *)incFileName);
01003 xmlFree(incFileName);
01004 }
01005
01006
01007 if ((!xmlStrcmp(cur->name, (const xmlChar *)"annotation"))) {
01008
01009 xmlNodePtr scenePtr = cur->xmlChildrenNode;
01010
01011 std::string sceneFilename, sceneFolder, sceneDescription, sceneType;
01012 Dims sceneDims;
01013 std::vector<ObjData> objects;
01014
01015
01016 while(scenePtr != NULL) {
01017 getNodeMatchText(doc, scenePtr, "filename", sceneFilename);
01018 getNodeMatchText(doc, scenePtr, "folder", sceneFolder);
01019 getNodeMatchText(doc, scenePtr, "description", sceneDescription);
01020
01021
01022 if ((!xmlStrcmp(scenePtr->name, (const xmlChar *)"specs"))) {
01023 LDEBUG("Specs %s", sceneDescription.c_str());
01024 xmlChar* width = xmlGetProp(scenePtr, (const xmlChar*)"width");
01025 xmlChar* height = xmlGetProp(scenePtr, (const xmlChar*)"height");
01026 xmlChar* type = xmlGetProp(scenePtr, (const xmlChar*)"type");
01027 LDEBUG("Dims set %s %s", (char*)width, (char*)height);
01028 if (width != NULL && height != NULL)
01029 sceneDims = Dims(atoi((char *)width), atoi((char *)height));
01030 if (type != NULL)
01031 sceneType = std::string((const char *)type);
01032 xmlFree(width);
01033 xmlFree(height);
01034 xmlFree(type);
01035 }
01036
01037
01038 if ((!xmlStrcmp(scenePtr->name, (const xmlChar *)"object"))) {
01039 std::string objId, objName, objDescription, objFilename, objFolder;
01040 std::vector<Point2D<int> > objPolygon;
01041 Dims objDims(0,0); Image<byte> objMask;
01042
01043 xmlNodePtr objectPtr = scenePtr->xmlChildrenNode;
01044 while(objectPtr != NULL) {
01045 getNodeMatchText(doc, objectPtr, "id", objId);
01046 getNodeMatchText(doc, objectPtr, "description", objDescription);
01047 getNodeMatchText(doc, objectPtr, "name", objName);
01048 getNodeMatchText(doc, objectPtr, "filename", objFilename);
01049 getNodeMatchText(doc, objectPtr, "folder", objFolder);
01050
01051
01052
01053 if ((!xmlStrcmp(objectPtr->name, (const xmlChar *)"polygon"))) {
01054 xmlNodePtr poly = objectPtr->xmlChildrenNode;
01055
01056 while(poly != NULL) {
01057
01058 if ((!xmlStrcmp(poly->name, (const xmlChar *)"pt"))) {
01059
01060 std::string xStr,yStr;
01061 xmlNodePtr point = poly->xmlChildrenNode;
01062 while (point != NULL) {
01063 getNodeMatchText(doc, point, "x", xStr);
01064 getNodeMatchText(doc, point, "y", yStr);
01065 point = point->next;
01066 }
01067 objPolygon.push_back(Point2D<int>(atoi(xStr.c_str()),
01068 atoi(yStr.c_str())));
01069 }
01070 poly = poly->next;
01071 }
01072 }
01073
01074
01075 if ((!xmlStrcmp(objectPtr->name, (const xmlChar *)"bndbox"))) {
01076 xmlNodePtr bboxPtr = objectPtr->xmlChildrenNode;
01077 std::string xmin, xmax, ymin, ymax;
01078 while(bboxPtr != NULL) {
01079 getNodeMatchText(doc, bboxPtr, "xmin", xmin);
01080 getNodeMatchText(doc, bboxPtr, "xmax", xmax);
01081 getNodeMatchText(doc, bboxPtr, "ymin", ymin);
01082 getNodeMatchText(doc, bboxPtr, "ymax", ymax);
01083 bboxPtr = bboxPtr->next;
01084 }
01085 objPolygon.push_back(Point2D<int>(atoi(xmin.c_str()),
01086 atoi(ymin.c_str())));
01087 objPolygon.push_back(Point2D<int>(atoi(xmax.c_str()),
01088 atoi(ymin.c_str())));
01089 objPolygon.push_back(Point2D<int>(atoi(xmax.c_str()),
01090 atoi(ymax.c_str())));
01091 objPolygon.push_back(Point2D<int>(atoi(xmin.c_str()),
01092 atoi(ymax.c_str())));
01093 }
01094
01095
01096 std::string objmaskfile;
01097 getNodeMatchText(doc, objectPtr, "objectmask", objmaskfile);
01098 if (objmaskfile.empty() == false) {
01099 if (objFolder.empty() == false)
01100 objmaskfile = objFolder+"/"+objmaskfile;
01101 Image<byte> timg = Raster::ReadGray(objmaskfile);
01102 if (objMask.initialized()) objMask += timg;
01103 else objMask = timg;
01104 }
01105
01106
01107 objectPtr = objectPtr->next;
01108 }
01109
01110
01111
01112
01113
01114 if (objPolygon.size() < 3 && objMask.initialized() == false)
01115 LINFO("Error: insufficent points in the polygon (%s)", xmlFile.c_str());
01116 else {
01117 ObjData objData;
01118
01119
01120 if (!objFilename.empty()) {
01121 if (itsCurrentPath.empty())
01122 objData.filename = objFolder + '/' + objFilename;
01123 else
01124 objData.filename = itsCurrentPath + '/' + objFolder +
01125 '/' + objFilename;
01126 }
01127 objData.id = atoi(objId.c_str());
01128
01129
01130 for (std::string::iterator i = objName.begin();
01131 i != objName.end(); i++)
01132 if (std::isspace(*i)) *i = '_';
01133
01134 objData.name = objName;
01135 objData.description = objDescription;
01136 objData.dims = objDims;
01137 objData.polygon = objPolygon;
01138 objData.objmask = objMask;
01139 objects.push_back(objData);
01140 }
01141 }
01142 scenePtr = scenePtr->next;
01143 }
01144 SceneData sceneData;
01145
01146
01147 if (sceneFolder == "VOC2009")
01148 sceneFolder += "/JPEGImages";
01149
01150 if (!sceneFilename.empty()) {
01151 if (itsCurrentPath.empty())
01152 sceneData.filename = sceneFolder + '/' + sceneFilename;
01153 else
01154 sceneData.filename = itsCurrentPath + '/' + sceneFolder +
01155 '/' + sceneFilename;
01156 }
01157
01158 LDEBUG("Scene %s", sceneData.filename.c_str());
01159 sceneData.description = sceneDescription;
01160 sceneData.dims = sceneDims;
01161 sceneData.type = sceneType;
01162 sceneData.objects = objects;
01163
01164 itsScenes.push_back(sceneData);
01165 }
01166 cur = cur->next;
01167 }
01168
01169 xmlFreeDoc(doc);
01170 xmlCleanupParser();
01171
01172 #else
01173 LFATAL("Need xmllib to parse scene files");
01174 #endif
01175
01176 return;
01177
01178 }
01179
01180
01181 #ifdef HAVE_LIBXML
01182 void TestImages::getNodeMatchText(xmlDocPtr doc, xmlNodePtr nodePtr,
01183 const char* nodeName, std::string &result)
01184 {
01185 xmlChar *tmp = NULL;
01186 if (!xmlStrcmp(nodePtr->name, (const xmlChar *)nodeName))
01187 tmp = xmlNodeListGetString(doc, nodePtr->xmlChildrenNode, 1);
01188
01189 if (tmp != NULL) {
01190 result = std::string((const char*)tmp);
01191 xmlFree(tmp);
01192 }
01193 }
01194 #endif // HAVE_LIBXML
01195
01196
01197 int TestImages::labelScene(uint scene, Image<PixRGB<byte> > &sceneImg)
01198 {
01199
01200 int lineWidth = int(sceneImg.getWidth()*0.005);
01201
01202 for (uint obj=0; obj<getNumObj(scene); obj++)
01203 {
01204
01205 ObjData objData = getObjectData(scene, obj);
01206
01207 std::vector<Point2D<int> > objPoly = objData.polygon;
01208 Point2D<int> p1 = objPoly[0];
01209 Point2D<int> centerLoc = p1;
01210 for(uint i=1; i<objPoly.size(); i++)
01211 {
01212 drawLine(sceneImg, p1, objPoly[i], PixRGB<byte>(255, 0, 0), lineWidth);
01213 p1 = objPoly[i];
01214 centerLoc.i += p1.i; centerLoc.j += p1.j;
01215 }
01216 drawLine(sceneImg, p1, objPoly[0], PixRGB<byte>(255, 0, 0), lineWidth);
01217
01218 centerLoc.i /= objPoly.size();
01219 centerLoc.j /= objPoly.size();
01220 writeText(sceneImg, centerLoc, objData.description.c_str(), PixRGB<byte>(255), PixRGB<byte>(0));
01221 }
01222
01223 return 1;
01224
01225 }
01226
01227
01228
01229
01230
01231