trainHough.C

Go to the documentation of this file.
00001 /*! @file SceneUnderstanding/trainHough.C train the hough transform */
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/trainHough.C $
00035 // $Id: trainHough.C 13765 2010-08-06 18:56:17Z lior $
00036 //
00037 
00038 //#include "Image/OpenCVUtil.H"  // must be first to avoid conflicting defs of int64, uint64
00039 
00040 #include "Component/JobServerConfigurator.H"
00041 #include "Component/ModelManager.H"
00042 #include "Image/Image.H"
00043 #include "Image/Pixels.H"
00044 #include "Image/DrawOps.H"
00045 #include "Image/MatrixOps.H"
00046 #include "Image/Point2D.H"
00047 #include "Media/SimFrameSeries.H"
00048 #include "Neuro/NeuroOpts.H"
00049 #include "Raster/Raster.H"
00050 #include "Simulation/SimEventQueueConfigurator.H"
00051 #include "Simulation/SimEventQueue.H"
00052 #include "Util/AllocAux.H"
00053 #include "Util/Pause.H"
00054 #include "Util/Types.H"
00055 #include "Util/csignals.H"
00056 #include "Util/log.H"
00057 #include "Util/sformat.H"
00058 #include "rutz/trace.h"
00059 #include "plugins/SceneUnderstanding/Geons3D.H"
00060 #include "plugins/SceneUnderstanding/SMap.H"
00061 #include "plugins/SceneUnderstanding/CornersFeatures.H"
00062 #include "plugins/SceneUnderstanding/V2.H"
00063 #include "GUI/DebugWin.H"
00064 #include "GUI/ViewPort3D.H"
00065 #include "Component/ModelManager.H"
00066 #include "Raster/GenericFrame.H"
00067 #include "Media/FrameSeries.H"
00068 #include "Transport/FrameInfo.H"
00069 #include "GUI/XWinManaged.H"
00070 #include "GUI/ImageDisplayStream.H"
00071 
00072 #include <signal.h>
00073 #include <sys/types.h>
00074 
00075 std::vector<CornersFeatures::CornerState> getCorners(std::vector<V2::LineSegment>& lines)
00076 {
00077   std::vector<CornersFeatures::CornerState> corners;
00078   float minDist = 5;
00079   float minDistSq = minDist*minDist;
00080 
00081   //Image<float> edges(320, 240, ZEROS);
00082   //for(uint i=0; i<lines.size(); i++)
00083   //{
00084   //  V2::LineSegment& ls1 = itsLines[i];
00085   //  drawLine(edges, Point2D<int>(ls1.p1), Point2D<int>(ls1.p2), 255.0F);
00086   //}
00087 
00088 
00089   for(uint i=0; i<lines.size(); i++)
00090   {
00091     V2::LineSegment& ls1 = lines[i];
00092 
00093     //Image<PixRGB<byte> > tmp(320,240,ZEROS); // = edges;
00094     //drawLine(tmp, Point2D<int>(ls1.p1), Point2D<int>(ls1.p2), PixRGB<byte>(255,0,0));
00095 
00096     std::vector<float> angles1; //The angles from p1 prospective
00097     std::vector<float> angles2; //the angles from p2 prospective
00098     double dx = ls1.p2.i - ls1.p1.i;
00099     double dy = ls1.p2.j - ls1.p1.j;
00100     double ang = atan2(dx, dy) + M_PI/2;
00101     angles1.push_back(ang);
00102     angles2.push_back(ang+M_PI);
00103 
00104     for(uint j=i+1; j<lines.size(); j++)
00105     {
00106       if (i == j)
00107         continue;
00108       V2::LineSegment& ls2 = lines[j];
00109 
00110       //Find if line segment i p1 intesect line segment j, and find the angle betwwen this
00111       //point and the reset of the ends
00112       if (ls1.p1.distanceToSegment(ls2.p1, ls2.p2) < minDist)
00113       {
00114         double dx1 = ls2.p1.i - ls1.p1.i;
00115         double dy1 = ls2.p1.j - ls1.p1.j;
00116 
00117         double dx2 = ls2.p2.i - ls1.p1.i;
00118         double dy2 = ls2.p2.j - ls1.p1.j;
00119 
00120         //If we intresected on a line then add both ends
00121         if ( (dx1*dx1 + dy1*dy1) > minDistSq) //p1 is further
00122           angles1.push_back(atan2(dx1, dy1) + M_PI/2);
00123 
00124         if ( (dx2*dx2 + dy2*dy2) > minDistSq) //p2 is further
00125           angles1.push_back(atan2(dx2, dy2) + M_PI/2);
00126       }
00127 
00128 
00129       //Do the same for p2 in line segment i
00130       if (ls1.p2.distanceToSegment(ls2.p1, ls2.p2) < minDist)
00131       {
00132         double dx1 = ls2.p1.i - ls1.p2.i;
00133         double dy1 = ls2.p1.j - ls1.p2.j;
00134 
00135         double dx2 = ls2.p2.i - ls1.p2.i;
00136         double dy2 = ls2.p2.j - ls1.p2.j;
00137 
00138         //If we intresected on a line then add both ends
00139         if ( (dx1*dx1 + dy1*dy1) > minDistSq) //p1 is further
00140           angles2.push_back(atan2(dx1, dy1) + M_PI/2);
00141 
00142         if ( (dx2*dx2 + dy2*dy2) > minDistSq) //p2 is further
00143           angles2.push_back(atan2(dx2, dy2) + M_PI/2);
00144         
00145       }
00146     }
00147 
00148     //Add the two corners
00149 
00150     CornersFeatures::CornerState c1;
00151     c1.center = ls1.p1;
00152     c1.angles = angles1;
00153     corners.push_back(c1);
00154 
00155     CornersFeatures::CornerState c2;
00156     c2.center = ls1.p2;
00157     c2.angles = angles2;
00158     corners.push_back(c2);
00159 
00160   }
00161   //SHOWIMG(tmp);
00162 
00163   //for(uint i=0; i<corners.size(); i++)
00164   //{
00165   //  Image<PixRGB<byte> > tmp(320, 240, ZEROS);
00166   //  for(uint ai=0; ai<corners[i].angles.size(); ai++)
00167   //  {
00168   //    int x1 = int(cos(corners[i].angles[ai])*30.0/2.0);
00169   //    int y1 = int(sin(corners[i].angles[ai])*30.0/2.0);
00170   //    Point2D<float> p1(corners[i].center.i-x1, corners[i].center.j+y1);
00171 
00172   //    drawLine(tmp, Point2D<int>(corners[i].center), Point2D<int>(p1), PixRGB<byte>(0,255,0));
00173   //  }
00174   //  SHOWIMG(tmp);
00175   //}
00176 
00177 
00178   return corners;
00179 
00180 }
00181 
00182 
00183 std::vector<V2::LineSegment> getLineSegments(ViewPort3D& vp, 
00184     Point3D<float>& objPos, Point3D<float>& objRot, Geons3D::GeonType type)
00185 {
00186   vp.setWireframeMode(false);
00187   vp.setLightsMode(true);
00188   vp.setFeedbackMode(false);
00189 
00190   vp.initFrame();
00191 
00192   switch(type)
00193   {
00194     case Geons3D::BOX:
00195       {
00196         vp.drawBox(
00197             objPos,
00198             objRot,
00199             Point3D<float>(30,30,30),
00200             PixRGB<byte>(0,256,0));
00201       }
00202       break;
00203     case Geons3D::SPHERE:
00204       break;
00205     case Geons3D::CYLINDER:
00206         vp.drawCylinder(
00207             objPos,
00208             objRot,
00209             15, 32.5,
00210             PixRGB<byte>(0,256,0));
00211       break;
00212 
00213   }
00214 
00215   Image<PixRGB<byte> > frame =  flipVertic(vp.getFrame());
00216   Image<float> surface = luminance(frame);
00217 
00218   Image<float> edgesMag, edgesOri;
00219   gradientSobel(surface, edgesMag, edgesOri);
00220 
00221   vp.setWireframeMode(true);
00222   vp.setLightsMode(false);
00223   vp.setFeedbackMode(true);
00224 
00225   vp.initFrame();
00226 
00227   switch(type)
00228   {
00229     case Geons3D::BOX:
00230       {
00231         vp.drawBox(
00232             objPos,
00233             objRot,
00234             Point3D<float>(30,30,30),
00235             PixRGB<byte>(0,256,0));
00236       }
00237       break;
00238     case Geons3D::SPHERE:
00239       break;
00240     case Geons3D::CYLINDER:
00241         vp.drawCylinder(
00242             objPos,
00243             objRot,
00244             15, 32.5,
00245             PixRGB<byte>(0,256,0));
00246       break;
00247 
00248   }
00249 
00250   std::vector<ViewPort3D::Line> lines = vp.getFrameLines();
00251 
00252   Image<float> mag(vp.getDims(),ZEROS);
00253   Image<float> ori(vp.getDims(),ZEROS);
00254   
00255   inplaceNormalize(edgesMag, 0.0F, 100.0F);
00256   std::vector<V2::LineSegment> lineSegments;
00257   for(uint i=0; i<lines.size(); i++)
00258   {
00259 
00260     double dx = lines[i].p2.i - lines[i].p1.i;
00261     double dy = lines[i].p2.j - lines[i].p1.j;
00262     double ang = atan2(dx,dy) + M_PI/2;
00263     //Change orientation from 0 to M_PI
00264     if (ang < 0) ang += M_PI;
00265     if (ang >= M_PI) ang -= M_PI;
00266 
00267     //Get the center of the line
00268     Point2D<float> center = lines[i].p1 + Point2D<float>(dx/2,dy/2); 
00269 
00270     if (edgesMag.coordsOk(Point2D<int>(lines[i].p1)) &&
00271         edgesMag.coordsOk(Point2D<int>(lines[i].p2)) &&
00272         edgesMag.getVal(Point2D<int>(lines[i].p1)) > 10 &&
00273         edgesMag.getVal(Point2D<int>(lines[i].p2)) > 10 &&
00274         edgesMag.getVal(Point2D<int>(center)) > 10)
00275     {
00276       double length = sqrt(dx*dx + dy*dy);
00277 
00278       V2::LineSegment ls;
00279       ls.p1 = lines[i].p1;
00280       ls.p2 = lines[i].p2;
00281       ls.length = length;
00282       ls.ori = ang;
00283       ls.center = center;
00284 
00285       lineSegments.push_back(ls);
00286     }
00287   }
00288   
00289   return lineSegments;
00290 
00291 }
00292 
00293 Image<float> getSmap(ViewPort3D& vp, std::vector<V2::LineSegment>& lines)
00294 {
00295 
00296   Image<float> smap(vp.getDims(), ZEROS);
00297 
00298   if (lines.size() <= 0)
00299     return smap;
00300   
00301   //Calculate the bounding box and center
00302   Point2D<int> center(0,0);
00303   Point2D<int> tl(0,0);
00304   Point2D<int> br(vp.getDims().w(),vp.getDims().h());
00305 
00306   for(uint i=0; i<lines.size(); i++)
00307   {
00308     center.i += int(lines[i].center.i);
00309     center.j += int(lines[i].center.j);
00310 
00311     if (lines[i].p1 > tl)
00312       tl = (Point2D<int>)lines[i].p1;
00313     if (lines[i].p2 > tl)
00314       tl = (Point2D<int>)lines[i].p2;
00315 
00316     if (lines[i].p1 < br)
00317       tl = (Point2D<int>)lines[i].p1;
00318     if (lines[i].p2 > tl)
00319       tl = (Point2D<int>)lines[i].p2;
00320 
00321   //  drawLine(smap, (Point2D<int>)lines[i].p1, (Point2D<int>)lines[i].p2, 255.0F);
00322   }
00323   center /= lines.size();
00324 
00325   drawDisk(smap, center, 3, 255.0F);
00326  // drawCircle(smap, tl, 3, 255.0F);
00327  // drawCircle(smap, br, 3, 255.0F);
00328 
00329   return smap;
00330 
00331 }
00332 
00333 
00334 
00335 int main(const int argc, const char **argv)
00336 {
00337 
00338   MYLOGVERB = LOG_INFO;
00339   ModelManager manager("Train Hough");
00340 
00341   nub::ref<SimEventQueueConfigurator>
00342     seqc(new SimEventQueueConfigurator(manager));
00343   manager.addSubComponent(seqc);
00344 
00345   nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00346   manager.addSubComponent(ofs);
00347 
00348   nub::ref<Geons3D> geons3D(new Geons3D(manager));
00349   manager.addSubComponent(geons3D);
00350   
00351   // Request a bunch of option aliases (shortcuts to lists of options):
00352   REQUEST_OPTIONALIAS_NEURO(manager);
00353   
00354 
00355   if (manager.parseCommandLine(
00356         (const int)argc, (const char**)argv, "", 0, 0) == false)
00357     return 1;
00358 
00359   nub::ref<SimEventQueue> seq = seqc->getQ();
00360   
00361   manager.start();
00362 
00363   GHough ghough;
00364 
00365 
00366   ViewPort3D vp(320,240, true, false, true);
00367   //double trans[3][4] = {
00368   //  {-0.996624, 0.070027, 0.042869, -16.907477},
00369   //  {-0.004359, 0.476245, -0.879302, 9.913470},
00370   //  {-0.081990, -0.876520, -0.474332, 276.648010}};
00371 
00372   double trans[3][4] = {
00373     {-0.999143, -0.041185, -0.004131, -1.142130},
00374     {-0.017002, 0.499358, -0.866229, 17.284269},
00375     {0.037739, -0.865416, -0.499630, 220.977236}};
00376   
00377   vp.setCamera(trans);
00378 
00379   Point3D<float> objPos(0,0,16/2);
00380   Point3D<float> objRot(0,0,0);
00381 
00382 
00383   // temporary, for debugging...
00384   seq->printCallbacks();
00385 
00386   PauseWaiter p;
00387   //int retval = 0;
00388   SimStatus status = SIM_CONTINUE;
00389 
00390   for(int obj=0; obj<3; obj++)
00391   for(float x=-150; x<150; x+=5)
00392     for(float y=40; y>-150; y-=5)
00393       for(float z=0; z<90; z+=5)
00394       {
00395 
00396         int objType = 0;
00397 
00398         switch (obj)
00399         {
00400           case 0:
00401             objType = 0;
00402             objPos.x = x;
00403             objPos.y = y;
00404             objRot.z = z;
00405             break;
00406           case 1:
00407             objType = 1;
00408             objPos.x = x;
00409             objPos.y = y;
00410             objRot.z = 0;
00411             z+= 90; //No rotation for object 1
00412             break;
00413           case 2:
00414             objType = 1;
00415             objPos.x = x;
00416             objPos.y = y;
00417 
00418             objRot.x = 90;
00419             objRot.y = z;
00420             objRot.z = 0;
00421             break;
00422         }
00423 
00424         //float x = 26.80;
00425         //float y = -44.90;
00426         //float z = 52;
00427         printf("%i %f %f %f\n",obj, x, y, z);
00428 
00429 
00430         std::vector<V2::LineSegment> lines = getLineSegments(vp, objPos, objRot, (Geons3D::GeonType)objType);
00431 
00432         std::vector<CornersFeatures::CornerState> corners = getCorners(lines);
00433 
00434 
00435         //for(uint i=0; i<corners.size(); i++)
00436         //{
00437         //  Image<PixRGB<byte> > tmp(320, 240, ZEROS);
00438         //  for(uint ai=0; ai<corners[i].angles.size(); ai++)
00439         //  {
00440         //    int x1 = int(cos(corners[i].angles[ai])*30.0/2.0);
00441         //    int y1 = int(sin(corners[i].angles[ai])*30.0/2.0);
00442         //    Point2D<float> p1(corners[i].center.i-x1, corners[i].center.j+y1);
00443 
00444         //    drawLine(tmp, Point2D<int>(corners[i].center), Point2D<int>(p1), PixRGB<byte>(0,255,0));
00445         //  }
00446         //  SHOWIMG(tmp);
00447         //}
00448         
00449 
00450 
00451         //Send an SMap
00452         Image<byte> smap = getSmap(vp, lines);
00453         std::vector<SMap::SMapState> smapState;
00454         seq->post(rutz::make_shared(new SimEventSMapOutput(geons3D.get(), smapState, smap)));
00455 
00456         //Send Corners
00457         seq->post(rutz::make_shared(new SimEventCornersOutput(geons3D.get(), corners)));
00458 
00459         //Send metadata
00460         //rutz::shared_ptr<GenericFrame::MetaData> metaData;
00461         rutz::shared_ptr<World3DInput::ObjectsData> objectsData(new World3DInput::ObjectsData);
00462         Point3D<float> color(1,1,1);
00463         Point3D<float> params(30,30,30);
00464         objectsData->objects.push_back(
00465             World3DInput::Object(World3DInput::Object::ObjectType(objType),
00466               objPos, objRot, color, params));
00467         ImageSet<float> cells;
00468         rutz::shared_ptr<GenericFrame::MetaData> metaData = objectsData;
00469         seq->post(rutz::make_shared(new SimEventLGNOutput(geons3D.get(), cells, metaData)));
00470         seq->post(rutz::make_shared(new SimEventV2Output(geons3D.get(), lines, vp.getDims())));
00471 
00472         // Evolve for one time step and switch to the next one:
00473         status = seq->evolve();
00474  
00475         Layout<PixRGB<byte> > disp = geons3D->getDebugImage(*seq);
00476         ofs->writeRgbLayout(disp, "Geons3D", FrameInfo("Geons3D", SRC_POS));
00477         
00478 
00479       }
00480 
00481 
00482   manager.stop();
00483 
00484   return 0;
00485 }
00486 
Generated on Sun May 8 08:41:09 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3