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 //