LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiFastEllipseExtraction.h

00001 /*
00002  * Copyright (C) 2004, 2005, 2006
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  * This file is part of the LTI-Computer Vision Library (LTI-Lib)
00006  *
00007  * The LTI-Lib is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License (LGPL)
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * The LTI-Lib is distributed in the hope that it will be
00013  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00014  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with the LTI-Lib; see the file LICENSE.  If
00019  * not, write to the Free Software Foundation, Inc., 59 Temple Place -
00020  * Suite 330, Boston, MA 02111-1307, USA.
00021  */
00022 
00023 
00024 /*--------------------------------------------------------------------
00025  * project ....: LTI-Lib: Image Processing and Computer Vision Library
00026  * file .......: ltiFastEllipseExtraction.h
00027  * authors ....: Ingo Grothues (ingo@isdevelop.de)
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 23.4.2004
00030  * revisions ..: $Id: ltiFastEllipseExtraction.h,v 1.8 2006/08/25 15:33:39 doerfler Exp $
00031  */
00032 
00033 #ifndef _LTI_FAST_ELLIPSE_EXTRACTION_H_
00034 #define _LTI_FAST_ELLIPSE_EXTRACTION_H_
00035 
00036 #include "ltiFeatureExtractor.h"
00037 #include "ltiPoint.h"
00038 #include <vector>
00039 
00040 namespace lti {
00041   
00042   /**
00043    * This functor implements a fast ellipse extraction
00044    * using the line segments found in digital images.
00045    * 
00046    * To achieve this, the lines of an image are extracted
00047    * by a fast line extraction. The edge lines of ellipses are
00048    * filtered by several checks. In further passes these lines 
00049    * are combined to arcs, adjacent arcs are combined to extended 
00050    * arcs which at last are used to extract ellipses.
00051    *
00052    * The fastEllipseExtraction::parameters specify several
00053    * ranges and conditions that the lines and arcs must fulfill.
00054    * The result strongly depends on these parameters,
00055    * especially the number and the precision of the 
00056    * extracted ellipses.
00057    *
00058    * The extracted arcs and ellipses are stored in STL vector
00059    * containers of the types <ellArcEntry>, <ellExtArcEntry> and 
00060    * <ellipseEntry>. They can be accessed by the methods 
00061    * getEllArcList(), getEllExtArcList and getEllipseList().
00062    *
00063    * \c ellArcEntry is the data struct for elliptic arcs:
00064    * <pre> struct ellArcEntry
00065    * {
00066    *   ipoint  start;    // start point                       
00067    *   ipoint  end;      // end point                         
00068    *   ipoint  mid;      // estimated circle midpoint         
00069    *   int     r2;       // estimated squared radius          
00070    *   ipoint  firstVec; // first line vector                 
00071    *   ipoint  lastVec;  // last line vector                  
00072    *   int     used;     // counts arc<->extarc assignments   
00073    *   int     group;    // base line group (1,2,3 or 4)      
00074    *   std::vector<int> *lineIdxList;  // base line index list
00075    * };</pre>                                                 
00076    *
00077    * \c ellExtArcEntry is the data struct for elliptic extended arcs:
00078    * <pre> struct ellExtArcEntry
00079    * {
00080    *   double  x,y;      // estimated ellipse center           
00081    *   double  a,b;      // estimated ellipse semi-axis        
00082    *   double  t;        // estimated ellipse orientation angle                  
00083    *   double  ix, iy;   // intersection point of end tangents 
00084    *   double  slopeLB;  // slope of line beam                 
00085    *   int     used;     // counts extarc<->ellipse assignments
00086    *   int     group;    // group of 2nd base arc                   
00087    *   int     arcIdx[3];// base arc indices                    
00088    * };</pre>
00089    *
00090    * \c ellipseEntry is the data struct for ellipses:
00091    * <pre>struct ellipseEntry
00092    * {
00093    *   double  x,y;      // estimated ellipse center   
00094    *   double  a,b;      // estimated ellipse semi-axis
00095    *   double  t;        // estimated ellipse orientation angle
00096    *   double  coverage; // ellipse coverage (accuracy 
00097    *   std::vector<int> *mergedArcs;  // arc index list
00098    * };</pre>
00099    *
00100    * The fast ellipse extraction does not perform any changes
00101    * to the analyzed image. To visualize the extracted ellipses
00102    * they have to be drawn by other code using the
00103    * ellipse lists and a drawing functor.
00104    *
00105    *
00106    * Example:
00107    * \code
00108    *
00109    * #include "ltiViewer.h"                // visualization tool
00110    * #include "ltiDraw.h"                  // drawing tool
00111    * #include "ltiALLfunctor.h"            // image loader
00112    * #include "ltiCannyEdges.h"            // edge detector
00113    * #include "ltiFastEllipseExtraction.h" // ellipse detector
00114    * 
00115    * // ...
00116    * 
00117    * lti::image inputImg;
00118    * lti::channel8 edges;
00119    * lti::channel8 result;
00120    * 
00121    * // load image
00122    * lti::loadImage loader;
00123    * loader.load("myImage.bmp", inputImg);
00124    * 
00125    * // we need the edges
00126    * lti::cannyEdges canny;
00127    * canny.apply(inputImg, edges);
00128    * 
00129    * // create FEE functor (using default parameters)
00130    * lti::fastEllipseExtraction fee;
00131    * 
00132    * // extract some ellipses
00133    * fee.apply(edges);
00134    * 
00135    * // get the ellipse list
00136    * std::vector<lti::fastEllipseExtraction::ellipseEntry> &ellipses = fee.getEllipseList();
00137    * 
00138    * // create a drawing functor
00139    * lti::draw<lti::channel8::value_type> drawer;
00140    * drawer.use(result);
00141    * drawer.setColor(255);
00142    * 
00143    * // create background with grey edges
00144    * result = edges;
00145    * result /= 2;
00146    * 
00147    * for(int i=0; i<ellipses.size(); i++) {
00148    *   // draw ellipse
00149    *   lti::point center((int)ellipses[i].x, (int)ellipses[i].y);
00150    *   drawer.ellipse(center, (int)ellipses[i].b, (int)ellipses[i].a, ellipses[i].t, false);
00151    *   // print ellipse data
00152    *   printf("ellipse[%i]: center=(%.0f,%.0f) semiaxis=(%.0f,%.0f) angle=%.1f coverage=%.1f%% \n",
00153    *          i, ellipses[i].x, ellipses[i].y, ellipses[i].a, ellipses[i].b, ellipses[i].t*180/3.14, ellipses[i].coverage*100);
00154    * }
00155    * 
00156    * // show the extracted ellipses
00157    * lti::viewer view("Detected ellipses");
00158    * view.show(result);
00159    * 
00160    * // wait for a mouse click in the viewer window
00161    * view.waitButtonPressed();
00162    *
00163    * \endcode
00164    */
00165    
00166   class fastEllipseExtraction : public featureExtractor {
00167   public:
00168   
00169     struct segmEntry
00170     {
00171       ipoint  start;    // start point
00172       ipoint  end;      // end point
00173       int     len;      // length
00174       int     used;     // counts segment<->line assignments
00175     };
00176 
00177     struct lineEntry
00178     {
00179       ipoint  start;    // start point
00180       ipoint  end;      // end point
00181       ipoint  mid;      // midpoint 
00182       double  tangent;  // line tangent
00183       int     len;      // length
00184       int     used;     // counts line<->arc assignments
00185       int     group;    // base segment group (1,2,3 or 4)
00186       std::vector<int> *segmIdxList;  // base segment index list
00187     };
00188 
00189     struct ellArcEntry
00190     {
00191       ipoint  start;    // start point
00192       ipoint  end;      // end point
00193       ipoint  mid;      // estimated circle midpoint 
00194       int     r2;       // estimated squared radius
00195       ipoint  firstVec; // first line vector
00196       ipoint  lastVec;  // last line vector
00197       int     used;     // counts arc<->extarc assignments
00198       int     group;    // base line group (1,2,3 or 4)
00199       std::vector<int> *lineIdxList;  // base line index list
00200     };
00201 
00202     struct ellExtArcEntry
00203     {
00204       double  x,y;      // estimated ellipse center
00205       double  a,b;      // estimated ellipse semi-axis
00206       double  t;        // orientation angle
00207       double  ix, iy;   // intersection point of end tangents
00208       double  slopeLB;  // slope of line beam
00209       int     used;     // counts extarc<->ellipse assignments
00210       int     group;    // group of 2nd arc
00211       int     arcIdx[3];// ell arc indices
00212     };
00213 
00214     struct ellipseEntry
00215     {
00216       double  x,y;      // estimated ellipse center
00217       double  a,b;      // estimated ellipse semi-axis
00218       double  t;        // orientation angle
00219       double  coverage; // ellipse coverage (accuracy strongly depends on radius and other effects)
00220       std::vector<int> *mergedArcs;  // extarc index list
00221     };
00222   
00223     /**
00224      * the parameters for the class fastEllipseExtraction
00225      */
00226     class parameters : public featureExtractor::parameters {
00227     public:
00228       /**
00229        * default constructor
00230        */
00231       parameters();
00232 
00233       /**
00234        * copy constructor
00235        * @param other the parameters object to be copied
00236        */
00237       parameters(const parameters& other);
00238 
00239       /**
00240        * destructor
00241        */
00242       ~parameters();
00243 
00244       /**
00245        * returns name of this type
00246        */
00247       const char* getTypeName() const;
00248 
00249       /**
00250        * copy the contents of a parameters object
00251        * @param other the parameters object to be copied
00252        * @return a reference to this parameters object
00253        */
00254       parameters& copy(const parameters& other);
00255 
00256       /**
00257        * copy the contents of a parameters object
00258        * @param other the parameters object to be copied
00259        * @return a reference to this parameters object
00260        */
00261       parameters& operator=(const parameters& other);
00262 
00263 
00264       /**
00265        * returns a pointer to a clone of the parameters
00266        */
00267       virtual functor::parameters* clone() const;
00268 
00269       /**
00270        * write the parameters in the given ioHandler
00271        * @param handler the ioHandler to be used
00272        * @param complete if true (the default) the enclosing begin/end will
00273        *        be also written, otherwise only the data block will be written.
00274        * @return true if write was successful
00275        */
00276       virtual bool write(ioHandler& handler,const bool complete=true) const;
00277 
00278       /**
00279        * read the parameters from the given ioHandler
00280        * @param handler the ioHandler to be used
00281        * @param complete if true (the default) the enclosing begin/end will
00282        *        be also written, otherwise only the data block will be written.
00283        * @return true if write was successful
00284        */
00285       virtual bool read(ioHandler& handler,const bool complete=true);
00286 
00287 #     ifdef _LTI_MSC_6
00288       /**
00289        * this function is required by MSVC only, as a workaround for a
00290        * very awful bug, which exists since MSVC V.4.0, and still by
00291        * V.6.0 with all bugfixes (so called "service packs") remains
00292        * there...  This method is also public due to another bug, so please
00293        * NEVER EVER call this method directly: use read() instead
00294        */
00295       bool readMS(ioHandler& handler,const bool complete=true);
00296 
00297       /**
00298        * this function is required by MSVC only, as a workaround for a
00299        * very awful bug, which exists since MSVC V.4.0, and still by
00300        * V.6.0 with all bugfixes (so called "service packs") remains
00301        * there...  This method is also public due to another bug, so please
00302        * NEVER EVER call this method directly: use write() instead
00303        */
00304       bool writeMS(ioHandler& handler,const bool complete=true) const;
00305 #     endif
00306 
00307       // ------------------------------------------------
00308       // the parameters
00309       // ------------------------------------------------
00310 
00311 
00312       /** This threshold constant defines the maximum mismatch
00313        *  between the found line segments and the estimated analog line.
00314        *  The segment is discarded if its starting/finishing pixel 
00315        *  differs more than <code>maxQuantizationError</code>
00316        *  from the estimated analog line.
00317        *  If this value is greater than 1.0 the line detection will
00318        *  also extract lines that are not completely straight, which
00319        *  may be useful for estimation of lines.
00320        *  possible values are
00321        *  <pre>
00322        *  0.5 < maxQuantizationError
00323        *  </pre>
00324        *  A high maxQuantizationError value will extract longer lines
00325        *  at the cost of precision. Low values result in better pixel
00326        *  matching but also in shorter lines.
00327        *  Best compromise between pixel matching and good detection
00328        *  is a value between 0.6 and 0.7 (the default is 0.79)
00329        */
00330       float maxQuantizationError;
00331 
00332 
00333       /**
00334        *  This constant defines how much the value of two adjacent pixels  
00335        *  may differ and still be considered pixels of the same segment.
00336        *  A <code>segmentTolerance</code> of 0 will only group pixels
00337        *  of the same value to one segment. When analyzing binary maps
00338        *  such as edge-images a value of 0 should be used.
00339        *  possible values are
00340        *  <pre>
00341        *  0 <= segmentTolerance <= 254
00342        *  </pre>
00343        *  Higher segmentTolerance values allow non-binary
00344        *  images to be analysed but may also result in wrong 
00345        *  segment start/end detection. 
00346        *  The default is 0
00347        */
00348       int segmentTolerance;
00349 
00350 
00351       /**
00352        *  The maximum gap two line segments may have and
00353        *  still be considered segments of the same line.
00354        *  This parameter changes the size of the searching window
00355        *  for line segments. Small sizes allow fast processing but may
00356        *  also cause detection failures (as well as too high values)
00357        *  A <code>maxSegmentGap</code> of 1 will only group
00358        *  contiguous segments to a line.
00359        *  possible values are
00360        *  <pre>
00361        *  maxSegmentGap >= 1 (pixel)
00362        *  </pre>
00363        *  Higher maxSegmentGap values also allow extraction of
00364        *  non-contiguous lines such as found in corrupted images.
00365        *  The default is 1
00366        */
00367       int maxSegmentGap;
00368 
00369 
00370       /**
00371        *  The minimum length a line must have to get extracted.
00372        *  The parameter <code>minLineLen</code> is used as 
00373        *  threshold, smaller lines will be ignored.
00374        *  possible values are
00375        *  <pre>
00376        *  minLineLen >= 3 (pixel)
00377        *  </pre>
00378        *  Values greater than 3 will strongly decrease
00379        *  the number of extracted lines and therefore speed up
00380        *  the following extraction stages. For most circles
00381        *  the optimal value lies between 5 and 7.
00382        *  The default is 6
00383        */
00384       int minLineLen;
00385 
00386 
00387       /**
00388        *  The minimum length a line segment must have to be detected.
00389        *  The parameter <code>minSegmLen</code> is used as 
00390        *  threshold, smaller segments will be ignored.
00391        *  Values greater than 2 strongly decrease the number
00392        *  of detected segments and the size of the segment lists.
00393        *  possible values are
00394        *  <pre>
00395        *  minSegmLen >= 2 (pixel)
00396        *  </pre>
00397        *  Values greater than 2 result in smaller segment lists
00398        *  and therefore allow slightly faster line detection.
00399        *  But mostly good line detection is more important than
00400        *  a small speedup, so don't change this parameter unless
00401        *  there is a good reason to do so.
00402        *  The default is 2
00403        */
00404       int minSegmLen;
00405 
00406 
00407       /**
00408        *  The maximum gap two lines may have and
00409        *  still be considered lines of the same arc.
00410        *  This parameter changes the size of the searching window
00411        *  for lines. Best results were obtained with small values,
00412        *  because large window sizes tend to combine adjacent parallel
00413        *  lines to one arc which causes detection failures.
00414        *  A <code>maxLineGap</code> of 1 will only group
00415        *  contiguous lines to an arc.
00416        *  possible values are
00417        *  <pre>
00418        *  maxLineGap >= 1 (pixel)
00419        *  </pre>
00420        *  Higher maxLineGap values also allow extraction of
00421        *  non-contiguous arcs such as found in corrupted images.
00422        *  The default is 3
00423        */
00424       int maxLineGap;
00425 
00426 
00427       /**
00428        *  The maximum gap two arcs may have and
00429        *  still be considered arcs of the same extended arc.
00430        *  This parameter changes the size of the searching window
00431        *  for arcs. Best results were obtained with large values,
00432        *  because every arc has to find at least two neighbours
00433        *  to remain in the extraction process. (the gap between
00434        *  these arcs mostly lies between 10 and 40 pixels)
00435        *  A <code>maxArcGap</code> of 1 will only group
00436        *  contiguous arcs to an extended arc.
00437        *  possible values are
00438        *  <pre>
00439        *  maxArcGap >= 1 (pixel)
00440        *  </pre>
00441        *  Higher maxArcGap values also allow extraction of
00442        *  non-contiguous arcs such as found in corrupted images.
00443        *  The default is 25
00444        */
00445       int maxArcGap;
00446 
00447 
00448       /** This parameter defines the maximum difference that
00449        *  the tangents of two lines may have in relation to the
00450        *  tangents of the arc that these lines represent.
00451        *  In other words, this parameter affects the tolerance
00452        *  in terms of roundness of the countour.
00453        *  Line pairs which exceed this threshold won't be 
00454        *  combined to an arc. Too large values result in 
00455        *  incorrect arcs and detection failures.
00456        *  reasonable values are
00457        *  <pre>
00458        *  8.5 <= maxLineTangentError <= 20
00459        *  </pre>
00460        *  Small values cause stricter circle checks
00461        *  whereas large values allow more tolerance.
00462        *  Best compromise between accuracy and tolerance
00463        *  is a value between 10 and 15 (the default is 14)
00464        */
00465       float maxLineTangentError;
00466 
00467 
00468       /** This parameter defines the maximum difference that
00469        *  the tangents of two arcs may have in relation to the
00470        *  tangents of the ellipse that these arcs represent.
00471        *  In other words, this parameter affects the tolerance
00472        *  in terms of ellipse matching.
00473        *  Arcs exceeding this threshold won't be combined
00474        *  to an extended arc. Too large values result incorrect
00475        *  extended arcs and detection failures.
00476        *  reasonable values are
00477        *  <pre>
00478        *  10 <= maxArcTangentError <= 20
00479        *  </pre>
00480        *  Small values cause stricter ellipse checks
00481        *  whereas large values allow more tolerance.
00482        *  Best results were obtained with more tolerant
00483        *  values between 15 and 20 (the default is 18)
00484        */
00485       float maxArcTangentError;
00486 
00487 
00488       /** This parameter defines the maximum value that the
00489        *  start and end points of one extArc inserted into the
00490        *  normal ellipse equation of the other extArc may give.
00491        *  ExtArcs which exceed this threshold won't
00492        *  be merged into an ellipse. Too large values 
00493        *  cause detection failures.
00494        *  reasonable values are
00495        *  <pre>
00496        *  0 < maxExtArcMismatch < 1
00497        *  </pre>
00498        *  Small values cause stricter ellipse matching checks
00499        *  whereas large values allow more tolerance.
00500        *  Best compromise between accuracy and tolerance
00501        *  is a value between 0.2 and 0.4 (the default is 0.3)
00502        */
00503       float maxExtArcMismatch;
00504 
00505 
00506       /** This parameter defines the maximum gap between
00507        *  the estimated ellipse centers of two extended arcs. 
00508        *  ExtArc pairs which exceed this threshold won't be 
00509        *  combined to an ellipse. Too large values cause 
00510        *  detection failures.
00511        *  reasonable values are
00512        *  <pre>
00513        *  1 <= maxCenterMismatch <= 10
00514        *  </pre>
00515        *  Small values cause stricter extArc matching checks
00516        *  whereas large values allow more tolerance.
00517        *  Best compromise between accuracy and tolerance
00518        *  is a value between 3 and 7 (the default is 5)
00519        */
00520       float maxCenterMismatch;
00521 
00522 
00523       /** This parameter defines the minimal matching ratio
00524        *  of the estimated ellipse radii of two extended arcs. 
00525        *  ExtArc pairs which underrun this threshold won't be 
00526        *  combined to an ellipse. Too small values cause 
00527        *  detection failures.
00528        *  reasonable values are
00529        *  <pre>
00530        *  0.5 <= minRadiusMatchRatio <= 0.95
00531        *  </pre>
00532        *  Large values cause stricter extArc matching checks
00533        *  whereas small values allow more tolerance.
00534        *  Best compromise between accuracy and tolerance
00535        *  is a value between 0.7 and 0.9 (the default is 0.8)
00536        */
00537       float minRadiusMatchRatio;
00538 
00539 
00540       /** This parameter defines the minimal coverage for estimated
00541        *  ellipses to get extracted. That is the ratio of the estimated
00542        *  circumference and the number of extracted arc pixels.
00543        *  Ellipses which underrun this threshold won't get extracted.
00544        *  Too small values cause extraction of ellipses with randomly
00545        *  matching arcs. Also this threshold shouldn't be set to values
00546        *  greater than 0.7, since only well fitting parts of a ellipses 
00547        *  are extracted. Therefore even a completely present ellipse  
00548        *  may get only 70%% coverage.
00549        *  reasonable values are
00550        *  <pre>
00551        *  0.2 <= minCoverage <= 0.7
00552        *  </pre>
00553        *  Best compromise between accuracy and tolerance
00554        *  is a value between 0.2 and 0.4 (the default is 0.25)
00555        *  Note: Very close and similar ellipses are sometimes
00556        *  merged to one ellipse which shows more than 100%% coverage.
00557        */
00558       float minCoverage;
00559       
00560 
00561       /** This parameter defines the minimum relative 
00562        *  distance of two arcs. That is the distance of
00563        *  the start points of both arcs compared to the 
00564        *  start-end point distance of the first arc.
00565        *  Arcs which underrun this threshold won't be 
00566        *  combined to extArcs. 
00567        *  reasonable values are
00568        *  <pre>
00569        *  0 <= minArcDistanceRatio <= 1
00570        *  </pre>
00571        *  Values <1 allow extraction of overlapping
00572        *  arcs. Best results were obtained with values
00573        *  between 0.5 and 0.7 (the default is 0.56)
00574        */
00575       float minArcDistanceRatio;
00576 
00577 
00578       /** This parameter defines the maximum angle
00579        *  between the connection line of the start points
00580        *  of two arcs and the line from start point to end 
00581        *  point of the first arc.
00582        *  reasonable values are
00583        *  <pre>
00584        *  10 <= maxArcDistanceAngle <= 20
00585        *  </pre>
00586        *  Small values increase the separation accuracy of
00587        *  adjacent ellipse arcs but also lowers tolerance 
00588        *  against corrupted arcs. Best results were obtained 
00589        *  with a value of 16 (the default).
00590        */
00591       float maxArcDistanceAngle;
00592 
00593 
00594       /** This parameter is a threshold for the gap angle
00595        *  check. Arcs with a gap smaller than this value are
00596        *  considered close enough to have a continous transition.
00597        *  Arcs with greater gaps must pass the additional gap
00598        *  angle check. Too large values cause detection failures.
00599        *  reasonable values are
00600        *  <pre>
00601        *  1 <= minGAPangleDistance <= 3
00602        *  </pre>
00603        *  Best results were obtained with a value of 2 (the default).
00604        */
00605       int   minGAPangleDistance;
00606 
00607 
00608       /** This parameter defines the maximum angle between
00609        *  the end tangent of the first arc and the start tangent
00610        *  of the second arc and the connection tangent.
00611        *  Arc pairs which exceed this threshold won't be 
00612        *  combined to an extArc. Too large values cause 
00613        *  detection failures whereas too small values reject
00614        *  correct arcs.
00615        *  reasonable values are
00616        *  <pre>
00617        *  25 <= maxGAPangle <= 35
00618        *  </pre>
00619        *  Best results were obtained with a value of 30 (the default).
00620        */
00621       float maxGAPangle;
00622 
00623 
00624       /** This parameter defines the maximum radial gap two
00625        *  overlapping arcs. ExtArc pairs which exceed this 
00626        *  threshold won't be combined to an extArc. 
00627        *  Too large values cause detection failures.
00628        *  reasonable values are
00629        *  <pre>
00630        *  1 <= maxArcOverlapGap <= 3
00631        *  </pre>
00632        *  Best results were obtained with a value of 1 (the default).
00633        */
00634       float maxArcOverlapGap;
00635 
00636 
00637       /** This parameter defines the maximum number of errors
00638        *  in the interior angle check. The interior angles
00639        *  of all lines of the three arcs must be smaller than 90
00640        *  degrees to remain in the extArc extraction process. 
00641        *  Because of image corruptions one or more errors should
00642        *  be allowed. Too large values cause detection failures.
00643        *  reasonable values are
00644        *  <pre>
00645        *  1 <= maxIntAngleMismatches <= 3
00646        *  </pre>
00647        *  Best results were obtained with a value of 1 (the default).
00648        */
00649       int   maxIntAngleMismatches;
00650 
00651 
00652       /** This parameter defines the maximum number of errors
00653        *  in the arc tangent check. The tangents of all lines of 
00654        *  the three base arcs of one extArc must match the
00655        *  corresponding tangents of the estimated ellipse.
00656        *  The maximum difference between ideal and real tangent
00657        *  is defined by the parameter maxArcTangentError.
00658        *  Because of image corruptions one or more errors should
00659        *  be allowed. Too large values cause detection failures.
00660        *  reasonable values are
00661        *  <pre>
00662        *  1 <= maxTangentErrors <= 3
00663        *  </pre>
00664        *  Best results were obtained with a value of 1 (the default).
00665        */
00666       int   maxTangentErrors;
00667 
00668 
00669       /** This parameter defines the maximum distance between
00670        *  the line beam of the extArc and the center point of 
00671        *  the estimated ellipse.
00672        *  ExtArcs which exceed this threshold won't be 
00673        *  combined to an ellipse. Too large values cause 
00674        *  detection failures.
00675        *  reasonable values are
00676        *  <pre>
00677        *  1 <= maxLBcenterMismatch <= 10
00678        *  </pre>
00679        *  Small values cause stricter extArc matching checks
00680        *  whereas large values allow more tolerance.
00681        *  Best compromise between accuracy and tolerance
00682        *  is a value between 3 and 6 (the default is 4)
00683        */
00684       float maxLBcenterMismatch;
00685       
00686 
00687       /** The number of checks that an extArc must pass 
00688        *  before it gets extracted. This parameter was mainly
00689        *  used for debugging purposes but might further on be
00690        *  useful for the finding of optimal extraction parameters.
00691        *  <pre>
00692        *  1 = interior angle check
00693        *  2 = tangent check
00694        *  3 = line beam check
00695        *  </pre>
00696        *  With a value of 1 or 2 you can examine the behaviour 
00697        *  of the extArc checks. Unless there is a good reason 
00698        *  for less extArc checks this this value should be 3.
00699        */
00700       int   ellExtArcExtractionStage;
00701     };
00702 
00703     /**
00704      * default constructor
00705      */
00706     fastEllipseExtraction();
00707 
00708     /**
00709      * Construct a functor using the given parameters
00710      */
00711     fastEllipseExtraction(const parameters& par);
00712 
00713     /**
00714      * copy constructor
00715      * @param other the object to be copied
00716      */
00717     fastEllipseExtraction(const fastEllipseExtraction& other);
00718 
00719     /**
00720      * destructor
00721      */
00722     virtual ~fastEllipseExtraction();
00723 
00724     /**
00725      * returns the name of this type ("fastEllipseExtraction")
00726      */
00727     virtual const char* getTypeName() const;
00728 
00729 
00730     /**
00731      * Applies fast ellipse detection on-place.
00732      * @param srcdest channel8 with the source data.
00733      * @return true if apply was successful or false otherwise.
00734      */
00735     bool apply(const channel8& srcdest);
00736 
00737     /**
00738      * Applies fast ellipse detection on-place.
00739      * @param srcdest channel with the source data.
00740      * @return true if apply was successful or false otherwise.
00741      */
00742     bool apply(const channel& srcdest);
00743 
00744     /**
00745      * copy data of "other" functor.
00746      * @param other the functor to be copied
00747      * @return a reference to this functor object
00748      */
00749     fastEllipseExtraction& copy(const fastEllipseExtraction& other);
00750 
00751     /**
00752      * alias for copy member
00753      * @param other the functor to be copied
00754      * @return a reference to this functor object
00755      */
00756     fastEllipseExtraction& operator=(const fastEllipseExtraction& other);
00757 
00758     /**
00759      * returns a pointer to a clone of this functor.
00760      */
00761     virtual functor* clone() const;
00762 
00763     /**
00764      * returns used parameters
00765      */
00766     const parameters& getParameters() const;
00767 
00768 
00769 ///////////////////////////////////////////////////////////
00770 
00771     /**
00772      * returns a vector with line segments of the specified group
00773      * @param groupNumber number of the line segment group (1,2,3,4)
00774      * @return vector with detected line segments
00775      */
00776     virtual std::vector<segmEntry>& getSegmentList(const int groupNumber);
00777 
00778     /**
00779      * returns a vector with lines of the specified group
00780      * @param groupNumber number of the line group (1,2,3,4, or 0 for all lines)
00781      * @return vector with extracted lines
00782      */
00783     virtual std::vector<lineEntry>& getLineList(const int groupNumber);
00784 
00785     /**
00786      * returns a vector with arcs of the specified group
00787      * @param groupNumber number of the arc group (1,2,3,4,5,6,7,8 or 0 for all arcs)
00788      * @return vector with extracted arcs
00789      */
00790     virtual std::vector<ellArcEntry>& getEllArcList(const int groupNumber);
00791 
00792     /**
00793      * returns a vector with extended arcs of the specified group
00794      * @param groupNumber number of the arc group (1,2,3,4,5,6,7,8 or 0 for all arcs)
00795      * @return vector with extracted extended arcs
00796      */
00797     virtual std::vector<ellExtArcEntry>& getEllExtArcList(const int groupNumber);
00798 
00799     /**
00800      * returns a vector with extracted ellipses.
00801      * @return vector with extracted ellipses
00802      */
00803     virtual std::vector<ellipseEntry>& getEllipseList();
00804 
00805 
00806 private:
00807 
00808     /**
00809      * clears a line list and its allocated objects
00810      * @param groupNumber number of the line group (0,1,2,3,4)
00811      */
00812     virtual void clearLineList(const int groupNumber);
00813 
00814     /**
00815      * clears an arc list and its allocated objects
00816      * @param groupNumber number of the arc group (0,1,2,3,4,5,6,7,8)
00817      */
00818     virtual void clearEllArcList(const int groupNumber);
00819 
00820     /**
00821      * clears an extended arc list and its allocated objects
00822      * @param groupNumber number of the arc group (0,1,2,3,4,5,6,7,8)
00823      */
00824     virtual void clearEllExtArcList(const int groupNumber);
00825 
00826     /**
00827      * clears the ellipse list and its allocated objects
00828      */
00829     virtual void clearEllipseList();
00830 
00831     /**
00832      * The segment detection methods. They detect segments by scanning pixel rows.
00833      * For performance and review reasons there are 4 methods (one per segment group).
00834      * Results are stored in STL vectors of type <segmEntry>. These vectors can
00835      * be accessed by the method getSegmentList().
00836      * @param src channel with source data
00837      */
00838     virtual void detectGroup1Segments(const channel8& src);
00839     virtual void detectGroup2Segments(const channel8& src);
00840     virtual void detectGroup3Segments(const channel8& src);
00841     virtual void detectGroup4Segments(const channel8& src);
00842 
00843     /**
00844      * The line extraction methods. They extract lines by tracking line segments.
00845      * For performance and review reasons there are 4 methods (one per segment group).
00846      * Results are stored in STL vectors of type <lineEntry>. These vectors can
00847      * be accessed by the method getLineList().
00848      */
00849     virtual void extractGroup1Lines();
00850     virtual void extractGroup2Lines();
00851     virtual void extractGroup3Lines();
00852     virtual void extractGroup4Lines();
00853 
00854     /**
00855      * The arc extraction methods. They extract arcs by tracking lines.
00856      * For performance and review reasons there are 4 methods (one per segment group).
00857      * Results are stored in STL vectors of type <ellArcEntry>. These vectors can
00858      * be accessed by the method getEllArcList().
00859      */
00860     virtual void extractGroup1and5Arcs();
00861     virtual void extractGroup3and7Arcs();
00862     virtual void extractGroup2and6Arcs();
00863     virtual void extractGroup4and8Arcs();
00864 
00865     /**
00866      * The extended arc extraction method. It extracts extended arcs by tracking arcs.
00867      * Results are stored in STL vectors of type <ellExtArcEntry>. These vectors can
00868      * be accessed by the method getEllExtArcList().
00869      * @param grp the extended arc group to extract
00870      */
00871     void extractEllExtArcs(const int grp);
00872 
00873 
00874     /**
00875      * The ellipse extraction method.
00876      * Ellipses are extracted by merging extended arcs.
00877      */
00878     void extractEllipses();
00879 
00880 
00881     /**
00882      * Calculates and checks the interior angles of two arcs.
00883      * @param a index of the first arc
00884      * @param grpA group of the first arc
00885      * @param b index of the second arc
00886      * @param grpB group of the second arc
00887      * @return the number of angle mismatches
00888      */
00889     int checkInteriorAngles(int a, int grpA, int b, int grpB);
00890 
00891 
00892     /**
00893      * Calculates and checks the tangent matching of an extended arc and an ellipse.
00894      * @param extarc the arc to be checked
00895      * @param Xest x coordinate of the ellipse
00896      * @param Yest y coordinate of the ellipse
00897      * @param Aest large semi-axis of the ellipse
00898      * @param Best small semi-axis of the ellipse
00899      * @param Test orientation angle of the ellipse
00900      * @return the number of tangent mismatches
00901      */
00902     int checkEllExtArcTangents(const ellExtArcEntry &extarc,
00903                                double Xest, double Yest, double Aest, double Best, double Test);
00904 
00905 
00906     /**
00907      * Calculates the distance from the linebeam of an extended arc to an ellipse center point.
00908      * The intersection point of the start and end tangents and the line beam slope are stored
00909      * in the given extArc entry.
00910      * @param firstLine first line of the arc to be checked
00911      * @param lastLine last line of the arc to be checked
00912      * @param extarc the arc to be checked
00913      * @param Xest x coordinate of the ellipse
00914      * @param Yest y coordinate of the ellipse
00915      * @return true if successful
00916      */
00917     bool lineBeamCenterDistance(const lineEntry &firstLine,
00918                                 const lineEntry &lastLine,
00919                                 ellExtArcEntry &extarc,
00920                                 double &distance, const double Xest, const double Yest);
00921 
00922 
00923     /**
00924      * Calculates the start and end point distance of an extended arc from an estimated ellipse.
00925      * @param extarc the arc to be checked
00926      * @param Xest x coordinate of the ellipse
00927      * @param Yest y coordinate of the ellipse
00928      * @param Aest large semi-axis of the ellipse
00929      * @param Best small semi-axis of the ellipse
00930      * @param Test orientation angle of the ellipse
00931      * @return the maximum distance
00932      */
00933     double ellipsePointMismatch(ellExtArcEntry &extarc,
00934                               double Xest, double Yest, double Aest, double Best, double Test);
00935 
00936 
00937     /**
00938      * Calculates the intersection point of the line beams of two extended arcs and its
00939      * distance from an ellipse center point.
00940      * @param extarcA first arc
00941      * @param extarcB second arc
00942      * @param Xest x coordinate of the ellipse
00943      * @param Yest y coordinate of the ellipse
00944      * @return the distance of intersection and center point
00945      */
00946     double lineBeamIsecCenterDistance(const ellExtArcEntry &extarcA,
00947                                       const ellExtArcEntry &extarcB,
00948                                       double Xest, double Yest);
00949   
00950 
00951     /**
00952      * Calculates the distance between a point and a line.
00953      * @param testPtX x coordinate of the point
00954      * @param testPtY y coordinate of the point
00955      * @param linePtY x coordinate of a line point
00956      * @param testPtY y coordinate of a line point
00957      * @param lineSlope slope of the line
00958      * @return the distance between the point and the line.
00959      */
00960     double linePointDistance(double testPtX, double testPtY, 
00961                              double linePtX, double linePtY,
00962                              double lineSlope);
00963   
00964 
00965 
00966     /**
00967      * Calculates the coverage of an estimated ellipse by approximating the ideal  
00968      * circumference and counting the edge pixels of the extracted extended arcs.
00969      * The coverage value is stored in the given ellipse entry.
00970      * @param ellipse the ellipse
00971      */
00972     void calculateEllipseCoverage(ellipseEntry &ellipse);
00973   
00974   
00975   
00976     /**
00977      * Estimates ellipse parameters by using a least square fitting algorithm.
00978      * @param arcA first arc of the ellipse
00979      * @param arcB second arc of the ellipse
00980      * @param arcC third arc of the ellipse
00981      * @param Xest estimated x coordinate of the ellipse
00982      * @param Yest estimated y coordinate of the ellipse
00983      * @param Aest estimated large semi-axis of the ellipse
00984      * @param Best estimated small semi-axis of the ellipse
00985      * @param Test estimated orientation angle of the ellipse
00986      * @return true if estimation was successful
00987      */
00988     bool estimateEllipse(const ellArcEntry &arcA, 
00989                          const ellArcEntry &arcB, 
00990                          const ellArcEntry &arcC, 
00991                          double &Xest, double &Yest, double &Aest, double &Best, double &Test);
00992                          
00993 
00994     /**
00995      * Estimates ellipse parameters by using a least square fitting algorithm.
00996      * @param mergedArcs pointer to vector with extArc index numbers
00997      * @param Xest estimated x coordinate of the ellipse
00998      * @param Yest estimated y coordinate of the ellipse
00999      * @param Aest estimated large semi-axis of the ellipse
01000      * @param Best estimated small semi-axis of the ellipse
01001      * @param Test estimated orientation angle of the ellipse
01002      * @return true if estimation was successful
01003      */
01004     bool estimateEllipse(const std::vector<int> *mergedArcs, 
01005                          double &Xest, double &Yest, double &Aest, double &Best, double &Test);
01006   
01007 
01008     /**
01009      * A least square fitting algorithm for ellipse estimation.
01010      * @param Design matrix with ellipse edge pixel data
01011      * @param Xest estimated x coordinate of the ellipse
01012      * @param Yest estimated y coordinate of the ellipse
01013      * @param Aest estimated large semi-axis of the ellipse
01014      * @param Best estimated small semi-axis of the ellipse
01015      * @param Test estimated orientation angle of the ellipse
01016      * @return true if estimation was successful
01017      */
01018     bool directEllipseFitting(const lti::matrix<double> &Design, 
01019                               double &Xest, double &Yest, double &Aest, double &Best, double &Test);
01020   
01021 
01022     /**
01023      * A least square fitting algorithm for ellipse estimation. 
01024      * Results are coefficients of the equation for conic sections.
01025      * @param Design matrix with ellipse edge pixel data
01026      * @param A first conic section coefficient
01027      * @param B second conic section coefficient
01028      * @param C third conic section coefficient
01029      * @param D fourth conic section coefficient
01030      * @param E fifth conic section coefficient
01031      * @param F sixth conic section coefficient
01032      * @return true if estimation was successful
01033      */
01034     bool directEllipseCoefficientFitting(const lti::matrix<double> &Design, 
01035                                          double &A, double &B, double &C, double &D, double &E, double &F);
01036   
01037 
01038     /**
01039      * Estimates circle parameters by using a least square fitting algorithm.
01040      * @param idxlist vector with arc line index numbers
01041      * @param group group number of the arc lines
01042      * @param Xest the estimated x-coordinate
01043      * @param Yest the estimated y-coordinate
01044      * @param R2est the estimated squared radius
01045      * @return true if calculation was successful
01046      */
01047     virtual bool estimateCircle(std::vector<int> &idxlist, const int group,
01048                                 double &Xest, double &Yest, double &R2est);
01049 
01050 
01051     /**
01052      * The segment containers. (to allow easier implementation
01053      * the arraysize is 5 although only 4 conatainers are used)
01054      * vecSegments[1..4] contain segment groups I..IV,
01055      * vecSegments[0] is not used. 
01056      */
01057     std::vector<segmEntry> vecSegments[5];
01058 
01059     /**
01060      * The line containers. 
01061      * vecLines[1..4] contain line groups I..IV,
01062      * vecLines[0] contains all lines.
01063      */
01064     std::vector<lineEntry> vecLines[5];
01065 
01066     /**
01067      * The elliptic arc containers (8-group classification).
01068      * vecExtArcs[1..9] contain arc groups 1..8,
01069      * vecExtArcs[0] contains all arcs. 
01070      */
01071     std::vector<ellArcEntry> vecEllArcs[9];
01072 
01073     /**
01074      * The elliptic extended arc containers (8-group classification).
01075      * vecEllExtArcs[1..9] contain extArc groups 1..8,
01076      * vecEllExtArcs[0] contains all extended arcs. 
01077      */
01078     std::vector<ellExtArcEntry> vecEllExtArcs[9];
01079 
01080     /**
01081      * The ellipse container.
01082      */
01083     std::vector<ellipseEntry> vecEllipses;
01084 
01085     /**
01086      * The input image width. Needed for coordinate transformation 
01087      * when extracting diagonal lines.
01088      */
01089     int imageWidth;
01090 
01091     /**
01092      * The number of pre-allocated vector entries.
01093      */
01094     static const int segmPreallocation;
01095     static const int linePreallocation;
01096     static const int ellArcPreallocation;
01097     static const int ellExtArcPreallocation;
01098     static const int ellipsePreallocation;
01099     
01100     /**
01101      * Numeric constants.
01102      */
01103     static const double PI;
01104     static const double INFINITE_SLOPE;
01105 
01106   };
01107 }
01108 
01109 #endif

Generated on Sat Apr 10 15:25:27 2010 for LTI-Lib by Doxygen 1.6.1