V2.H

Go to the documentation of this file.
00001 /*!@file plugins/SceneUnderstanding/V2.H  */
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/V2.H $
00035 // $Id: V2.H 14683 2011-04-05 01:30:59Z lior $
00036 //
00037 
00038 #ifndef V2_H_DEFINED
00039 #define V2_H_DEFINED
00040 
00041 //#include "Image/OpenCVUtil.H"  // must be first to avoid conflicting defs of int64, uint64
00042 
00043 #include "Image/Image.H"
00044 #include "Image/ImageSet.H"
00045 #include "Image/Pixels.H"
00046 #include "Image/Layout.H"
00047 #include "Image/TensorOps.H"
00048 #include "plugins/SceneUnderstanding/V1.H"
00049 #include "plugins/SceneUnderstanding/TensorVoting.H"
00050 #include "Simulation/SimEvents.H"
00051 #include "Simulation/SimModule.H"
00052 #include "Util/WorkThreadServer.H"
00053 #include <float.h>
00054 
00055 //#include "Image/OpenCVUtil.H"
00056 
00057 #include <limits>
00058 #include <vector>
00059 #include <string>
00060 #include <stack>
00061 #include <list>
00062 
00063 #define NOTDEF   -1000.0
00064 #define BIG_NUMBER 1.0e+300
00065 #define M_3_2_PI 4.71238898038
00066 #define M_2__PI  6.28318530718
00067 #define NOTUSED 0
00068 #define USED    1
00069 #define NOTINI  2
00070 
00071 #define MY_ROUND(f) ( (float) floor( (double) (f) + 0.5 ) )
00072 
00073 struct NFAInfo
00074 {
00075   short int ori;
00076   short int xLoc;
00077   short int yLoc;
00078   short int length;
00079   short int pts;
00080   short int alg;
00081 };
00082 
00083 struct NumEntries
00084   {
00085     size_t num;
00086     short int pts;
00087     NumEntries() : num(0), pts(0) {}
00088 
00089   };
00090 
00091 //A PDF width 4 params
00092 typedef std::map<short int, //ori
00093         std::map<short int, //xLoc
00094         std::map<short int, //yLoc,
00095         std::map<short int, //length, 
00096         std::map<short int, //alg, 
00097         NumEntries > > > > > NFAPDFMap;
00098 
00099 
00100 
00101 class Rect
00102 {
00103 
00104   public:
00105 
00106   Rect(const Point2D<int>& center, Dims& d, float ori) :
00107     itsCenter(center),
00108     itsSize(d),
00109     itsOri(ori)
00110   {
00111     float distX = itsSize.w()/2;
00112     float distY = itsSize.h()/2;
00113     float radius = sqrt((distX*distX) + (distY*distY));
00114 
00115     float thetaO = atan(distX/distY);
00116     float thetaN1 = thetaO + itsOri;
00117     float thetaN2 = itsOri - thetaO;
00118     float Xnew1 = radius*sin(thetaN1);
00119     float Ynew1 = radius*cos(thetaN1);
00120     float Xnew2 = radius*sin(thetaN2);
00121     float Ynew2 = radius*cos(thetaN2);
00122 
00123     itsP1 = Point2D<int>(itsCenter.i+Xnew1, itsCenter.j+Ynew1);
00124     itsP2 = Point2D<int>(itsCenter.i+Xnew2, itsCenter.j+Ynew2);
00125     itsP3 = Point2D<int>(itsCenter.i-Xnew1, itsCenter.j-Ynew1);
00126     itsP4 = Point2D<int>(itsCenter.i-Xnew2, itsCenter.j-Ynew2);
00127 
00128     itsPolygon.clear();
00129     itsPolygon.push_back(itsP1); itsPolygon.push_back(itsP2);
00130     itsPolygon.push_back(itsP3); itsPolygon.push_back(itsP4);
00131   }
00132 
00133   void initIter()
00134   {
00135     itsEdgeCount = itsPolygon.size();
00136     itsNum = itsPolygon.size();
00137     itsMinY = itsPolygon[0].j; 
00138     itsStartV1 = 0;
00139     for(uint c= 1; c < itsPolygon.size(); c++) //Find Top Vertex
00140     {
00141       if (itsPolygon[c].j < itsMinY)
00142       {
00143         itsMinY = itsPolygon[c].j;
00144         itsStartV1 = c;
00145       }
00146     }
00147     itsStartV2 = itsStartV1;
00148     itsEndV1 = itsStartV1 - 1;
00149     if(itsEndV1 < 0) itsEndV1 = (itsNum-1);
00150 
00151     itsEndV2 = itsStartV2 + 1;
00152     if (itsEndV2 >= itsNum) itsEndV2 = 0;
00153     itsMinY = itsPolygon[itsStartV1].j;
00154 
00155     int x1 = itsPolygon[itsStartV1].i; int y1 = itsPolygon[itsStartV1].j;
00156     int x2 = itsPolygon[itsEndV1].i; int y2 = itsPolygon[itsEndV1].j;
00157 
00158     itsDx1 = ((x2 - x1) << 8) / (y2 - y1 + 1);
00159     itsCount1 = y2-y1;
00160     itsXVal1 = x1 << 8;
00161 
00162     int x11 = itsPolygon[itsStartV2].i; int y11 = itsPolygon[itsStartV2].j;
00163     int x22 = itsPolygon[itsEndV2].i; int y22 = itsPolygon[itsEndV2].j;
00164 
00165     itsDx2 = ((x22 - x11) << 8) / (y22 - y11 + 1);
00166     itsCount2 = y22-y11;
00167     itsXVal2 = x11 << 8;
00168   }
00169 
00170   bool iterEnd()
00171   {
00172     if (itsEdgeCount > 1)
00173       return false;
00174     else
00175       return true;
00176   }
00177 
00178   void incIter(int& x1, int& x2, int& y)
00179   {
00180     if (itsEdgeCount > 1)
00181     {
00182       while( itsEdgeCount > 1 && (itsCount1 == 0 || itsCount2 == 0) )
00183       {
00184         if (itsCount1 == 0)
00185         {
00186           itsEdgeCount--;
00187           itsStartV1 = itsEndV1;
00188           itsEndV1--;
00189           if (itsEndV1 < 0) itsEndV1 = itsNum-1;
00190 
00191           itsMinY = itsPolygon[itsStartV1].j;
00192           int x1 = itsPolygon[itsStartV1].i, y1 = itsPolygon[itsStartV1].j;
00193           int x2 = itsPolygon[itsEndV1].i, y2 = itsPolygon[itsEndV1].j;
00194           itsDx1 = ((x2 - x1) << 8) / (abs(y2 - y1) + 1);
00195           itsCount1 = y2-y1;
00196           itsXVal1 = x1 << 8;
00197         }
00198         if (itsCount2 == 0)
00199         {
00200           itsEdgeCount--;
00201           itsStartV2 = itsEndV2;
00202           itsEndV2++;
00203           if(itsEndV2 >= itsNum) itsEndV2 = 0;
00204           itsMinY = itsPolygon[itsStartV2].j;
00205           int x11 = itsPolygon[itsStartV2].i, y11 = itsPolygon[itsStartV2].j;
00206           int x22 = itsPolygon[itsEndV2].i, y22 = itsPolygon[itsEndV2].j;
00207           itsDx2 = ((x22 - x11) << 8) / (abs(y22 - y11) + 1);
00208           itsCount2 = y22-y11;
00209           itsXVal2 = x11 << 8;
00210         }
00211       }
00212       if ( (itsCount1 > 0) &&  (itsCount2 > 0) )
00213       {
00214         x1 = itsXVal1 >> 8;
00215         x2 = itsXVal2 >> 8;
00216         y = itsMinY;
00217 
00218         itsXVal1 += itsDx1; itsXVal2 += itsDx2;
00219         itsCount1--; itsCount2--;
00220         itsMinY++;
00221       }
00222     }
00223 
00224   }
00225 
00226   std::vector<Point2D<int> > getPolygon() { return itsPolygon; }
00227 
00228 
00229 
00230   private:
00231     Point2D<int> itsCenter;
00232     Dims itsSize;
00233     float itsOri;
00234 
00235     Point2D<int> itsP1;
00236     Point2D<int> itsP2;
00237     Point2D<int> itsP3;
00238     Point2D<int> itsP4;
00239 
00240 
00241     int itsEdgeCount;
00242     int itsNum;
00243     int itsMinY;
00244     int itsStartV1;
00245     int itsStartV2;
00246     int itsEndV1;
00247     int itsEndV2;
00248 
00249     int itsDx1;
00250     int itsCount1;
00251     int itsXVal1;
00252 
00253     int itsDx2;
00254     int itsCount2;
00255     int itsXVal2;
00256 
00257     std::vector<Point2D<int> > itsPolygon;
00258 };
00259 
00260 class V2 : public SimModule
00261 {
00262 public:
00263 
00264   struct CornerState
00265   {
00266     Point2D<float> pos;
00267     float ori;
00268     float ang;
00269     float var;
00270     float prob;
00271 
00272     int lineSeg1;
00273     int lineSeg2;
00274 
00275     Point2D<float> endPoint1;
00276     Point2D<float> endPoint2;
00277 
00278 
00279     CornerState() {}
00280     CornerState(Point2D<float> p, float o, float a) :
00281       pos(p), ori(o), ang(a)
00282     {}
00283 
00284     bool operator<(const CornerState& cornerState) const
00285     {
00286       return prob < cornerState.prob;
00287     }
00288 
00289   };
00290 
00291   struct SymmetryState
00292   {
00293     int lineSeg1;
00294     int lineSeg2;
00295     Point2D<float> center;
00296     float ang;
00297     float length;
00298   };
00299 
00300 
00301   /*----------------------------------------------------------------------------*/
00302   struct coorlist
00303   {
00304     int x,y;
00305     struct coorlist * next;
00306   };
00307 
00308   /*----------------------------------------------------------------------------*/
00309   struct point {int x,y;};
00310 
00311   /*----------------------------------------------------------------------------*/
00312   struct rect /* line segment with width */
00313   {
00314     float x1,y1,x2,y2;  /* first and second point of the line segment */
00315     float width;        /* rectangle width */
00316     float x,y;          /* center of the rectangle */
00317     float theta;        /* angle */
00318     float dx,dy;        /* vector with the line segment angle */
00319     float prec;         /* tolerance angle */
00320     double p;           /* probability of a point with angle within prec */
00321     float sum;          /* the sum of mag */
00322   };
00323 
00324   /*----------------------------------------------------------------------------*/
00325   /*
00326      rectangle points iterator
00327      */
00328   typedef struct
00329   {
00330     float vx[4];
00331     float vy[4];
00332     float ys,ye;
00333     int x,y;
00334   } rect_iter;
00335 
00336 
00337   struct LineSegment
00338   {
00339     Point2D<float> p1;
00340     Point2D<float> p2;
00341     float width;
00342     float length;
00343     float ori;
00344     int color;
00345     Point2D<float> center;
00346     std::vector<float> side1Color;
00347     std::vector<float> side2Color;
00348     float prob;
00349 
00350     float strength;
00351 
00352     LineSegment(Point2D<float> inP1, Point2D<float> inP2) :
00353       p1(inP1),
00354       p2(inP2)
00355     {}
00356 
00357     LineSegment() {}
00358 
00359     double distance(const LineSegment &line)
00360     {
00361       return center.distance(line.center);
00362     }
00363 
00364     double colorDist(const LineSegment &line)
00365     {
00366       float distColor1 = std::numeric_limits<float>::max();
00367       if (side1Color.size() == 3 && line.side1Color.size() == 3)
00368         distColor1 = sqrt( squareOf(side1Color[0] - line.side1Color[0]) +
00369                            squareOf(side1Color[1] - line.side1Color[1]) +
00370                            squareOf(side1Color[2] - line.side1Color[2]));
00371 
00372       float distColor2 = std::numeric_limits<float>::max();
00373       if (side2Color.size() == 3 && line.side2Color.size() == 3)
00374         distColor2 = sqrt( squareOf(side2Color[0] - line.side2Color[0]) +
00375                            squareOf(side2Color[1] - line.side2Color[1]) +
00376                            squareOf(side2Color[2] - line.side2Color[2]));
00377 
00378       return std::min(distColor2, distColor1);
00379     }
00380 
00381 
00382     LineSegment& operator=(const LineSegment& line)
00383     {
00384       //Assign the new specs for the line, but keep the strength the same
00385       p1 = line.p1;
00386       p2 = line.p2;
00387       width = line.width;
00388       length = line.length;
00389       ori = line.ori;
00390       center = line.center;
00391       side1Color = line.side1Color;
00392       side2Color = line.side2Color;
00393 
00394       return *this;
00395 
00396     }
00397 
00398   };
00399 
00400   struct ContourState
00401   {
00402     std::vector<LineSegment> lines;
00403   };
00404 
00405 
00406 
00407   V2(OptionManager& mgr, const std::string& descrName = "V2",
00408       const std::string& tagName = "V2");
00409 
00410   //! Destructor
00411   ~V2();
00412 
00413   void init(Dims numCells);
00414 
00415   void evolve(Image<PixRGB<byte> >& img);
00416   void evolve(Image<float>& img);
00417   void evolve(TensorField& tensorField);
00418   void evolve(SimEventQueue& q);
00419   void evolveLines();
00420   void evolveContours();
00421   void evolve2();
00422 
00423   Layout<PixRGB<byte> > getDebugImage();
00424 
00425   void findLines(const Image<float> &mag, const Image<float>& ori,
00426       Image<float>& retMag, Image<float>& retOri);
00427 
00428   int findMostProbableLine(const LineSegment& line, float &prob);
00429   std::vector<LineSegment> proposeLineSegments(ImageSet<float> &LGNInput); //Use the LGN raw input
00430   std::vector<LineSegment> proposeLineSegments(V1::EdgesState& edgesState); //use the V1 edges
00431 
00432   void trainNFA(V1::EdgesState& edgesState); //use the V1 edges
00433 
00434   std::vector<ContourState> proposeContours(std::vector<LineSegment>& lines);
00435 
00436 
00437   std::vector<LineSegment> findNerestLines(std::list<LineSegment>& lines,
00438       std::stack<Point2D<float> >& endPoints);
00439 
00440 
00441   void cornerSymetryDetection(std::vector<LineSegment>& lines);
00442 
00443   void evolveBorderOwner();
00444   std::vector<V2::ContourState> proposeContoursBO(std::vector<LineSegment>& lines);
00445 
00446 
00447   rect getRect(const Point2D<int> p1, const Point2D<int> p2,const int width);
00448   
00449 
00450 protected:
00451   //! Callback for when a new ganglion output is ready
00452   SIMCALLBACK_DECLARE(V2, SimEventV1Output);
00453 
00454   //! Callback for every time we should save our outputs
00455   SIMCALLBACK_DECLARE(V2, SimEventSaveOutput);
00456 
00457   //! Callback for every time we have a user event
00458   SIMCALLBACK_DECLARE(V2, SimEventUserInput);
00459 
00460   //! Should we show our debug info
00461   OModelParam<bool> itsShowDebug;
00462 
00463   //! Train the NFA
00464   OModelParam<bool> itsTrainNFA;
00465   OModelParam<std::string> itsTrainNFAFile;
00466 
00467 
00468   std::vector<LineSegment> itsLines;
00469   std::vector<ContourState> itsContours;
00470 
00471 
00472 public:
00473 /*
00474    compute the direction of the level line at each point.
00475    it returns:
00476 
00477    - an image_float with the angle at each pixel or NOTDEF.
00478    - the image_float 'modgrad' (a pointer is passed as argument)
00479      with the gradient magnitude at each point.
00480    - a list of pixels 'list_p' roughly ordered by gradient magnitude.
00481      (the order is made by classing points into bins by gradient magnitude.
00482       the parameters 'n_bins' and 'max_grad' specify the number of
00483       bins and the gradient modulus at the highest bin.)
00484    - a pointer 'mem_p' to the memory used by 'list_p' to be able to
00485      free the memory.
00486  */
00487 Image<float> ll_angle(Image<float>& in, float threshold,
00488                              std::vector<Point2D<int> > &list_p, void ** mem_p,
00489                              Image<float>& modgrad, int n_bins, int max_grad );
00490 Image<float> ll_angle(const TensorField& tensorField, float threshold,
00491                              std::vector<Point2D<int> > &list_p,
00492                              Image<float>& modgrad, int n_bins, int max_grad );
00493 
00494 #define RELATIVE_ERROR_FACTOR 100.0
00495 
00496 /*----------------------------------------------------------------------------*/
00497 /** Compare doubles by relative error.
00498 
00499     The resulting rounding error after floating point computations
00500     depend on the specific operations done. The same number computed by
00501     different algorithms could present different rounding errors. For a
00502     useful comparison, an estimation of the relative rounding error
00503     should be considered and compared to a factor times EPS. The factor
00504     should be related to the cumulated rounding error in the chain of
00505     computation. Here, as a simplification, a fixed factor is used.
00506  */
00507 static int double_equal(double a, double b)
00508 {
00509   double abs_diff,aa,bb,abs_max;
00510 
00511   /* trivial case */
00512   if( a == b ) return true;
00513 
00514   abs_diff = fabs(a-b);
00515   aa = fabs(a);
00516   bb = fabs(b);
00517   abs_max = aa > bb ? aa : bb;
00518 
00519   /* DBL_MIN is the smallest normalized number, thus, the smallest
00520      number whose relative error is bounded by DBL_EPSILON. For
00521      smaller numbers, the same quantization steps as for DBL_MIN
00522      are used. Then, for smaller numbers, a meaningful "relative"
00523      error should be computed by dividing the difference by DBL_MIN. */
00524   if( abs_max < DBL_MIN ) abs_max = DBL_MIN;
00525 
00526   /* equal if relative error <= factor x eps */
00527   return (abs_diff / abs_max) <= (RELATIVE_ERROR_FACTOR * DBL_EPSILON);
00528 }
00529 
00530 
00531 /*----------------------------------------------------------------------------*/
00532 /*
00533    find if the point x,y in angles have angle theta up to precision prec
00534  */
00535 bool isaligned(Point2D<int> loc,const  Image<float>& angles,
00536                float theta, float prec);
00537 float angle_diff(float a, float b);
00538 
00539 
00540 /*----------------------------------------------------------------------------*/
00541 /*----------------------------- NFA computation ------------------------------*/
00542 /*----------------------------------------------------------------------------*/
00543 
00544 /*----------------------------------------------------------------------------*/
00545 /*
00546    Calculates the natural logarithm of the absolute value of
00547    the gamma function of x using the Lanczos approximation,
00548    see http://www.rskey.org/gamma.htm.
00549 
00550    The formula used is
00551      \Gamma(x) = \frac{ \sum_{n=0}^{N} q_n x^n }{ \Pi_{n=0}^{N} (x+n) }
00552                  (x+5.5)^(x+0.5) e^{-(x+5.5)}
00553    so
00554      \log\Gamma(x) = \log( \sum_{n=0}^{N} q_n x^n ) + (x+0.5) \log(x+5.5)
00555                      - (x+5.5) - \sum_{n=0}^{N} \log(x+n)
00556    and
00557      q0 = 75122.6331530
00558      q1 = 80916.6278952
00559      q2 = 36308.2951477
00560      q3 = 8687.24529705
00561      q4 = 1168.92649479
00562      q5 = 83.8676043424
00563      q6 = 2.50662827511
00564  */
00565 double log_gamma_lanczos(double x);
00566 
00567 /*----------------------------------------------------------------------------*/
00568 /*
00569    Calculates the natural logarithm of the absolute value of
00570    the gamma function of x using Robert H. Windschitl method,
00571    see http://www.rskey.org/gamma.htm.
00572 
00573    The formula used is
00574      \Gamma(x) = \sqrt(\frac{2\pi}{x}) ( \frac{x}{e}
00575                    \sqrt{ x\sinh(1/x) + \frac{1}{810x^6} } )^x
00576    so
00577      \log\Gamma(x) = 0.5\log(2\pi) + (x-0.5)\log(x) - x
00578                      + 0.5x\log( x\sinh(1/x) + \frac{1}{810x^6} ).
00579 
00580    This formula is good approximation when x > 15.
00581  */
00582 double log_gamma_windschitl(double x);
00583 
00584 /*----------------------------------------------------------------------------*/
00585 /*
00586    Calculates the natural logarithm of the absolute value of
00587    the gamma function of x. When x>15 use log_gamma_windschitl(),
00588    otherwise use log_gamma_lanczos().
00589  */
00590 #define log_gamma(x) ((x)>15.0?log_gamma_windschitl(x):log_gamma_lanczos(x))
00591 
00592 /*----------------------------------------------------------------------------*/
00593 /*
00594    Computes the logarithm of NFA to base 10.
00595 
00596    NFA = NT.b(n,k,p)
00597    the return value is log10(NFA)
00598 
00599    n,k,p - binomial parameters.
00600    logNT - logarithm of Number of Tests
00601  */
00602 
00603 #define TABSIZE 100000
00604 double nfa(int n, int k, double p, double logNT);
00605 void rect_copy(struct rect * in, struct rect * out);
00606 float inter_low(float x, float x1, float y1, float x2, float y2);
00607 float inter_hi(float x, float x1, float y1, float x2, float y2);
00608 
00609 void ri_del(rect_iter * iter);
00610 int ri_end(rect_iter * i);
00611 void ri_inc(rect_iter * i);
00612 rect_iter * ri_ini(struct rect * r);
00613 
00614 int ri_end(rect_iter& itr);
00615 void ri_inc(rect_iter& itr);
00616 void ri_ini(struct rect * r, rect_iter& iter);
00617 
00618 
00619 double rect_nfa(struct rect * rec, Image<float>& angles, double logNT);
00620 float get_theta( struct point * reg, int reg_size, float x, float y,
00621                         Image<float>& modgrad, float reg_angle, float prec,
00622                         float * elongation );
00623 float region2rect( struct point * reg, int reg_size,
00624                           Image<float>& modgrad, float reg_angle,
00625                           float prec, double p, struct rect * rec,
00626                           float* sum_l, float* sum_w, int sum_offset, int sum_res);
00627 void region_grow(Point2D<int> loc, Image<float>& angles, struct point * reg,
00628                          int * reg_size, float * reg_angle, Image<byte>& used,
00629                          float prec, int radius,
00630                          Image<float> modgrad, double p, int min_reg_size );
00631 
00632 double rect_improve( struct rect * rec, Image<float>& angles,
00633                             double logNT, double eps );
00634 
00635 
00636 /* execute LSD */
00637 /* LSD parameters */
00638 //float q = 2.0;           /* Bound to the quantization error on the
00639 //                            gradient norm.                                 */
00640 //float d = 8.0;           /* Gradient angle tolerance, tau = 180 degree / d */
00641 //double eps = 0.0;        /* Detection threshold, -log10(NFA).              */
00642 //int n_bins = 16256;      /* Number of bins in pseudo-ordering of gradient
00643 //                            modulus. This default value is selected to work
00644 //                            well on images with gray levels in [0,255].    */
00645 //int max_grad = 260100;   /* Gradient modulus in the highest bin. The default
00646 //                            value corresponds to the highest gradient modulus
00647 //                            on images with gray levels in [0,255].         */
00648 //float scale = 1.0;       /* scale the image by Gaussian filter to 'scale'. */
00649 //float sigma_scale = 0.6; /* sigma used in Gaussian filter when scale!=1.0
00650 //                            sigma = sigma_scale/scale.                     */
00651 
00652 std::vector<LineSegment> lineSegmentDetection(Image<float>& img,
00653     float q = 2.0, float d = 8.0, double eps = 0.0,
00654     int n_bins = 16256, int max_grad = 260100,
00655     float scale = 1.0, float sigma_scale = 0.6 );
00656 
00657 std::vector<LineSegment> lineSegmentDetection(const TensorField& tensorField,
00658     float q = 2.0, float d = 20, double eps = 0.0,
00659     int n_bins = 16256, int max_grad = 260100);
00660 
00661 private:
00662   ImageSet<float>  itsLGNInput;
00663   std::vector<CornerState> itsCornersState;
00664   std::vector<SymmetryState> itsSymmetries;
00665   std::vector<TensorVoting> itsTensorFields;
00666   Image<float> itsEdges;
00667   Image<float> itsCornersProposal;
00668   V1::EdgesState itsV1EdgesState;
00669   bool itsLSDVerbose;
00670   TensorVoting itsLumTV;
00671   TensorVoting itsRGTV;
00672   TensorVoting itsBYTV;
00673   TensorField itsMaxTF;
00674   int itsFrameNum;
00675   std::string itsStoredFrames;
00676   float itsQuantError;
00677   float itsAngleTolerance;
00678   float itsEPS;
00679   
00680   rutz::shared_ptr<WorkThreadServer> itsThreadServer;
00681   std::vector<NFAPDFMap> itsPDF;
00682   std::vector<Point2D<int> > itsLocations;
00683 
00684 #ifdef HAVE_OPENCV
00685   //CvMemStorage* itsStorage;
00686 #endif
00687 
00688 };
00689 
00690 /* ############################### V2 sim events ######################## */
00691 class SimEventV2Output : public SimEvent
00692 {
00693 public:
00694   SimEventV2Output(SimModule* src,
00695       std::vector<V2::LineSegment>& lines,
00696       std::vector<V2::CornerState>& corners,
00697       Image<float>& cornersProposals,
00698       Image<float>& edges,
00699       std::vector<TensorVoting>& tensorFields,
00700       Dims dims) :
00701     SimEvent(src), itsLines(lines), itsCorners(corners),
00702     itsCornersProposals(cornersProposals), itsEdges(edges),
00703     itsTensorFields(tensorFields),
00704     itsDims(dims)
00705   {}
00706 
00707   SimEventV2Output(SimModule* src,
00708       std::vector<V2::LineSegment>& lines, Dims dims) :
00709     SimEvent(src), itsLines(lines), 
00710     itsCorners(std::vector<V2::CornerState>()),
00711     itsCornersProposals(Image<float>()),
00712     itsEdges(Image<float>()),
00713     itsDims(dims)
00714   {}
00715 
00716   virtual ~SimEventV2Output(){}
00717   std::vector<V2::LineSegment> getLines() { return itsLines; }
00718   std::vector<V2::CornerState> getCorners() { return itsCorners; }
00719   Image<float> getCornersProposals() { return itsCornersProposals; }
00720   Image<float> getEdges() { return itsEdges; }
00721   std::vector<TensorVoting> getTensorFields() { return itsTensorFields; }
00722   Dims getDims() { return itsDims; }
00723 
00724 private:
00725   const std::vector<V2::LineSegment>& itsLines;
00726   const std::vector<V2::CornerState>& itsCorners;
00727   const Image<float>& itsCornersProposals;
00728   const Image<float>& itsEdges;
00729   const std::vector<TensorVoting> itsTensorFields;
00730   const Dims itsDims;
00731 
00732 };
00733 
00734 // ######################################################################
00735 /* So things look consistent in everyone's emacs... */
00736 /* Local Variables: */
00737 /* indent-tabs-mode: nil */
00738 /* End: */
00739 
00740 #endif //
Generated on Sun May 8 08:05:32 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3