GHough.C

00001 /*!@file SceneUnderstanding/GHough.C  Generalized Hough */
00002 
00003 
00004 
00005 // //////////////////////////////////////////////////////////////////// //
00006 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00007 // by the University of Southern California (USC) and the iLab at USC.  //
00008 // See http://iLab.usc.edu for information about this project.          //
00009 // //////////////////////////////////////////////////////////////////// //
00010 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00011 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00012 // in Visual Environments, and Applications'' by Christof Koch and      //
00013 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00014 // pending; application number 09/912,225 filed July 23, 2001; see      //
00015 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00016 // //////////////////////////////////////////////////////////////////// //
00017 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00018 //                                                                      //
00019 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00020 // redistribute it and/or modify it under the terms of the GNU General  //
00021 // Public License as published by the Free Software Foundation; either  //
00022 // version 2 of the License, or (at your option) any later version.     //
00023 //                                                                      //
00024 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00025 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00026 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00027 // PURPOSE.  See the GNU General Public License for more details.       //
00028 //                                                                      //
00029 // You should have received a copy of the GNU General Public License    //
00030 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00031 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00032 // Boston, MA 02111-1307 USA.                                           //
00033 // //////////////////////////////////////////////////////////////////// //
00034 //
00035 // Primary maintainer for this file: Lior Elazary <elazary@usc.edu>
00036 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/FeatureMatching/GHough.C $
00037 // $Id: GHough.C 13815 2010-08-22 17:58:48Z lior $
00038 //
00039 
00040 #ifndef GHough_C_DEFINED
00041 #define GHough_C_DEFINED
00042 
00043 #include "FeatureMatching/GHough.H"
00044 #include "Image/DrawOps.H"
00045 #include "GUI/DebugWin.H"
00046 #include "Image/FilterOps.H"
00047 #include <fcntl.h>
00048 #include <cstdio>
00049 
00050 
00051 namespace
00052 {
00053   pthread_mutex_t itsAccLock;
00054 
00055   class GHTJob : public JobWithSemaphore
00056   {
00057   public:
00058 
00059     GHTJob(GHough* ghough, int id, const GHough::RTable& rTable, const std::vector<GHough::Feature>& features,
00060         std::vector<GHough::Acc>& acc) :
00061       itsGHough(ghough),
00062       itsId(id),
00063       itsRTable(rTable),
00064       itsFeatures(features),
00065       itsAcc(acc)
00066     {}
00067 
00068     virtual ~GHTJob() {}
00069 
00070     virtual void run()
00071     {
00072       float maxVotes = 0;
00073       std::vector<GHough::Acc> acc = itsGHough->getVotes(itsId, itsRTable, itsFeatures, maxVotes);
00074 
00075       pthread_mutex_lock(&itsAccLock);
00076       for(uint j=0; j<acc.size(); j++)
00077         itsAcc.push_back(acc[j]);
00078       pthread_mutex_unlock(&itsAccLock);
00079 
00080       this->markFinished();
00081     }
00082 
00083     virtual const char* jobType() const { return "GHTJob"; }
00084 
00085     GHough* itsGHough;
00086     int itsId;
00087     const GHough::RTable& itsRTable;
00088     const std::vector<GHough::Feature>& itsFeatures;
00089     std::vector<GHough::Acc>& itsAcc;
00090   };
00091 }
00092 
00093 // ######################################################################
00094 GHough::GHough()  :
00095   itsNumEntries(20)
00096 {
00097 
00098   //itsThreadServer.reset(new WorkThreadServer("GHough", 10));
00099   
00100   if (0 != pthread_mutex_init(&itsAccLock, NULL))
00101     LFATAL("pthread_mutex_init() failed");
00102 
00103   itsSOFM = new SOFM("Corners", 360, 25,25 );
00104   
00105 }
00106 
00107 // ######################################################################
00108 GHough::~GHough()
00109 {
00110 
00111   if (0 != pthread_mutex_destroy(&itsAccLock))
00112     LERROR("pthread_mutex_destroy() failed");
00113 }
00114 
00115 Point2D<float> GHough::addModel(int& id, const Image<byte>& img, const Image<float>& ang,
00116     Point3D<float> pos, Point3D<float> rot)
00117 {
00118 
00119   Model model;
00120   model.id = 0;
00121   model.pos = pos;
00122   model.rot = rot;
00123 
00124 
00125   Point2D<float> imgLoc;
00126   RTable rTable = createRTable(img, ang, model.imgPos, model.numFeatures, imgLoc);
00127   if (rTable.entries.size() > 0)
00128   {
00129     model.rTables.push_back(rTable);
00130     itsModels.push_back(model);
00131     id = itsModels.size()-1;
00132   }
00133 
00134   return imgLoc;
00135 
00136 }
00137 
00138 Point2D<float> GHough::addModel(int& id, int type, const std::vector<GHough::Feature>& features, 
00139     Point3D<float> pos, Point3D<float> rot)
00140 {
00141 
00142   Model model;
00143   model.id = 0;
00144   model.pos = pos;
00145   model.rot = rot;
00146   model.type = type;
00147 
00148   Point2D<float> imgLoc;
00149   model.numFeatures = features.size();
00150   RTable rTable = createRTable(features, model.imgPos, imgLoc);
00151   if (rTable.featureEntries.size() > 0)
00152   {
00153     model.rTables.push_back(rTable);
00154     itsModels.push_back(model);
00155     id = itsModels.size()-1;
00156   }
00157 
00158   return imgLoc;
00159 
00160 }
00161 
00162 void GHough::addModel(int id, const Image<float>& img)
00163 {
00164 
00165   Image<float> mag, ori;
00166   gradientSobel(img, mag, ori);
00167 
00168   ////Non maximal suppersion
00169   mag = nonMaxSuppr(mag, ori);
00170   SHOWIMG(mag);
00171 
00172   //createInvRTable(mag, ori);
00173 
00174   Model model;
00175   model.id = id;
00176 
00177   //RTable rTable = createRTable(mag, ori, model.imgPos, model.numFeatures);
00178   //if (rTable.entries.size() > 0)
00179   //{
00180   //  model.rTables.push_back(rTable);
00181   //  itsModels.push_back(model);
00182   //}
00183 
00184 }
00185 
00186 Point2D<int> GHough::addModel(int id, const std::vector<Point2D<int> >& polygon)
00187 {
00188 
00189   Point2D<int> center;
00190  
00191   Image<float> mag(320, 240, ZEROS);
00192   Image<float> ori(320, 240, ZEROS);
00193 
00194   for(uint i=0; i<polygon.size(); i++)
00195   {
00196     Point2D<int> p1 = polygon[i];
00197     Point2D<int> p2 = polygon[(i+1)%polygon.size()];
00198 
00199     float ang = atan2(p1.j-p2.j, p2.i - p1.i);
00200     drawLine(mag, p1, p2, 255.0F);
00201     drawLine(ori, p1, p2, ang);
00202   }
00203 
00204   Model model;
00205   model.id = id;
00206 
00207   RTable rTable = createRTable(mag, ori, center, model.numFeatures);
00208   if (rTable.entries.size() > 0)
00209   {
00210     model.rTables.push_back(rTable);
00211     itsModels.push_back(model);
00212   }
00213 
00214   return center;
00215 
00216 }
00217 
00218 
00219 std::vector<GHough::Acc> GHough::getVotes(const Image<float>& img)
00220 {
00221 
00222   //std::vector<Acc> acc;
00223 
00224   Image<float> mag, ori;
00225   gradientSobel(img, mag, ori);
00226 
00227   ////Non maximal suppersion
00228   mag = nonMaxSuppr(mag, ori);
00229 
00230   //Image<float> acci = getInvVotes(mag, ori);
00231   //Point2D<int> loc; float max;
00232   //findMax(acci, loc, max);
00233   ////drawCircle(acci, loc, 10, 1550.0F);
00234   //SHOWIMG(acci);
00235 
00236   std::vector<GHough::Acc> acc;
00237 
00238   for(uint i=0; i<itsModels.size(); i++)
00239   {
00240     for(uint j=0; j<itsModels[i].rTables.size(); j++)
00241     {
00242       std::vector<GHough::Acc> accScale =  getVotes(i, itsModels[i].rTables[j], mag, ori);
00243       for(uint j=0; j<accScale.size(); j++)
00244         acc.push_back(accScale[j]);
00245     }
00246   }
00247 
00248   //sort the acc
00249   std::sort(acc.begin(), acc.end(), AccCmp());
00250 
00251   drawCircle(mag, acc[0].pos, 3, 255.0F);
00252   SHOWIMG(mag);
00253 
00254   return acc;
00255 }
00256 
00257 std::vector<GHough::Acc> GHough::getVotes(const Image<float>& mag, const Image<float>& ori)
00258 {
00259 
00260   std::vector<GHough::Acc> acc;
00261 
00262   for(uint i=0; i<itsModels.size(); i++)
00263   {
00264     for(uint j=0; j<itsModels[i].rTables.size(); j++)
00265     {
00266       std::vector<GHough::Acc> accScale =  getVotes(i, itsModels[i].rTables[j], mag, ori);
00267       for(uint j=0; j<accScale.size(); j++)
00268         acc.push_back(accScale[j]);
00269     }
00270   }
00271 
00272   //sort the acc
00273   //std::sort(acc.begin(), acc.end(), AccCmp());
00274 
00275   return acc;
00276 }
00277 
00278 
00279 void GHough::setPosOffset(int id, Point3D<float> pos)
00280 {
00281 
00282   itsModels[id].pos = pos;
00283 
00284 }
00285 
00286 GHough::RTable GHough::createRTable(const Image<byte>& img, const Image<float>& ang,
00287     Point2D<float>& imgPos, int& numFeatures, Point2D<float>& imgLoc)
00288 {
00289   RTable rTable;
00290 
00291   //Compute refrance Point
00292   Point2D<int> center(0,0);
00293   int numOfPixels = 0;
00294 
00295   imgLoc = Point2D<float>(0,0);
00296   for(int y=0; y<img.getHeight(); y++)
00297     for(int x=0; x<img.getWidth(); x++)
00298     {
00299       if (img.getVal(x,y) > 0)
00300       {
00301         center.i += x;
00302         center.j += y;
00303         numOfPixels++;
00304 
00305         if (y > imgLoc.j)
00306           imgLoc = Point2D<float>(x,y);
00307       }
00308     }
00309   numFeatures = numOfPixels;
00310   if (numOfPixels > 0)
00311     center /= numOfPixels;
00312   else
00313     return rTable;
00314 
00315   //LINFO("Learn pos");
00316   //Image<PixRGB<byte> > tmp = img;
00317   //drawCircle(tmp, Point2D<int>(imgLoc), 3, PixRGB<byte>(255,0,0));
00318   //SHOWIMG(tmp);
00319 
00320 
00321   imgPos.i = imgLoc.i - center.i;
00322   imgPos.j = imgLoc.j - center.j;
00323 
00324 
00325   double D=M_PI/itsNumEntries;
00326 
00327   for(int y=0; y<img.getHeight(); y++)
00328     for(int x=0; x<img.getWidth(); x++)
00329     {
00330       if (img.getVal(x,y) > 0)
00331       {
00332         double phi = ang.getVal(x,y);
00333         int i = (int)round(phi/D);
00334         rTable.entries[i].push_back(Point2D<float>(x-center.i, y-center.j));
00335       }
00336     }
00337   return rTable;
00338 }
00339 
00340 GHough::RTable GHough::createRTable(const Image<byte>& img, const Image<float>& ang,
00341     Point2D<int>& center, int& numFeatures)
00342 {
00343   RTable rTable;
00344 
00345   //Compute refrance Point
00346   center.i = 0; center.j = 0;
00347   int numOfPixels = 0;
00348 
00349   for(int y=0; y<img.getHeight(); y++)
00350     for(int x=0; x<img.getWidth(); x++)
00351     {
00352       if (img.getVal(x,y) > 0)
00353       {
00354         center.i += x;
00355         center.j += y;
00356         numOfPixels++;
00357       }
00358     }
00359   numFeatures = numOfPixels;
00360   if (numOfPixels > 0)
00361     center /= numOfPixels;
00362   else
00363     return rTable;
00364 
00365   double D=M_PI/itsNumEntries;
00366 
00367   for(int y=0; y<img.getHeight(); y++)
00368     for(int x=0; x<img.getWidth(); x++)
00369     {
00370       if (img.getVal(x,y) > 0)
00371       {
00372         double phi = ang.getVal(x,y);
00373 
00374         if (phi < 0) phi += M_PI;
00375         if (phi > M_PI) phi -= M_PI;
00376 
00377         int i = (int)round(phi/D);
00378         rTable.entries[i].push_back(Point2D<float>(x-center.i, y-center.j));
00379       }
00380     }
00381   return rTable;
00382 }
00383 
00384 GHough::RTable GHough::createRTable(const std::vector<Feature>& features,
00385     Point2D<float>& imgPos, Point2D<float>& imgLoc)
00386 {
00387   RTable rTable;
00388 
00389   //Compute refrance Point
00390   imgLoc = Point2D<float>(0,0);
00391   Point2D<float> center(0,0);
00392   for(uint i=0; i<features.size(); i++)
00393   {
00394     center += features[i].loc;
00395     if (features[i].loc.j > imgLoc.j)
00396       imgLoc = features[i].loc;
00397   }
00398   center /= features.size();
00399 
00400   //LINFO("Learn pos");
00401   //Image<PixRGB<byte> > tmp(150,150,ZEROS);
00402   //for(uint i=0; i<features.size(); i++)
00403   //  tmp.setVal(Point2D<int>(features[i].loc), PixRGB<byte>(0,255,0));
00404   //drawCircle(tmp, Point2D<int>(imgLoc), 3, PixRGB<byte>(255,0,0));
00405   //SHOWIMG(tmp);
00406 
00407   imgPos.i = imgLoc.i - center.i;
00408   imgPos.j = imgLoc.j - center.j;
00409 
00410   for(uint i=0; i<features.size(); i++)
00411   {
00412     long idx = getIndex(features[i].values);
00413 
00414     Feature f;
00415     f.loc = features[i].loc - center;
00416     f.values = features[i].values;
00417     rTable.featureEntries[idx].push_back(f);
00418   }
00419 
00420   return rTable;
00421 }
00422 
00423 long GHough::getIndex(const std::vector<float>& values)
00424 {
00425 
00426   double D=2*M_PI/45; //itsNumEntries;
00427 
00428   //Generate a histogram
00429   int hist[360];
00430   for(uint i=0; i<360; i++)
00431     hist[i] = 0;
00432 
00433   for(uint i=0; i<values.size(); i++)
00434   {
00435     float ang = values[i];
00436     if (ang < 0) ang += 2*M_PI;
00437     if (ang > 2*M_PI) ang -= M_PI*2;
00438     int idx = (int)round(ang/D);
00439     hist[idx]++;
00440   }
00441 
00442   //Show histogram
00443 
00444   //for(uint i=0; i<360; i++)
00445   //  if (hist[i] > 0)
00446   //    printf("%i:%i ", i, hist[i]);
00447   //printf("\n");
00448 
00449 
00450   //Generate the index from the histogram
00451   long idx = 0;
00452   for(uint i=0; i<360; i++)
00453   {
00454     if (hist[i] > 0)
00455       idx = (360*idx) + i; 
00456   }
00457   //LINFO("Index %ld", idx);
00458 
00459   return idx;
00460 
00461 }
00462 
00463 Point3D<float> GHough::getModelRot(const int id)
00464 {
00465   if (id >= 0 && id < (int)itsModels.size())
00466     return itsModels[id].rot;
00467   else
00468   {
00469     LFATAL("Invalid model id %i", id);
00470     return Point3D<float>(0,0,0);
00471   }
00472 
00473 }
00474 
00475 Point2D<float> GHough::getModelImgPos(const int id)
00476 {
00477   if (id >= 0 && id < (int)itsModels.size())
00478     return itsModels[id].imgPos;
00479   else
00480   {
00481     LFATAL("Invalid model id %i", id);
00482     return Point2D<float>(0,0);
00483   }
00484 }
00485 
00486 int GHough::getModelType(const int id)
00487 {
00488   if (id >= 0 && id < (int)itsModels.size())
00489     return itsModels[id].type;
00490   else
00491   {
00492     LFATAL("Invalid model id %i", id);
00493     return -1;
00494   }
00495 }
00496 
00497 Point3D<float> GHough::getModelPosOffset(const int id)
00498 {
00499   if (id >= 0 && id < (int)itsModels.size())
00500     return itsModels[id].pos;
00501   else 
00502   {
00503     LFATAL("Invalid model id %i", id);
00504     return Point3D<float>(0,0,0);
00505   }
00506 }
00507 
00508 std::vector<GHough::Acc> GHough::getVotes(const Image<byte>& img, const Image<float>& ang)
00509 {
00510   std::vector<GHough::Acc> acc;
00511 
00512   for(uint i=0; i<itsModels.size(); i++)
00513   {
00514     for(uint j=0; j<itsModels[i].rTables.size(); j++)
00515     {
00516       std::vector<GHough::Acc> accScale =  getVotes(i, itsModels[i].rTables[j], img, ang);
00517       for(uint j=0; j<accScale.size(); j++)
00518         acc.push_back(accScale[j]);
00519     }
00520   }
00521 
00522   //sort the acc
00523   std::sort(acc.begin(), acc.end(), AccCmp());
00524 
00525   return acc;
00526 
00527 }
00528 
00529 std::vector<GHough::Acc> GHough::getVotes(const std::vector<Feature>& features)
00530 {
00531 
00532   //Show the features
00533   Image<PixRGB<byte> > cornersImg(320, 240, ZEROS);
00534   for(uint i=0; i<features.size(); i++)
00535   {
00536     for(uint ai=0; ai<features[i].values.size(); ai++)
00537     {
00538       int x1 = int(cos(features[i].values[ai])*30.0/2.0);
00539       int y1 = int(sin(features[i].values[ai])*30.0/2.0);
00540       Point2D<float> p1(features[i].loc.i-x1, features[i].loc.j+y1);
00541 
00542       drawLine(cornersImg, Point2D<int>(features[i].loc), Point2D<int>(p1), PixRGB<byte>(0,255,0));
00543     }
00544   }
00545   SHOWIMG(cornersImg);
00546   
00547   //itsSOFM->RandomWeights(0,1);
00548   //itsSOFM->ReadNet("hough.sofm");
00549   //for(uint i=0; i<10; i++)
00550   //trainSOFM();
00551 
00552 
00553   CpuTimer timer;
00554   timer.reset();
00555   
00556   //std::vector<rutz::shared_ptr<GHTJob> > jobs;
00557   
00558   std::vector<GHough::Acc> acc;
00559   uint numModels = 0;
00560   for(uint i=0; i<itsModels.size(); i++)
00561   {
00562 
00563     for(uint j=0; j<itsModels[i].rTables.size(); j++)
00564     {
00565       uint numFeatures = getNumFeatures(i);
00566       if (numFeatures < 3)
00567         continue;
00568       if (itsModels[i].type != 1)
00569         continue;
00570 
00571       float maxVotes  =0;
00572       //Image<PixRGB<byte> > rTableImg = getRTableImg(i);
00573       //SHOWIMG(rTableImg);
00574       std::vector<GHough::Acc> accScale =  getVotes2(i, itsModels[i].rTables[j], features, maxVotes);
00575 
00576       //if (accScale.size() > 0 && maxVotes > 0.01)
00577       {
00578         LINFO("Model %i/%i rt %i nf %i maxVotes %f rot %f,%f,%f", i,
00579             (uint)itsModels.size(), j, numFeatures, maxVotes,
00580             itsModels[i].rot.x,itsModels[i].rot.y,itsModels[i].rot.z);
00581         Image<PixRGB<byte> > rTableImg = getRTableImg(i);
00582         SHOWIMG(rTableImg);
00583 
00584         Image<float> accImg = getAccImg(accScale);
00585         inplaceNormalize(accImg, 0.0F, 255.0F);
00586         Image<PixRGB<byte> > tmp = accImg;
00587         tmp += cornersImg;
00588         SHOWIMG(tmp);
00589       }
00590 
00591       for(uint j=0; j<accScale.size(); j++)
00592         acc.push_back(accScale[j]);
00593 
00594       //jobs.push_back(rutz::make_shared(new GHTJob(this, i, itsModels[i].rTables[j], features, acc)));
00595       //itsThreadServer->enqueueJob(jobs.back());
00596 
00597       numModels++;
00598 
00599     }
00600   }
00601 
00602   ////wait for jobs to finish
00603   //while(itsThreadServer->size() > 0)
00604   //  usleep(10000);
00605 
00606   timer.mark();
00607   LINFO("Total time %0.2f sec for %i models (%i proposals)", timer.real_secs(), numModels, (uint)acc.size());
00608 
00609   //sort the acc
00610   std::sort(acc.begin(), acc.end(), AccCmp());
00611 
00612   return acc;
00613 
00614 }
00615 
00616 
00617 std::vector<GHough::Acc> GHough::getVotes(int id, const RTable& rTable,
00618     const Image<byte>& img, const Image<float>& ang)
00619 {
00620   double D=M_PI/itsNumEntries;
00621 
00622 
00623   std::map<unsigned long, Acc> tmpAcc;
00624 
00625   Image<float> accImg(320, 240, ZEROS);
00626 
00627   for(int y=0; y<img.getHeight(); y++)
00628     for(int x=0; x<img.getWidth(); x++)
00629     {
00630       if (img.getVal(x,y) > 0)
00631       {
00632         double phi = ang.getVal(x,y);
00633         if (phi < 0) phi += M_PI;
00634         if (phi > M_PI) phi -= M_PI;
00635         int i = (int)round(phi/D);
00636 
00637         std::map<int, std::vector<Point2D<float> > >::const_iterator iter = 
00638           rTable.entries.find(i);
00639 
00640         if (iter != rTable.entries.end())
00641         {
00642           ////Vote
00643           for(uint j=0; j<iter->second.size(); j++)
00644           {
00645             Point2D<float> loc =iter->second[j];
00646             Point2D<int> voteLoc(int(x-loc.i),int(y-loc.j)); 
00647             if (voteLoc.i > 0 && voteLoc.i < 512 &&
00648                 voteLoc.j > 0 && voteLoc.j < 512)
00649             {
00650               if (accImg.coordsOk(voteLoc))
00651                 accImg.setVal(voteLoc, accImg.getVal(voteLoc) + 1);
00652               unsigned long key = id*512*512 + voteLoc.j*512 + voteLoc.i; 
00653               std::map<unsigned long, Acc>::iterator it = tmpAcc.find(key);
00654               if (it != tmpAcc.end())
00655                 it->second.votes++;
00656               else
00657                 tmpAcc[key] = Acc(id, voteLoc,1);
00658             }
00659           }
00660         }
00661       }
00662     }
00663 
00664   std::vector<Acc> acc;
00665 
00666   for(uint i=0; i<100; i++)
00667   {
00668     Point2D<int> maxLoc; float maxVal;
00669     findMax(accImg, maxLoc, maxVal);
00670 
00671     acc.push_back(Acc(0, maxLoc, maxVal));
00672     drawDisk(accImg, maxLoc, 10, 0.0F);
00673     //SHOWIMG(accImg);
00674   }
00675 
00676 
00677   //std::map<unsigned long, Acc>::iterator it;
00678   //for(it = tmpAcc.begin(); it != tmpAcc.end(); it++)
00679   //{
00680   //  it->second.prob = float(it->second.votes)/float(itsModels[it->second.id].numFeatures);
00681   //  //if (it->second.prob > 0.20)
00682   //  {
00683   //    acc.push_back(it->second);
00684   //  }
00685   //}
00686 
00687   return acc;
00688 }
00689 
00690 
00691 std::vector<GHough::Acc> GHough::getVotes(int id, const RTable& rTable, const std::vector<Feature>& features, float& maxVotes)
00692 {
00693   std::map<unsigned long, Acc> tmpAcc;
00694 
00695   //Used for appliing a variance over position
00696   //TODO change to a veriance in feature position, not its endpoint
00697   float stddevX = 1.1;
00698   float stddevY = 1.1;
00699   int voteSizeX = int(ceil(stddevX * sqrt(-2.0F * log(exp(-5.0F)))));
00700   int voteSizeY = int(ceil(stddevY * sqrt(-2.0F * log(exp(-5.0F)))));
00701 
00702   Image<PixRGB<byte> > tmp(320,240,ZEROS);
00703 
00704   int numFeatures = 0;
00705   for(uint fi=0; fi<features.size(); fi++)
00706   {
00707     long idx = getIndex(features[fi].values);
00708 
00709 
00710     /************/
00711     for(uint ai=0; ai<features[fi].values.size(); ai++)
00712     {
00713       int x1 = int(cos(features[fi].values[ai])*30.0/2.0);
00714       int y1 = int(sin(features[fi].values[ai])*30.0/2.0);
00715       Point2D<float> p1(features[fi].loc.i-x1, features[fi].loc.j+y1);
00716 
00717       drawLine(tmp, Point2D<int>(features[fi].loc), Point2D<int>(p1), PixRGB<byte>(0,255,0));
00718     }
00719 
00720     LINFO("Feature %i indx %ld\n", fi, idx);
00721     SHOWIMG(tmp);
00722     /****************/
00723 
00724 
00725 
00726     std::map<long, std::vector<Feature > >::const_iterator iter = 
00727       rTable.featureEntries.find(idx);
00728 
00729     if (iter != rTable.featureEntries.end())
00730     {
00731       LINFO("Found match");
00732       ////Vote
00733       for(uint j=0; j<iter->second.size(); j++)
00734       {
00735         Point2D<float> loc =iter->second[j].loc;
00736 
00737         Point2D<int> voteLoc(int(features[fi].loc.i-loc.i),int(features[fi].loc.j-loc.j)); 
00738         numFeatures ++;
00739 
00740         
00741         //Vote in a gaussien unsertinty
00742         for(int y=voteLoc.j-voteSizeY; y<voteLoc.j+voteSizeY; y++)
00743         {
00744           float diffY = y-voteLoc.j;
00745           float ry = exp(-((diffY*diffY)/(stddevY*stddevY)));
00746           for(int x=voteLoc.i-voteSizeX; x<voteLoc.i+voteSizeX; x++)
00747           {
00748             float diffX = x-voteLoc.i;
00749             float rx = exp(-((diffX*diffX)/(stddevX*stddevX)));
00750             //float weight = nafState.prob + rRot*rx*ry;
00751             float weight = rx*ry;
00752 
00753             if (x > 0 && x < 512 &&
00754                 y > 0 && y < 512)
00755             {
00756               unsigned long key = id*512*512 + y*512 + x; 
00757 
00758               std::map<unsigned long, Acc>::iterator it = tmpAcc.find(key);
00759               if (it != tmpAcc.end())
00760                 it->second.votes += weight;
00761               else
00762                 tmpAcc[key] = Acc(id, x,y, weight);
00763             }
00764           }
00765         }
00766       }
00767     }
00768   }
00769 
00770   std::vector<Acc> acc;
00771 
00772 
00773   std::map<unsigned long, Acc>::iterator it;
00774   for(it = tmpAcc.begin(); it != tmpAcc.end(); it++)
00775   {
00776     it->second.prob = float(it->second.votes)/float(numFeatures);
00777     //LINFO("id:%i geons %i votes %i features %i prob %f", 
00778     //    it->second.id,
00779     //    getModelType( it->second.id),
00780     //    it->second.votes,
00781     //    numFeatures,
00782     //    it->second.prob);
00783     if (it->second.votes > maxVotes)
00784       maxVotes = it->second.votes;
00785 
00786     if (it->second.votes > 1)
00787     {
00788       acc.push_back(it->second);
00789     }
00790   }
00791 
00792   return acc;
00793 }
00794 
00795 std::vector<GHough::Acc> GHough::getVotes2(int id, const RTable& rTable, const std::vector<Feature>& features, float& maxVotes)
00796 {
00797   std::map<unsigned long, Acc> tmpAcc;
00798 
00799   //Used for appliing a variance over position
00800   //TODO change to a veriance in feature position, not its endpoint
00801   float stddevX = 0.5;
00802   float stddevY = 0.5;
00803   int voteSizeX = int(ceil(stddevX * sqrt(-2.0F * log(exp(-5.0F)))));
00804   int voteSizeY = int(ceil(stddevY * sqrt(-2.0F * log(exp(-5.0F)))));
00805 
00806   Image<PixRGB<byte> > tmp(320,240,ZEROS);
00807 
00808   int numFeatures = 0;
00809   for(uint fi=0; fi<features.size(); fi++)
00810   {
00811     //Build a GMM
00812     std::vector<GaussianDef> gmmF;
00813     double weight = 1.0/double(features[fi].values.size()); //equal weight
00814     for(uint i=0; i<features[fi].values.size(); i++)
00815       gmmF.push_back(GaussianDef(weight, features[fi].values[i], 1*M_PI/180)); //1 deg variance
00816 
00817     //Find all the features that are closest to this one and vote
00818 
00819     std::map<long, std::vector<Feature> >::const_iterator iter;
00820     for(iter = rTable.featureEntries.begin(); iter != rTable.featureEntries.end(); iter++)
00821     {
00822       for(uint k=0; k<iter->second.size(); k++)
00823       {
00824         const Feature& feature = iter->second[k];
00825         if (feature.values.size() > 1)
00826         {
00827           std::vector<GaussianDef> gmmG;
00828           double weight = 1.0/double(feature.values.size()); //equal weight
00829           for(uint j=0; j<feature.values.size(); j++)
00830             gmmG.push_back(GaussianDef(weight, feature.values[j], (1*M_PI/180))); //2 deg variance
00831 
00832           double dist = L2GMM(gmmF, gmmG);
00833           if (dist < 2)
00834           {
00835             Point2D<float> loc =iter->second[k].loc;
00836             Point2D<int> voteLoc(int(features[fi].loc.i-loc.i),int(features[fi].loc.j-loc.j)); 
00837             numFeatures ++;
00838 
00839             //Vote in a gaussien unsertinty
00840             for(int y=voteLoc.j-voteSizeY; y<voteLoc.j+voteSizeY; y++)
00841             {
00842               float diffY = y-voteLoc.j;
00843               float ry = exp(-((diffY*diffY)/(stddevY*stddevY)));
00844               for(int x=voteLoc.i-voteSizeX; x<voteLoc.i+voteSizeX; x++)
00845               {
00846                 float diffX = x-voteLoc.i;
00847                 float rx = exp(-((diffX*diffX)/(stddevX*stddevX)));
00848                 //float weight = nafState.prob + rRot*rx*ry;
00849                 float weight = rx*ry;
00850 
00851                 if (x > 0 && x < 512 &&
00852                     y > 0 && y < 512)
00853                 {
00854                   unsigned long key = id*512*512 + y*512 + x; 
00855 
00856                   std::map<unsigned long, Acc>::iterator it = tmpAcc.find(key);
00857                   if (it != tmpAcc.end())
00858                     it->second.votes += weight;
00859                   else
00860                     tmpAcc[key] = Acc(id, x,y, weight);
00861                 }
00862               }
00863             }
00864           }
00865 
00866         }
00867       }
00868     }
00869 
00870 
00871   }
00872 
00873   std::vector<Acc> acc;
00874 
00875 
00876   std::map<unsigned long, Acc>::iterator it;
00877   for(it = tmpAcc.begin(); it != tmpAcc.end(); it++)
00878   {
00879     it->second.prob = float(it->second.votes)/float(numFeatures);
00880     //LINFO("id:%i geons %i votes %i features %i prob %f", 
00881     //    it->second.id,
00882     //    getModelType( it->second.id),
00883     //    it->second.votes,
00884     //    numFeatures,
00885     //    it->second.prob);
00886     if (it->second.votes > maxVotes)
00887       maxVotes = it->second.votes;
00888 
00889     if (it->second.votes > 1)
00890     {
00891       acc.push_back(it->second);
00892     }
00893   }
00894 
00895   return acc;
00896 }
00897 
00898 //Image<float> GHough::getRTableImg(const int id)
00899 //{
00900 //
00901 //  Image<float> img(320,240,ZEROS);
00902 //  for(uint tbl=0; tbl<itsModels[id].rTables.size() && tbl < 1; tbl++)
00903 //  {
00904 //    RTable rTable = itsModels[id].rTables[tbl];
00905 //
00906 //    std::map<int, std::vector<Point2D<float> > >::const_iterator iter;
00907 //    for(iter = rTable.entries.begin(); iter != rTable.entries.end(); iter++)
00908 //    {
00909 //      //int ori = iter->first;
00910 //      for(uint k=0; k<iter->second.size(); k++)
00911 //      {
00912 //        Point2D<int> loc = Point2D<int>(iter->second[k]) + Point2D<int>(320/2, 240/2);
00913 //        img.setVal(loc, 255.0F);
00914 //      }
00915 //    }
00916 //  }
00917 //
00918 //  return img;
00919 //
00920 //}
00921 
00922 Image<float> GHough::getAccImg(std::vector<GHough::Acc>& acc)
00923 {
00924   Image<float> img(320,240,ZEROS);
00925 
00926 
00927   for(uint i=0; i<acc.size(); i++)
00928     img.setVal(acc[i].pos, acc[i].votes);
00929 
00930   Point2D<int> loc; float val;
00931   findMax(img, loc, val);
00932   LINFO("Max at %ix%i val %f", loc.i, loc.j, val);
00933   
00934   return img;
00935 }
00936 
00937 Image<PixRGB<byte> > GHough::getRTableImg(const int id)
00938 {
00939 
00940   Image<PixRGB<byte> > img(320,240,ZEROS);
00941   for(uint tbl=0; tbl<itsModels[id].rTables.size() && tbl < 1; tbl++)
00942   {
00943     const RTable& rTable = itsModels[id].rTables[tbl];
00944 
00945     std::map<long, std::vector<Feature> >::const_iterator iter;
00946     for(iter = rTable.featureEntries.begin(); iter != rTable.featureEntries.end(); iter++)
00947     {
00948       //int ori = iter->first;
00949       for(uint k=0; k<iter->second.size(); k++)
00950       {
00951         const Feature& feature = iter->second[k];
00952         Point2D<int> loc = Point2D<int>(feature.loc) + Point2D<int>(320/2, 240/2);
00953         drawCircle(img, loc, 3, PixRGB<byte>(255,0,0));
00954 
00955         for(uint ai=0; ai<feature.values.size(); ai++)
00956         {
00957           int x1 = int(cos(feature.values[ai])*30.0/2.0);
00958           int y1 = int(sin(feature.values[ai])*30.0/2.0);
00959           Point2D<float> p1(loc.i-x1, loc.j+y1);
00960 
00961           drawLine(img, Point2D<int>(loc), Point2D<int>(p1), PixRGB<byte>(0,255,0));
00962         }
00963       }
00964     }
00965   }
00966   return img;
00967 }
00968 
00969 
00970 void GHough::trainSOFM()
00971 {
00972 
00973   Image<PixRGB<byte> > tmp = itsSOFM->getWeightsImage();
00974   SHOWIMG(tmp);
00975 
00976   std::vector<Feature> features;
00977 
00978   for(uint obj=0; obj<itsModels.size(); obj++)
00979   {
00980     for(uint tbl=0; tbl<itsModels[obj].rTables.size() && tbl < 1; tbl++)
00981     {
00982       const RTable& rTable = itsModels[obj].rTables[tbl];
00983 
00984       std::map<long, std::vector<Feature> >::const_iterator iter;
00985       for(iter = rTable.featureEntries.begin(); iter != rTable.featureEntries.end(); iter++)
00986       {
00987         for(uint k=0; k<iter->second.size(); k++)
00988         {
00989           const Feature& feature = iter->second[k];
00990           if (feature.values.size() > 1)
00991             features.push_back(feature);
00992           //Point2D<int> loc = Point2D<int>(feature.loc) + Point2D<int>(320/2, 240/2);
00993 
00994           //itsSOFM->setInput(hist);
00995           //itsSOFM->Propagate();
00996 
00997           //double winnerVal;
00998           //Point2D<int> winnerId = itsSOFM->getWinner(winnerVal);
00999 
01000           //itsSOFM->organize(hist);
01001           
01002         }
01003       }
01004     }
01005     //LINFO("Obj %i/%lu done", obj, itsModels.size());
01006 
01007   //  Image<PixRGB<byte> > tmp = itsSOFM->getWeightsImage();
01008   //  SHOWIMG(tmp);
01009   }
01010   //itsSOFM->WriteNet("hough.sofm");
01011 
01012   //Image<float> amap = itsSOFM->getActMap();
01013   //SHOWIMG(amap);
01014   //
01015 
01016   int idx = 1203;
01017 
01018   //Build a GMM
01019   std::vector<GaussianDef> gmmF;
01020   double weight = 1.0/double(features[idx].values.size()); //equal weight
01021   for(uint i=0; i<features[idx].values.size(); i++)
01022     gmmF.push_back(GaussianDef(weight, features[idx].values[i], 1*M_PI/180)); //2 deg variance
01023 
01024   Image<PixRGB<byte> > qImg(320,240,ZEROS);
01025   for(uint ai=0; ai<features[idx].values.size(); ai++)
01026   {
01027     int x1 = int(cos(features[idx].values[ai])*30.0/2.0);
01028     int y1 = int(sin(features[idx].values[ai])*30.0/2.0);
01029     Point2D<float> p1(320/2-x1, 240/2+y1);
01030 
01031     drawLine(qImg, Point2D<int>(320/2,240/2), Point2D<int>(p1), PixRGB<byte>(0,255,0));
01032   }
01033   SHOWIMG(qImg);
01034 
01035   LINFO("Features %i", (uint)features.size());
01036   for(uint i=0; i<features.size(); i++)
01037   {
01038     printf("Feature c: ");
01039     for(uint j=0; j<features[idx].values.size(); j++)
01040       printf("%f ", features[idx].values[j]*180/M_PI);
01041     printf("\n");
01042 
01043     printf("Feature %i: ", i);
01044     for(uint j=0; j<features[i].values.size(); j++)
01045       printf("%f ", features[i].values[j]*180/M_PI);
01046     printf("\n");
01047 
01048 
01049     std::vector<GaussianDef> gmmG;
01050     double weight = 1.0/double(features[i].values.size()); //equal weight
01051     for(uint j=0; j<features[i].values.size(); j++)
01052       gmmG.push_back(GaussianDef(weight, features[i].values[j], (1*M_PI/180))); //2 deg variance
01053 
01054     double dist = L2GMM(gmmF, gmmG);
01055     LINFO("Dist %f", dist);
01056     LINFO("\n");
01057 
01058     if (dist < 2)
01059     {
01060       Image<PixRGB<byte> > tmp2 = qImg;
01061       for(uint ai=0; ai<features[i].values.size(); ai++)
01062       {
01063         int x1 = int(cos(features[i].values[ai])*30.0/2.0);
01064         int y1 = int(sin(features[i].values[ai])*30.0/2.0);
01065         Point2D<float> p1(320/2-x1, 240/2+y1);
01066 
01067         drawLine(tmp2, Point2D<int>(320/2,240/2), Point2D<int>(p1), PixRGB<byte>(255,0,0));
01068       }
01069       SHOWIMG(tmp2);
01070     }
01071   }
01072     
01073 }
01074 
01075 
01076 uint GHough::getNumFeatures(const int id)
01077 {
01078 
01079   uint numFeatures=0;
01080   for(uint tbl=0; tbl<itsModels[id].rTables.size() && tbl < 1; tbl++)
01081   {
01082     const RTable& rTable = itsModels[id].rTables[tbl];
01083 
01084     std::map<long, std::vector<Feature> >::const_iterator iter;
01085     for(iter = rTable.featureEntries.begin(); iter != rTable.featureEntries.end(); iter++)
01086     {
01087       //int ori = iter->first;
01088       for(uint k=0; k<iter->second.size(); k++)
01089       {
01090         numFeatures++;
01091       }
01092     }
01093   }
01094   return numFeatures;
01095 
01096 }
01097 
01098 //Image<float> GHough::getCorners()
01099 //{
01100 //
01101 //  float hist[360];
01102 //
01103 //  for(uint obj=0; obj<itsModels.size(); obj++)
01104 //    for(uint tbl=0; tbl<itsModels[id].rTables.size() && tbl < 1; tbl++)
01105 //    {
01106 //      RTable rTable = itsModels[id].rTables[tbl];
01107 //
01108 //      std::map<long, std::vector<Feature> >::const_iterator iter;
01109 //      for(iter = rTable.featureEntries.begin(); iter != rTable.featureEntries.end(); iter++)
01110 //      {
01111 //        for(uint j=0; j<iter->second.size(); j++)
01112 //        {
01113 //          Point2D<float> loc =iter->second[j].loc;
01114 //          numFeatures ++;
01115 //          Point2D<int> voteLoc(int(features[fi].loc.i-loc.i),int(features[fi].loc.j-loc.j)); 
01116 //          if (voteLoc.i > 0 && voteLoc.i < 512 &&
01117 //              voteLoc.j > 0 && voteLoc.j < 512)
01118 //          {
01119 //            unsigned long key = id*512*512 + voteLoc.j*512 + voteLoc.i; 
01120 //            std::map<unsigned long, Acc>::iterator it = tmpAcc.find(key);
01121 //            if (it != tmpAcc.end())
01122 //              it->second.votes++;
01123 //            else
01124 //              tmpAcc[key] = Acc(id, voteLoc);
01125 //          }
01126 //        }
01127 //      }
01128 //    }
01129 //
01130 //  return Image<float>();
01131 //}
01132 
01133 
01134 void GHough::createInvRTable(const Image<byte>& img, const Image<float>& ang)
01135 {
01136 
01137   //Compute refrance Point
01138   Point2D<int> center(0,0);
01139   int numOfPixels = 0;
01140 
01141   for(int y=0; y<img.getHeight(); y++)
01142     for(int x=0; x<img.getWidth(); x++)
01143     {
01144       if (img.getVal(x,y) > 0)
01145       {
01146         center.i += x;
01147         center.j += y;
01148         numOfPixels++;
01149       }
01150     }
01151   center /= numOfPixels;
01152 
01153   int entries = 5;
01154   double D=M_PI/entries;
01155 
01156   Model model;
01157   model.id = 0;
01158 
01159   for(int y=0; y<img.getHeight(); y++)
01160     for(int x=0; x<img.getWidth(); x++)
01161     {
01162       if (img.getVal(x,y) > 0)
01163       {
01164         Point2D<int> w2 = findInvFeature(x,y, img, ang);
01165 
01166         if (w2.isValid())
01167         {
01168           //Compute beta
01169           double phi = tan(ang.getVal(x,y));
01170           double phj = tan(ang.getVal(w2));
01171 
01172           double beta=1.57;
01173           if ((1.0+phi*phj) != 0)
01174             beta=atan((phi-phj)/(1.0+phi*phj));
01175 
01176           //compute k
01177           double ph=1.57;
01178           if((x-center.i)!=0)
01179             ph=atan(float(y-center.j)/float(x-center.i));
01180           double k=ph-ang.getVal(x,y);
01181 
01182           //Insert into the table
01183           int i=(int)round((beta+(M_PI/2))/D);
01184 
01185           model.invRTable[i].push_back(k);
01186 
01187         }
01188       }
01189     }
01190 
01191   itsModels.push_back(model);
01192 }
01193 
01194 
01195 Point2D<int> GHough::findInvFeature(const int x, const int y, const Image<float>&img, const Image<float>& ang)
01196 {
01197   double alpha = M_PI/4;
01198   //Find a second feature point
01199   Point2D<int> w2(-1,-1);
01200   double phi = ang.getVal(x,y) + M_PI/2;
01201   double m = tan(phi-alpha);
01202 
01203   //Follow a line (in bouth direction of x,y) 
01204   //and find the next feature from that location
01205   if (m>-1 && m<1)
01206   {
01207     for(int i=3; i<img.getWidth(); i++)
01208     {
01209       int c = x + i;
01210       int j=(int)round(m*(x-c)+y);
01211       Point2D<int> loc(c,j);
01212 
01213       if (img.coordsOk(loc) && img.getVal(loc) > 0)
01214       {
01215         w2 = loc; //We found the feature
01216         break;
01217       } else {
01218         //Look in the other direction
01219         c = x - i;
01220         j=(int)round(m*(x-c)+y);
01221         loc = Point2D<int>(c,j);
01222         if (img.coordsOk(loc) && img.getVal(loc) > 0)
01223         {
01224           w2 = loc; //We found the feature
01225           break;
01226         }
01227       }
01228     }
01229   } else {
01230     for(int i=3; i<img.getHeight(); i++)
01231     {
01232       int c = y + i;
01233       int j=(int)round(x+(y-c)/m);
01234       Point2D<int> loc(j,c);
01235 
01236       if (img.coordsOk(loc) && img.getVal(loc) > 0)
01237       {
01238         w2 = loc; //We found the feature
01239         break;
01240       } else {
01241         //Look in the other direction
01242         c = y - i;
01243         j=(int)round(x+(y-c)/m);
01244         loc = Point2D<int>(j,c);
01245         if (img.coordsOk(loc) && img.getVal(loc) > 0)
01246         {
01247           w2 = loc; //We found the feature
01248           break;
01249         }
01250       }
01251     }
01252   }
01253 
01254   return w2;
01255 }
01256 
01257 Image<float> GHough::getInvVotes(const Image<byte>& img,
01258     const Image<float>& ang)
01259 {
01260   int entries = 5;
01261   double D=M_PI/entries;
01262 
01263   Image<float> acc(img.getDims(), ZEROS);
01264 
01265   for(int y=0; y<img.getHeight(); y++)
01266     for(int x=0; x<img.getWidth(); x++)
01267     {
01268       if (img.getVal(x,y) > 0)
01269       {
01270         Point2D<int> w2 = findInvFeature(x,y,img, ang);
01271 
01272         if (w2.isValid())
01273         {
01274           //Compute beta
01275           double phi = tan(ang.getVal(x,y));
01276           double phj = tan(ang.getVal(w2));
01277 
01278           double beta=1.57;
01279           if ((1+phi*phj) != 0)
01280             beta=atan((phi-phj)/(1+phi*phj));
01281 
01282           //Read from rTable
01283           int i=(int)round((beta+(M_PI/2))/D);
01284 
01285           //Search for k
01286           std::map<int, std::vector<double> >::iterator iter =
01287             itsModels[0].invRTable.find(i);
01288 
01289           for(uint j=0; j<iter->second.size(); j++)
01290           {
01291             float k=iter->second[j];
01292             //lines of votes
01293             float m=tan(k+ang.getVal(x,y));
01294             if (m>-1 && m<1)
01295             {
01296               for(int x0=1; x0<img.getWidth(); x0++)
01297               {
01298                 int y0=(int)round(y+m*(x0-x));
01299                 if(y0>0 && y0<img.getHeight())
01300                   acc.setVal(x0,y0, acc.getVal(x0,y0)+1);
01301               }
01302             } else {
01303               for(int y0=0; y0<img.getHeight(); y0++)
01304               {
01305                 int x0=(int)round(x+(y0-y)/m);
01306                 if(x0>0 && x0<img.getWidth())
01307                   acc.setVal(x0,y0, acc.getVal(x0,y0)+1);
01308               }
01309             }
01310           }
01311 
01312         }
01313       }
01314     }
01315 
01316   return acc;
01317 }
01318 
01319 
01320 void GHough::writeTable(const char* filename)
01321 {
01322   int fd;
01323 
01324   if ((fd = creat(filename, 0644)) == -1)
01325     LFATAL("Can not open %s for saving\n", filename);
01326 
01327   //Write the Dims of the table
01328   size_t numModels = itsModels.size();
01329   int ret = write(fd, (char *) &numModels, sizeof(size_t));
01330 
01331   for(uint i=0; i<numModels; i++)
01332   {
01333     ret = write(fd, (char *) &itsModels[i].id, sizeof(int));
01334     ret = write(fd, (char *) &itsModels[i].type, sizeof(int));
01335     ret = write(fd, (char *) &itsModels[i].pos, sizeof(Point3D<float>));
01336     ret = write(fd, (char *) &itsModels[i].rot, sizeof(Point3D<float>));
01337     ret = write(fd, (char *) &itsModels[i].imgPos, sizeof(Point2D<float>));
01338     ret = write(fd, (char *) &itsModels[i].numFeatures, sizeof(int));
01339 
01340 
01341     size_t numTables = itsModels[i].rTables.size();
01342     ret = write(fd, (char *) &numTables, sizeof(size_t));
01343 
01344     for(uint j=0; j<numTables; j++)
01345     {
01346       //Size of each table
01347       RTable& rTable = itsModels[i].rTables[j];
01348 
01349       //Entries
01350       size_t numEntries = rTable.entries.size();
01351       ret = write(fd, (char *) &numEntries, sizeof(size_t));
01352 
01353       std::map<int, std::vector<Point2D<float> > >::const_iterator iter;
01354       for(iter = rTable.entries.begin(); iter != rTable.entries.end(); iter++)
01355       {
01356         ret = write(fd, (char *) &iter->first, sizeof(int));
01357 
01358         size_t numPos = iter->second.size();
01359         ret = write(fd, (char *) &numPos, sizeof(size_t));
01360 
01361         for(uint k=0; k<numPos; k++)
01362           ret = write(fd, (char *) &iter->second[k], sizeof(Point2D<float>));
01363       }
01364 
01365       //Feature Entries
01366       size_t numFeatureEntries = rTable.featureEntries.size();
01367       ret = write(fd, (char *) &numFeatureEntries, sizeof(size_t));
01368 
01369       std::map<long, std::vector<Feature> >::const_iterator fiter;
01370       for(fiter = rTable.featureEntries.begin(); fiter != rTable.featureEntries.end(); fiter++)
01371       {
01372         ret = write(fd, (char *) &fiter->first, sizeof(long));
01373 
01374         size_t numFeatures = fiter->second.size();
01375         ret = write(fd, (char *) &numFeatures, sizeof(size_t));
01376 
01377         for(uint k=0; k<numFeatures; k++)
01378         {
01379           ret = write(fd, (char *) &fiter->second[k].loc, sizeof(Point2D<float>));
01380 
01381           size_t numValues = fiter->second[k].values.size();
01382           ret = write(fd, (char *) &numValues, sizeof(size_t));
01383           for(uint ii=0; ii<numValues; ii++)
01384             ret = write(fd, (char *) &fiter->second[k].values[ii], sizeof(float));
01385         }
01386       }
01387 
01388     }
01389   }
01390 
01391   close(fd);
01392 }
01393 
01394 void GHough::readTable(const char* filename)
01395 {
01396   int fd;
01397   if ((fd = open(filename, 0, 0644)) == -1) return;
01398 
01399   LINFO("Reading from %s", filename);
01400 
01401   //Write the Dims of the table
01402   size_t numModels;
01403   int ret = read(fd, (char *) &numModels, sizeof(size_t));
01404 
01405 
01406   itsModels.clear();
01407 
01408   for(uint i=0; i<numModels; i++)
01409   {
01410     Model model;
01411     ret = read(fd, (char *) &model.id, sizeof(int));
01412     ret = read(fd, (char *) &model.type, sizeof(int));
01413     ret = read(fd, (char *) &model.pos, sizeof(Point3D<float>));
01414     ret = read(fd, (char *) &model.rot, sizeof(Point3D<float>));
01415     ret = read(fd, (char *) &model.imgPos, sizeof(Point2D<float>));
01416     ret = read(fd, (char *) &model.numFeatures, sizeof(int));
01417 
01418     size_t numTables;
01419     ret = read(fd, (char *) &numTables, sizeof(size_t));
01420 
01421     int totalFeatures = 0;
01422 
01423     for(uint j=0; j<numTables; j++)
01424     {
01425       //Size of each table
01426 
01427       RTable rTable;
01428 
01429       //features
01430       size_t numEntries;
01431       ret = read(fd, (char *) &numEntries, sizeof(size_t));
01432       for(uint k=0; k<numEntries; k++)
01433       {
01434         int key;
01435         ret = read(fd, (char *) &key, sizeof(int));
01436 
01437         size_t numPos;
01438         ret = read(fd, (char *) &numPos, sizeof(size_t));
01439 
01440         for(uint ii=0; ii<numPos; ii++)
01441         {
01442           Point2D<float> loc;
01443           ret = read(fd, (char *) &loc, sizeof(Point2D<float>));
01444           rTable.entries[key].push_back(loc);
01445         }
01446       }
01447 
01448       //Feature Entries
01449       size_t numFeatureEntries;
01450       ret = read(fd, (char *) &numFeatureEntries, sizeof(size_t));
01451       for(uint k=0; k<numFeatureEntries; k++)
01452       {
01453         long key;
01454         ret = read(fd, (char *) &key, sizeof(long));
01455 
01456         size_t numFeatures;
01457         ret = read(fd, (char *) &numFeatures, sizeof(size_t));
01458 
01459         for(uint ii=0; ii<numFeatures; ii++)
01460         {
01461           Feature f;
01462           ret = read(fd, (char *) &f.loc, sizeof(Point2D<float>));
01463           totalFeatures++;
01464 
01465           size_t numValues;
01466           ret = read(fd, (char *) &numValues, sizeof(size_t));
01467 
01468           for(uint jj=0; jj<numValues; jj++)
01469           {
01470             float value;
01471             ret = read(fd, (char *) &value, sizeof(float));
01472             f.values.push_back(value);
01473           }
01474 
01475           rTable.featureEntries[key].push_back(f);
01476         }
01477       }
01478 
01479       model.rTables.push_back(rTable);
01480     }
01481     itsModels.push_back(model);
01482   }
01483   LINFO("Added %i models", (uint)itsModels.size());
01484   close(fd);
01485 }
01486 
01487 
01488 
01489 // ######################################################################
01490 /* So things look consistent in everyone's emacs... */
01491 /* Local Variables: */
01492 /* indent-tabs-mode: nil */
01493 /* End: */
01494 
01495 #endif
01496 
Generated on Sun May 8 08:04:46 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3