SceneRec.C

Go to the documentation of this file.
00001 /*!@file RCBot/SceneRec.C  Recognize scenes                             */
00002 // //////////////////////////////////////////////////////////////////// //
00003 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00004 // University of Southern California (USC) and the iLab at USC.         //
00005 // See http://iLab.usc.edu for information about this project.          //
00006 // //////////////////////////////////////////////////////////////////// //
00007 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00008 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00009 // in Visual Environments, and Applications'' by Christof Koch and      //
00010 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00011 // pending; application number 09/912,225 filed July 23, 2001; see      //
00012 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00013 // //////////////////////////////////////////////////////////////////// //
00014 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00015 //                                                                      //
00016 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00017 // redistribute it and/or modify it under the terms of the GNU General  //
00018 // Public License as published by the Free Software Foundation; either  //
00019 // version 2 of the License, or (at your option) any later version.     //
00020 //                                                                      //
00021 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00022 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00023 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00024 // PURPOSE.  See the GNU General Public License for more details.       //
00025 //                                                                      //
00026 // You should have received a copy of the GNU General Public License    //
00027 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00028 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00029 // Boston, MA 02111-1307 USA.                                           //
00030 // //////////////////////////////////////////////////////////////////// //
00031 //
00032 // Primary maintainer for this file: Lior Elazary <elazary@usc.edu>
00033 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/RCBot/SceneRec.C $
00034 // $Id: SceneRec.C 14125 2010-10-12 06:29:08Z itti $
00035 //
00036 
00037 #include "RCBot/SceneRec.H"
00038 #include "Component/OptionManager.H"
00039 #include "Image/CutPaste.H"
00040 #include <cstdio> // for sprintf
00041 
00042 #define DEBUG
00043 #ifdef DEBUG
00044 
00045 #include "GUI/XWinManaged.H"
00046 #include "Image/DrawOps.H"
00047 XWinManaged xwin(Dims(320,240), -1, -1, "SceneRec");
00048 
00049 #endif
00050 
00051 // ######################################################################
00052 // The working Thread
00053 void *SceneRecWorkTh(void *c)
00054 {
00055   SceneRec *d = (SceneRec*)c;
00056   d->computeLocation();
00057   return NULL;
00058 }
00059 
00060 // ######################################################################
00061 SceneRec::SceneRec(OptionManager& mgr, const std::string& descrName,
00062                    const std::string& tagName):
00063   ModelComponent(mgr, descrName, tagName)
00064 { }
00065 
00066 // ######################################################################
00067 void SceneRec::start1()
00068 {
00069   pthread_mutex_init(&jobLock, NULL);
00070   pthread_mutex_init(&locLock, NULL);
00071   pthread_mutex_init(&vdbLock, NULL);
00072   pthread_cond_init(&jobCond, NULL);
00073 
00074   currentLeg = 0;
00075   jobDone = true;
00076 
00077   currentLegVdb = NULL;
00078   nextLegVdb = NULL;
00079   loadVisualDB(currentLeg);
00080 
00081   // start the working thread
00082   worker = new pthread_t[1];
00083   pthread_create(&worker[0], NULL, SceneRecWorkTh, (void *)this);
00084   usleep(100000);
00085 }
00086 
00087 // ######################################################################
00088 void SceneRec::stop2()
00089 {
00090   delete [] worker;
00091 }
00092 
00093 // ######################################################################
00094 SceneRec::~SceneRec()
00095 {  }
00096 
00097 // ######################################################################
00098 void SceneRec::newInput(const Image< PixRGB<byte> > img)
00099 {
00100   pthread_mutex_lock(&jobLock);
00101   workImg = img;
00102   jobDone = false;
00103   pthread_mutex_unlock(&jobLock);
00104 
00105   // let the thread know we are ready for processing
00106   pthread_cond_broadcast(&jobCond);
00107 }
00108 
00109 // ######################################################################
00110 bool SceneRec::outputReady()
00111 {
00112   bool ret = false;
00113 
00114   pthread_mutex_lock(&jobLock);
00115   if (jobDone) ret = true;
00116   pthread_mutex_unlock(&jobLock);
00117 
00118   return ret;
00119 }
00120 
00121 // ######################################################################
00122 short SceneRec::getLandmarkLoc(Point2D<int> &loc)
00123 {
00124   pthread_mutex_lock(&locLock);
00125   loc = landmarkLoc;
00126   pthread_mutex_unlock(&locLock);
00127 
00128   return currentLeg;
00129 }
00130 
00131 // ######################################################################
00132 void SceneRec::trainFeature(Image<PixRGB<byte> > &img, Point2D<int> loc,
00133                             Dims window, short leg)
00134 {
00135   int width = img.getWidth();
00136   int height = img.getHeight();
00137   winsize = window;
00138 
00139   try {
00140     LDEBUG("Training loc (%i,%i) Win(%i,%i) leg=%i currentLeg=%i",
00141            loc.i, loc.j, window.w(), window.h(), leg, currentLeg);
00142 
00143     // if we are on a different leg, the load the correct vdb
00144     if (currentLeg != leg){
00145       pthread_mutex_lock(&vdbLock);
00146       loadVisualDB(leg);
00147       pthread_mutex_unlock(&vdbLock);
00148     }
00149 
00150     char name[255]; char fileName[255];
00151     sprintf(name, "Loc%i_%i", objNum, currentLeg);
00152     sprintf(fileName, "Loc%i_%i.png", objNum, currentLeg);
00153 
00154     // the location is at the center, move it to the top left
00155     Point2D<int> topLeft(loc.i-((window.w()-1)/2), loc.j-((window.h()-1)/2));
00156 
00157     // fix the window so that it does not go outside the image
00158     if (topLeft.i < 0 ) topLeft.i = 0;
00159     if (topLeft.i > width - window.w()) topLeft.i = width - window.w();
00160 
00161     if (topLeft.j < 0 ) topLeft.j = 0;
00162     if (topLeft.j > height - window.h()) topLeft.j = height - window.h();
00163 
00164     Image<PixRGB<byte> > templLoc = crop(img,topLeft, window);
00165     rutz::shared_ptr<VisualObject> voTempl(new VisualObject(name,fileName, templLoc));
00166 
00167     LINFO("Saving %s to %s", name, fileName);
00168     pthread_mutex_lock(&vdbLock);
00169     currentLegVdb->addObject(voTempl);
00170     sprintf(fileName, "path%i.vdb", currentLeg);
00171     currentLegVdb->saveTo(fileName);
00172     pthread_mutex_unlock(&vdbLock);
00173     objNum++;
00174 
00175   } catch(...) {
00176     LDEBUG("Error in training");
00177     pthread_mutex_unlock(&vdbLock);
00178   }
00179 }
00180 
00181 // ######################################################################
00182 void SceneRec::computeLocation()
00183 {
00184   while (true){
00185     // wait until a job comes
00186     pthread_mutex_lock(&jobLock);
00187     pthread_cond_wait(&jobCond, &jobLock);
00188 
00189     // got a job
00190     Image<PixRGB<byte> > img = workImg;
00191     pthread_mutex_unlock(&jobLock);
00192 
00193     LDEBUG("Got a location to recognize, currentLeg = %i", currentLeg);
00194     pthread_mutex_lock(&locLock);
00195     landmarkLoc.i = -1; landmarkLoc.j = -1;
00196     pthread_mutex_unlock(&locLock);
00197 
00198     try {
00199       std::vector< rutz::shared_ptr<VisualObjectMatch> > matches;
00200       unsigned int nmatch = 0;
00201       if (img.initialized()){
00202         rutz::shared_ptr<VisualObject> voimg(new VisualObject("PIC", "PIC", img));
00203 
00204         float scale; Point2D<int> loc; bool landmarkFound = false;
00205 
00206         // search the next location, if we do not look at the current one
00207         if (nextLegVdb->numObjects()) { // do we have any objects
00208           pthread_mutex_lock(&vdbLock);
00209           nmatch = nextLegVdb->getObjectMatches(voimg, matches,
00210                                                 VOMA_KDTREEBBF);
00211           pthread_mutex_unlock(&vdbLock);
00212 
00213           getLandmarkInfo(scale, loc, nmatch, matches, img);
00214           LINFO("Next DB: Found landmark at (%i,%i), scale = %f", loc.i, loc.j, scale);
00215           if (nmatch > 0 && scale > 0.75) { //We found the next location
00216             loadVisualDB(currentLeg+1); //load the next vdbs
00217             landmarkFound = true;
00218           }
00219         }
00220 
00221         // the next Landmark is not found, search the current db
00222         if (!landmarkFound){
00223           if (currentLegVdb->numObjects()) { // do we have any objects
00224             pthread_mutex_lock(&vdbLock);
00225             nmatch = currentLegVdb->getObjectMatches(voimg, matches,
00226                                                      VOMA_KDTREEBBF);
00227             pthread_mutex_unlock(&vdbLock);
00228 
00229             getLandmarkInfo(scale, loc, nmatch, matches, img);
00230             LINFO("Curr DB: Found landmark at (%i,%i), scale = %f", loc.i, loc.j, scale);
00231             if (nmatch > 0){ //match at any scale
00232               landmarkFound = true;
00233             }
00234           }
00235         }
00236 
00237         if (landmarkFound) { // if we found the landmark then store the position
00238           pthread_mutex_lock(&locLock);
00239           landmarkLoc = loc;
00240           pthread_mutex_unlock(&locLock);
00241         }
00242       }
00243 
00244     } catch (...){
00245       LDEBUG("Got an error " );
00246       pthread_mutex_unlock(&vdbLock);
00247       pthread_mutex_unlock(&locLock);
00248     }
00249 
00250     // sleep(1);
00251     pthread_mutex_lock(&jobLock);
00252     jobDone = true;
00253     pthread_mutex_unlock(&jobLock);
00254   }
00255 }
00256 
00257 // ######################################################################
00258 void SceneRec::getLandmarkInfo(float &scale, Point2D<int> &loc,
00259                                unsigned int nmatch,
00260                                std::vector< rutz::shared_ptr<VisualObjectMatch> > &matches,
00261                                Image<PixRGB<byte> > &img)
00262 {
00263   LDEBUG("Found %i currentLeg %i\n", nmatch, currentLeg);
00264   if (nmatch > 0 )
00265   {
00266     // look at the first match
00267     for(unsigned int i = 0; i < 1; i++)
00268     {
00269       rutz::shared_ptr<VisualObjectMatch> vom = matches[i];
00270       rutz::shared_ptr<VisualObject> obj = vom->getVoTest();
00271 
00272       // get the number of the object
00273       const char *nameNum = obj->getName().c_str();
00274       int objNum = atoi(nameNum+3); // skip over Loc
00275 
00276       LDEBUG("### Object match with '%s' score=%f Number %i",
00277              obj->getName().c_str(), vom->getScore(), objNum);
00278       Point2D<int> tl, tr, br, bl;
00279       vom->getTransfTestOutline(tl, tr, br, bl);
00280 
00281       // find the center:
00282       Point2D<int> landmarkCenter( tl.i + ((br.i - tl.i)/2),
00283                               tl.j + ((br.j - tl.j)/2));
00284       loc = landmarkCenter;
00285 
00286 #ifdef DEBUG
00287       drawLine(img, tl, tr, PixRGB<byte>(255, 0, 0));
00288       drawLine(img, tr, br, PixRGB<byte>(255, 0, 0));
00289       drawLine(img, br, bl, PixRGB<byte>(255, 0, 0));
00290       drawLine(img, bl, tl, PixRGB<byte>(255, 0, 0));
00291       drawDisk(img, Point2D<int>(landmarkCenter),
00292                4, PixRGB<byte>(255, 0, 0));
00293       xwin.drawImage(img);
00294 #endif
00295 
00296       float size =  (br.i - tl.i)*(br.j - tl.j);
00297       LINFO("Size: %i %i %f", br.i - tl.i, br.j - tl.j, size);
00298 
00299       scale = size / (winsize.w()*winsize.h());
00300     }
00301   } else {
00302     scale = 0;
00303     loc.i = -1; loc.j = -1;
00304   }
00305 }
00306 
00307 // ######################################################################
00308 void SceneRec::loadVisualDB(short leg)
00309 {
00310   char fileName[255];
00311 
00312   //save the old dbs
00313   if (currentLegVdb) {
00314     if (currentLegVdb->numObjects()){
00315       sprintf(fileName, "path%i.vdb", currentLeg);
00316       currentLegVdb->saveTo(fileName);
00317     }
00318     delete currentLegVdb;
00319   }
00320 
00321   if (nextLegVdb){
00322     if (nextLegVdb->numObjects()){
00323       sprintf(fileName, "path%i.vdb", currentLeg+1);
00324       nextLegVdb->saveTo(fileName);
00325     }
00326     delete nextLegVdb;
00327   }
00328 
00329   // load dbs
00330   sprintf(fileName, "path%i.vdb", leg);
00331   currentLegVdb = new VisualObjectDB();
00332   currentLegVdb->loadFrom(fileName);
00333   objNum = currentLegVdb->numObjects();
00334   LINFO("Load current=%i(%i) next=%i", leg, objNum, leg+1);
00335 
00336   sprintf(fileName, "path%i.vdb", leg+1);
00337   nextLegVdb = new VisualObjectDB();
00338   nextLegVdb->loadFrom(fileName);
00339 
00340   currentLeg = leg;
00341 }
00342 
00343 // ######################################################################
00344 /* So things look consistent in everyone's emacs... */
00345 /* Local Variables: */
00346 /* indent-tabs-mode: nil */
00347 /* End: */
Generated on Sun May 8 08:05:35 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3