TestImages.C

Go to the documentation of this file.
00001 /*!@file Media/TestImages.C Test Images */
00002 
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: Lior Elazary <elazary@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Media/TestImages.C $
00035 // $Id: TestImages.C 12357 2009-12-21 19:49:24Z lior $
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" // for isDirectory()
00047 #include "Util/sformat.H"
00048 #include <dirent.h>
00049 #include <list>
00050 #include <algorithm>
00051 
00052 //init the objects def for the ALOI lib
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             // get the individual files
00208             itsSceneFilenames.clear();
00209             readDir(filePath.c_str());
00210 
00211             // if (shuffle)
00212             //  std::random_shuffle(itsSceneFilenames.begin(),
00213             //  itsSceneFilenames.end());
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         //only train on num of objects
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; //only 1000 objects are avilable
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; //dont overflow
00277         filename = sformat("%s/%i/%i_%s.png", itsImagesPath,
00278                            id, id,ALOI_LUM[lum]);
00279       } else if (col > -1) {
00280         col = col%itsMaxCol;  //dont overflow
00281         filename = sformat("%s/%i/%i_%s.png", itsImagesPath,
00282                            id, id,ALOI_COL[col]);
00283       } else if (rot > -1) {
00284         rot = rot%itsMaxRot; //dont overflow
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; //only 100 objects are avilable
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     // find the object dimention from the polygon:
00348 
00349     // tranform the outline (becuase of the crop)
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             // find the bounds for the crop
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         // getting object from the scene
00370         objData.img = Raster::ReadRGB(itsScenes[scene].filename);
00371         // check for out of bounds and fix
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         // LINFO("Cropping %ix%i, size: %ix%i\n",
00391         //     upperLeft.i, upperLeft.j,
00392         //     objData.dims.h(), objData.dims.w());
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       // find the object dimention from the polygon
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               // find the bounds for the crop
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           // check if point is within the polygon
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); //resize the image
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         // use the first point to place the object
00483         if (objData.polygon.size() > 0)
00484           {
00485             if (itsScenes[scene].filename.empty()) {
00486               // this is a generated background
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"); //change extention to xml
00504   Image<PixRGB<byte> > objImg =  Raster::ReadRGB(filename);
00505 
00506   // crop the object in the scene
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   // crop the object in the scene
00524   Point2D<int> upperLeft = objOutline[0];
00525   Point2D<int> lowerRight = objOutline[0];
00526   for(uint i=0; i<objOutline.size(); i++)
00527   {
00528     // find the bounds for the crop
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   // tranforme the outline (becuase of the crop)
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   //clear all pixels outsize the polygon
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)); //clear the pixel
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   //Get the xml file for the given scene
00693   std::string xmlFile = std::string(itsImagesPath);
00694   xmlFile.insert(xmlFile.rfind("/"), "/Annotations"); //set the Annotations dir
00695   xmlFile += "/" + itsSceneFilenames[sceneId];
00696   xmlFile.replace(xmlFile.size()-4, 4, ".xml"); //change extention to xml
00697 
00698   itsCurrentScene = Raster::ReadRGB(std::string(itsImagesPath) + '/' +
00699                                     itsSceneFilenames[sceneId]);
00700 
00701   //clear the objname and polygons
00702   itsObjNames.clear();
00703   itsObjPolygon.clear();
00704 
00705   //check if the file exists
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   /*Get the root element node */
00714   xmlNode *root_element = xmlDocGetRootElement(doc);
00715 
00716   //look for object annotations
00717   xmlNodePtr cur = root_element->xmlChildrenNode; //dont care about toop level
00718   while (cur != NULL) {
00719     if ((!xmlStrcmp(cur->name, (const xmlChar *)"object"))) {
00720 
00721       xmlNodePtr object = cur->xmlChildrenNode;
00722       while(object != NULL)  //read the attributes and polygons
00723       {
00724         //Name
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         //Polygon
00735         //Read the points
00736         if ((!xmlStrcmp(object->name, (const xmlChar *)"polygon"))) {
00737           xmlNodePtr poly = object->xmlChildrenNode;
00738 
00739           std::vector<Point2D<int> > points;
00740           while(poly != NULL)  //read the attributes and polygons
00741           {
00742             //Get a point
00743             if ((!xmlStrcmp(poly->name, (const xmlChar *)"pt"))) {
00744 
00745               //get Point x and Point y
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; //next
00765               }
00766               points.push_back(Point2D<int>(x,y));
00767             }
00768             poly = poly->next; //next point
00769           }
00770           itsObjPolygon.push_back(points);
00771         }
00772         object = object->next; //next object
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 // get only the right images
00789 Image<PixRGB<byte> > TestImages::getCscLabScene(uint sceneId)
00790 {
00791 #ifdef HAVE_LIBXML
00792   ASSERT(sceneId < itsSceneFilenames.size());
00793 
00794   xmlDocPtr doc;
00795 
00796   //Get the xml file for the given scene
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   //clear the objname and polygons
00805   itsObjNames.clear();
00806   itsObjPolygon.clear();
00807 
00808   /*Get the root element node */
00809   xmlNode *root_element = xmlDocGetRootElement(doc);
00810 
00811   //look for object annotations
00812   xmlNodePtr cur = root_element->xmlChildrenNode; //dont care about toop level
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)  //read the attributes and polygons
00822       {
00823         //Get right Polygon
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           //make a polygon
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; //next object
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"); //change extention to xml
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   //clear all pixels outsize the polygon
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; //no need to check other objects.
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   // Get the xml file for the given scene:
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   //Get the root dir
00970   LDEBUG("Reading %s", xmlFile.c_str());
00971 
00972   // check if the file exists:
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   /* Get the root element node */
00980   xmlNode *root_element = xmlDocGetRootElement(doc);
00981 
00982   // look for object annotations
00983   xmlNodePtr cur = root_element; //->xmlChildrenNode; //dont care about top level
00984 
00985   //Skip the top level if scenes is in the name
00986   if ((!xmlStrcmp(cur->name, (const xmlChar *)"scenes")))
00987     cur = root_element->xmlChildrenNode; //dont care about top level
00988 
00989   while (cur != NULL) {
00990     // check for dir paths
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     // check for include directives:
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     // get the objects from the scene:
01007     if ((!xmlStrcmp(cur->name, (const xmlChar *)"annotation"))) {
01008       // get the  scene data:
01009       xmlNodePtr scenePtr = cur->xmlChildrenNode;
01010 
01011       std::string sceneFilename, sceneFolder, sceneDescription, sceneType;
01012       Dims sceneDims;
01013       std::vector<ObjData> objects;
01014 
01015       // new scene:
01016       while(scenePtr != NULL) { // read the attributes and polygons
01017         getNodeMatchText(doc, scenePtr, "filename", sceneFilename);
01018         getNodeMatchText(doc, scenePtr, "folder", sceneFolder);
01019         getNodeMatchText(doc, scenePtr, "description", sceneDescription);
01020 
01021         // get the scene size:
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         // get the object details from the scene:
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) { // read the attributes and polygons
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             // Polygon: Read the points
01053             if ((!xmlStrcmp(objectPtr->name, (const xmlChar *)"polygon"))) {
01054               xmlNodePtr poly = objectPtr->xmlChildrenNode;
01055 
01056               while(poly != NULL) { // read the attributes and polygons
01057                 // Get a point
01058                 if ((!xmlStrcmp(poly->name, (const xmlChar *)"pt"))) {
01059                   // get Point x and Point y:
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; //next
01066                   }
01067                   objPolygon.push_back(Point2D<int>(atoi(xStr.c_str()),
01068                                                     atoi(yStr.c_str())));
01069                 }
01070                 poly = poly->next; //next point
01071               }
01072             }
01073 
01074             //Read the bounding box
01075             if ((!xmlStrcmp(objectPtr->name, (const xmlChar *)"bndbox"))) {
01076               xmlNodePtr bboxPtr = objectPtr->xmlChildrenNode;
01077               std::string xmin, xmax, ymin, ymax;
01078               while(bboxPtr != NULL) { // read the box size
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; //next point
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             // object mask file?
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; // will clamp to 255
01103               else objMask = timg;
01104             }
01105 
01106             // next object data:
01107             objectPtr = objectPtr->next;
01108           }
01109 
01110          // LINFO("Read object %s (id %s) in %s",objName.c_str(),
01111          //     objId.c_str(),sceneFilename.c_str());
01112 
01113           // assign the object data to array:
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             // Replace spaces in objname with _
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; //next scene data
01143       }
01144       SceneData sceneData;
01145 
01146       //Hack for PASCAL dataset since the folder points to VOC2009/JPEGImages
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   //draw an outline of the object in the scene
01200   int lineWidth = int(sceneImg.getWidth()*0.005);
01201 
01202   for (uint obj=0; obj<getNumObj(scene); obj++) //look at all the objects in the scene
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); //close the polygon
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 /* So things look consistent in everyone's emacs... */
01229 /* Local Variables: */
01230 /* indent-tabs-mode: nil */
01231 /* End: */
Generated on Sun May 8 08:41:01 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3