CornersFeatures.C

Go to the documentation of this file.
00001 /*!@file SceneUnderstanding/CornersFeatures.C  */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the 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/plugins/SceneUnderstanding/CornersFeatures.C $
00035 // $Id: CornersFeatures.C 13765 2010-08-06 18:56:17Z lior $
00036 //
00037 
00038 #ifndef CornersFeatures_C_DEFINED
00039 #define CornersFeatures_C_DEFINED
00040 
00041 #include "plugins/SceneUnderstanding/CornersFeatures.H"
00042 
00043 #include "Image/DrawOps.H"
00044 #include "Image/MathOps.H"
00045 //#include "Image/OpenCVUtil.H"
00046 #include "Image/Kernels.H"
00047 #include "Image/FilterOps.H"
00048 #include "Image/Transforms.H"
00049 #include "Image/fancynorm.H"
00050 #include "Image/Convolutions.H"
00051 #include "Image/MatrixOps.H"
00052 #include "Simulation/SimEventQueue.H"
00053 #include "GUI/DebugWin.H"
00054 #include <math.h>
00055 #include <fcntl.h>
00056 #include <limits>
00057 #include <string>
00058 
00059 const ModelOptionCateg MOC_CornersFeatures = {
00060   MOC_SORTPRI_3,   "CornersFeatures-Related Options" };
00061 
00062 // Used by: SimulationViewerEyeMvt
00063 const ModelOptionDef OPT_CornersFeaturesShowDebug =
00064   { MODOPT_ARG(bool), "CornersFeaturesShowDebug", &MOC_CornersFeatures, OPTEXP_CORE,
00065     "Show debug img",
00066     "corners-debug", '\0', "<true|false>", "false" };
00067 
00068 
00069 //Define the inst function name
00070 SIMMODULEINSTFUNC(CornersFeatures);
00071 
00072 // ######################################################################
00073 CornersFeatures::CornersFeatures(OptionManager& mgr, const std::string& descrName,
00074     const std::string& tagName) :
00075   SimModule(mgr, descrName, tagName),
00076   SIMCALLBACK_INIT(SimEventV2Output),
00077   SIMCALLBACK_INIT(SimEventSaveOutput),
00078   SIMCALLBACK_INIT(SimEventUserInput),
00079   itsShowDebug(&OPT_CornersFeaturesShowDebug, this),
00080   itsPatchSize(20,20)
00081 {
00082 
00083   initRandomNumbers();
00084 
00085   itsSOFM = new SOFM("Corners", itsPatchSize.sz(), 50,50 );
00086   //itsSOFM->RandomWeights();
00087   itsSOFM->ReadNet("SOFM.net");
00088 
00089 }
00090 
00091 
00092 // ######################################################################
00093 CornersFeatures::~CornersFeatures()
00094 {
00095 }
00096 
00097 
00098 // ######################################################################
00099 void CornersFeatures::onSimEventV2Output(SimEventQueue& q,
00100                                   rutz::shared_ptr<SimEventV2Output>& e)
00101 {
00102   itsLines = e->getLines();
00103   //itsCornersProposals = e->getCornersProposals();
00104   evolve(q);
00105 
00106   q.post(rutz::make_shared(new SimEventCornersOutput(this, itsCorners)));
00107 }
00108 
00109 // ######################################################################
00110 void CornersFeatures::onSimEventSaveOutput(SimEventQueue& q, rutz::shared_ptr<SimEventSaveOutput>& e)
00111 {
00112   if (itsShowDebug.getVal())
00113     {
00114       // get the OFS to save to, assuming sinfo is of type
00115       // SimModuleSaveInfo (will throw a fatal exception otherwise):
00116       nub::ref<FrameOstream> ofs =
00117         dynamic_cast<const SimModuleSaveInfo&>(e->sinfo()).ofs;
00118       Layout<PixRGB<byte> > disp = getDebugImage(q);
00119       ofs->writeRgbLayout(disp, "CornersFeatures", FrameInfo("CornersFeatures", SRC_POS));
00120     }
00121 }
00122 
00123 // ######################################################################
00124 void CornersFeatures::onSimEventUserInput(SimEventQueue& q, rutz::shared_ptr<SimEventUserInput>& e)
00125 {
00126 
00127   LINFO("Got event %s %ix%i key=%i",
00128       e->getWinName(),
00129       e->getMouseClick().i,
00130       e->getMouseClick().j,
00131       e->getKey());
00132 
00133   if (e->getMouseClick().isValid())
00134   {
00135   }
00136 
00137   //evolve(q);
00138 
00139 }
00140 
00141 std::vector<CornersFeatures::CornerState> CornersFeatures::getCorners(std::vector<V2::LineSegment>& lines)
00142 {
00143   std::vector<CornersFeatures::CornerState> corners;
00144   float minDist = 5;
00145   float minDistSq = minDist*minDist;
00146 
00147   //Image<float> edges(320, 240, ZEROS);
00148   //for(uint i=0; i<lines.size(); i++)
00149   //{
00150   //  V2::LineSegment& ls1 = itsLines[i];
00151   //  drawLine(edges, Point2D<int>(ls1.p1), Point2D<int>(ls1.p2), 255.0F);
00152   //}
00153 
00154 
00155   for(uint i=0; i<lines.size(); i++)
00156   {
00157     V2::LineSegment& ls1 = itsLines[i];
00158 
00159     //Image<PixRGB<byte> > tmp(320,240,ZEROS); // = edges;
00160     //drawLine(tmp, Point2D<int>(ls1.p1), Point2D<int>(ls1.p2), PixRGB<byte>(255,0,0));
00161 
00162     std::vector<float> angles1; //The angles from p1 prospective
00163     std::vector<float> angles2; //the angles from p2 prospective
00164     double dx = ls1.p2.i - ls1.p1.i;
00165     double dy = ls1.p2.j - ls1.p1.j;
00166     double ang = atan2(dx, dy) + M_PI/2;
00167     angles1.push_back(ang);
00168     angles2.push_back(ang+M_PI);
00169 
00170     for(uint j=i+1; j<lines.size(); j++)
00171     {
00172       if (i == j)
00173         continue;
00174       V2::LineSegment& ls2 = itsLines[j];
00175 
00176       //Find if line segment i p1 intesect line segment j, and find the angle betwwen this
00177       //point and the reset of the ends
00178       if (ls1.p1.distanceToSegment(ls2.p1, ls2.p2) < minDist)
00179       {
00180         double dx1 = ls2.p1.i - ls1.p1.i;
00181         double dy1 = ls2.p1.j - ls1.p1.j;
00182 
00183         double dx2 = ls2.p2.i - ls1.p1.i;
00184         double dy2 = ls2.p2.j - ls1.p1.j;
00185 
00186         //If we intresected on a line then add both ends
00187         if ( (dx1*dx1 + dy1*dy1) > minDistSq) //p1 is further
00188           angles1.push_back(atan2(dx1, dy1) + M_PI/2);
00189 
00190         if ( (dx2*dx2 + dy2*dy2) > minDistSq) //p2 is further
00191           angles1.push_back(atan2(dx2, dy2) + M_PI/2);
00192       }
00193 
00194 
00195       //Do the same for p2 in line segment i
00196       if (ls1.p2.distanceToSegment(ls2.p1, ls2.p2) < minDist)
00197       {
00198         double dx1 = ls2.p1.i - ls1.p2.i;
00199         double dy1 = ls2.p1.j - ls1.p2.j;
00200 
00201         double dx2 = ls2.p2.i - ls1.p2.i;
00202         double dy2 = ls2.p2.j - ls1.p2.j;
00203 
00204         //If we intresected on a line then add both ends
00205         if ( (dx1*dx1 + dy1*dy1) > minDistSq) //p1 is further
00206           angles2.push_back(atan2(dx1, dy1) + M_PI/2);
00207 
00208         if ( (dx2*dx2 + dy2*dy2) > minDistSq) //p2 is further
00209           angles2.push_back(atan2(dx2, dy2) + M_PI/2);
00210         
00211       }
00212     }
00213 
00214     //Add the two corners
00215 
00216     CornerState c1;
00217     c1.center = ls1.p1;
00218     c1.angles = angles1;
00219     corners.push_back(c1);
00220 
00221     CornerState c2;
00222     c2.center = ls1.p2;
00223     c2.angles = angles2;
00224     corners.push_back(c2);
00225 
00226 
00227 
00228   }
00229 
00230 
00231   return corners;
00232 
00233 }
00234 
00235 // ######################################################################
00236 void CornersFeatures::evolve(SimEventQueue& q)
00237 {
00238 
00239   //Find corners from lines end points;
00240 
00241 
00242   std::vector<CornerState> corners = getCorners(itsLines);
00243 
00244   itsCorners = corners;
00245 
00246   //Add to corners db
00247   ////////////////////////////////////////
00248 
00249   //for(uint i=0; i<corners.size(); i++)
00250   //{
00251   //  CornerState& cs = corners[i];
00252   //  //Find the nearest corner in the db
00253   //  // and update the prob
00254   //  //
00255   //  std::vector<GaussianDef> gmmF;
00256   //  double weight = 1.0/double(cs.angles.size()); //equal weight
00257   //  for(uint i=0; i<cs.angles.size(); i++)
00258   //    gmmF.push_back(GaussianDef(weight, cs.angles[i], 1*M_PI/180)); //1 deg variance
00259 
00260   //  bool found = false;
00261   //  for(uint j=0; j<itsCornersDB.size(); j++)
00262   //  {
00263   //    CornerState& dbcs = itsCornersDB[j];
00264 
00265   //    std::vector<GaussianDef> gmmG;
00266   //    double weight = 1.0/double(dbcs.angles.size()); //equal weight
00267   //    for(uint i=0; i<dbcs.angles.size(); i++)
00268   //      gmmG.push_back(GaussianDef(weight, dbcs.angles[i], 1*M_PI/180)); //1 deg variance
00269 
00270   //    double dist = L2GMM(gmmF, gmmG);
00271 
00272   //    if (dist < 2)
00273   //    {
00274   //      //Found it
00275   //      dbcs.prob++;
00276   //      found = true;
00277   //      break;
00278   //    }
00279 
00280   //  }
00281 
00282   //  if (!found)
00283   //    itsCornersDB.push_back(cs); //add it to the db
00284   //}
00285 
00286 
00287   ////Write out the corners db
00288   //FILE *fp = fopen("corners.dat", "w");
00289 
00290   //for(uint i=0; i<itsCornersDB.size(); i++)
00291   //{
00292   //  CornerState& dbcs = itsCornersDB[i];
00293   //  for(uint j=0; j<dbcs.angles.size(); j++)
00294   //    fprintf(fp," %f", dbcs.angles[j]);
00295   //  fprintf(fp," %f\n", dbcs.prob);
00296   //}
00297   //fclose(fp);
00298 
00299 
00300 
00301 
00302   ////////////////////////////////////////
00303 
00304   //Sample from the cor
00305   //Image<float> tmp=itsCornersProposals;
00306   //inplaceNormalize(itsCornersProposals, 0.0F, 100.0F);
00307 
00308   //inplaceNormalize(itsEdges, 0.0F, 255.0F);
00309 
00310   //itsCorners.clear();
00311 
00312   //int radius = 10;
00313   //for(int i=0; i<20; i++)
00314   //{
00315   //  Point2D<int> maxLoc; float maxVal;
00316   //  findMax(tmp, maxLoc, maxVal);
00317 
00318   //  Point2D<int> tl(maxLoc.i-(itsPatchSize.w()/2), maxLoc.j-(itsPatchSize.h()/2));
00319 
00320   //  if (itsEdges.coordsOk(tl) &&
00321   //      itsEdges.coordsOk(tl.i+itsPatchSize.w(), tl.j+itsPatchSize.h()))
00322   //  {
00323   //    Image<float> patch = crop(itsEdges, tl, itsPatchSize);
00324 
00325   //    itsSOFM->setInput(patch);
00326   //    itsSOFM->Propagate();
00327 
00328   //    double winnerVal;
00329   //    Point2D<int> winnerId = itsSOFM->getWinner(winnerVal);
00330   //    //LINFO("WinnerVal %e\n", winnerVal);
00331 
00332 
00333   //    Image<float> learnedPatch(patch.getDims(), NO_INIT);
00334   //    std::vector<float> weights = itsSOFM->getWeights(winnerId);
00335   //    for(uint i=0; i<weights.size(); i++)
00336   //      learnedPatch[i] = weights[i];
00337 
00338   //    //Only organize if we have not learned this patch
00339   //    //if (winnerVal > 1)
00340   //    //  itsSOFM->organize(patch);
00341 
00342   //    CornerState cs;
00343   //    cs.id = winnerId;
00344   //    cs.patch = patch;
00345   //    cs.learnedPatch = learnedPatch;
00346   //    cs.loc = maxLoc;
00347   //    cs.prob = 0;
00348   //    itsCorners.push_back(cs);
00349   //  }
00350   //  //Apply IOR
00351   //  drawDisk(tmp, maxLoc, radius, 0.0f);
00352   //}
00353 
00354   //itsSOFMMap = itsSOFM->getWeightsImage();
00355 
00356   //itsSOFM->WriteNet("SOFM.net");
00357 
00358 }
00359 
00360 
00361 Layout<PixRGB<byte> > CornersFeatures::getDebugImage(SimEventQueue& q)
00362 {
00363   Layout<PixRGB<byte> > outDisp;
00364 
00365   Image<PixRGB<byte> > cornersImg(320, 240, ZEROS);
00366   for(uint i=0; i<itsCorners.size(); i++)
00367   {
00368     for(uint ai=0; ai<itsCorners[i].angles.size(); ai++)
00369     {
00370       int x1 = int(cos(itsCorners[i].angles[ai])*30.0/2.0);
00371       int y1 = int(sin(itsCorners[i].angles[ai])*30.0/2.0);
00372       Point2D<float> p1(itsCorners[i].center.i-x1, itsCorners[i].center.j+y1);
00373 
00374       drawLine(cornersImg, Point2D<int>(itsCorners[i].center), Point2D<int>(p1), PixRGB<byte>(0,255,0));
00375     }
00376   }
00377 
00378   outDisp = cornersImg; 
00379 
00380   return outDisp;
00381 
00382 }
00383 
00384 // ######################################################################
00385 /* So things look consistent in everyone's emacs... */
00386 /* Local Variables: */
00387 /* indent-tabs-mode: nil */
00388 /* End: */
00389 
00390 #endif
00391 
Generated on Sun May 8 08:05:31 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3