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

ltiFastLineExtraction.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 .......: ltiFastLineExtraction.h
00027  * authors ....: Ingo Grothues (ingo@isdevelop.de)
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 10.3.2004
00030  * revisions ..: $Id: ltiFastLineExtraction.h,v 1.10 2006/02/08 11:06:36 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_FAST_LINE_EXTRACTION_H_
00034 #define _LTI_FAST_LINE_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 line extraction
00044    * using the line segments found in digital images.
00045    * 
00046    * To achieve this, the (edge-)image is decomposed into
00047    * line segments of four types (I=horizontal, II=vertical, 
00048    * III=diagonal horizontal, IV=diagonal vertical)
00049    * which are recomposed to lines in a second pass.
00050    * 
00051    * The fastLineExtraction::parameters specify ranges
00052    * for segments/lines and conditions that a set of 
00053    * segments must fulfill to be considered as a line.
00054    * The result strongly depends on these parameters,
00055    * especially the number and the precision of the 
00056    * extracted lines.
00057    *
00058    * The extracted segments and lines are stored in STL vector
00059    * containers of the type <segmEntry> and can be accessed by
00060    * the methods getSegmentList() and getLineList().
00061    *
00062    * \c ipoint is the data type for coordinates:
00063    * <pre> typedef tpoint<int> ipoint; </pre>
00064    *   
00065    * \c segmEntry is the data struct for segments/lines:
00066    * <pre> struct segmEntry
00067    *  {
00068    *    ipoint  start;    // start point of segment or line
00069    *    ipoint  end;      // end point of segment or line
00070    *    int     len;      // length of segment or line
00071    *    int     used;     // counts segment<->line assignments
00072    *  };</pre>
00073    * 
00074    * Additionally there are two methods which return some
00075    * statistical information about the line extraction process:
00076    * getNonGroupedSegmentCount() and getMultiGroupedSegmentCount()
00077    *
00078    * The fast line extraction does not perform any changes
00079    * to the analyzed image. To visualize the extracted lines
00080    * they have to be drawn by other code using the
00081    * segment lists and a drawing functor.
00082    *
00083    *
00084    * Example:
00085    * \code
00086    *    
00087    * #include "ltiViewer.h"               // visualization tool
00088    * #include "ltiDraw.h"                 // drawing tool
00089    * #include "ltiALLfunctor.h"           // image loader   
00090    * #include "ltiCannyEdges.h"           // edge detector
00091    * #include "ltiFastLineExtraction.h"   // line detector
00092    * 
00093    * // ...
00094    * 
00095    * lti::image inputImg;
00096    * lti::channel8 edges;
00097    * lti::channel8 result;
00098    *
00099    * // load image
00100    * lti::loadImage loader;
00101    * loader.load("myImage.bmp", inputImg);
00102    *
00103    * // we need the edges
00104    * lti::cannyEdges canny;
00105    * canny.apply(inputImg, edges);
00106    * 
00107    * // create FLE functor (using default parameters)
00108    * lti::fastLineExtraction fle;
00109    * 
00110    * // extract the lines
00111    * fle.apply(m_edges);
00112    * 
00113    * // get the complete line list
00114    * std::vector<lti::fastLineExtraction::segmEntry> &lines = fle.getLineList(0);
00115    * 
00116    * // create a drawing functor
00117    * lti::draw<lti::channel8::value_type> drawer;
00118    * drawer.use(result);
00119    * drawer.setColor(255);
00120    * 
00121    * for(int i=0; i<lines.size(); i++) {
00122    *   // draw all lines
00123    *   drawer.line(lines[i].start, lines[i].end);
00124    *   // print line data
00125    *   printf("line[%i]: start=(%i,%i) end=(%i,%i) length=%i \n", i, 
00126    *           lines[i].start.x, lines[i].start.y, lines[i].end.x, lines[i].end.y, lines[i].len);
00127    * }
00128    * 
00129    * // show the extracted lines
00130    * lti::viewer view("Detected lines");
00131    * view.show(result);
00132    * 
00133    * // wait for a mouse click in the viewer window
00134    * view.waitButtonPressed();
00135    * 
00136    * \endcode
00137    */
00138 
00139   class fastLineExtraction : public featureExtractor {
00140   public:
00141 
00142     struct segmEntry
00143     {
00144       ipoint  start;    // start point of segment or line
00145       ipoint  end;      // end point of segment or line
00146       int     len;      // length of segment or line
00147       int     used;     // counts segment<->line assignments
00148     };
00149   
00150 
00151     /**
00152      * the parameters for the class fastLineExtraction
00153      */
00154 
00155     class parameters : public featureExtractor::parameters {
00156     public:
00157       /**
00158        * default constructor
00159        */
00160       parameters();
00161 
00162       /**
00163        * copy constructor
00164        * @param other the parameters object to be copied
00165        */
00166       parameters(const parameters& other);
00167 
00168       /**
00169        * destructor
00170        */
00171       ~parameters();
00172 
00173       /**
00174        * returns name of this type
00175        */
00176       const char* getTypeName() const;
00177 
00178       /**
00179        * copy the contents of a parameters object
00180        * @param other the parameters object to be copied
00181        * @return a reference to this parameters object
00182        */
00183       parameters& copy(const parameters& other);
00184 
00185       /**
00186        * copy the contents of a parameters object
00187        * @param other the parameters object to be copied
00188        * @return a reference to this parameters object
00189        */
00190       parameters& operator=(const parameters& other);
00191 
00192 
00193       /**
00194        * returns a pointer to a clone of the parameters
00195        */
00196       virtual functor::parameters* clone() const;
00197 
00198       /**
00199        * write the parameters in the given ioHandler
00200        * @param handler the ioHandler to be used
00201        * @param complete if true (the default) the enclosing begin/end will
00202        *        be also written, otherwise only the data block will be written.
00203        * @return true if write was successful
00204        */
00205       virtual bool write(ioHandler& handler,const bool complete=true) const;
00206 
00207       /**
00208        * read the parameters from the given ioHandler
00209        * @param handler the ioHandler to be used
00210        * @param complete if true (the default) the enclosing begin/end will
00211        *        be also written, otherwise only the data block will be written.
00212        * @return true if write was successful
00213        */
00214       virtual bool read(ioHandler& handler,const bool complete=true);
00215 
00216 #ifdef _LTI_MSC_6
00217       /**
00218        * this function is required by MSVC only, as a workaround for a
00219        * very awful bug, which exists since MSVC V.4.0, and still by
00220        * V.6.0 with all bugfixes (so called "service packs") remains
00221        * there...  This method is also public due to another bug, so please
00222        * NEVER EVER call this method directly: use read() instead
00223        */
00224       bool readMS(ioHandler& handler,const bool complete=true);
00225 
00226       /**
00227        * this function is required by MSVC only, as a workaround for a
00228        * very awful bug, which exists since MSVC V.4.0, and still by
00229        * V.6.0 with all bugfixes (so called "service packs") remains
00230        * there...  This method is also public due to another bug, so please
00231        * NEVER EVER call this method directly: use write() instead
00232        */
00233       bool writeMS(ioHandler& handler,const bool complete=true) const;
00234 #endif
00235 
00236       // ------------------------------------------------
00237       // the parameters
00238       // ------------------------------------------------
00239 
00240 
00241 
00242       /** This threshold constant defines the maximum mismatch
00243        *  between the found line segments and the estimated analog line.
00244        *  The segment is discarded if its starting/finishing pixel 
00245        *  differs more than \c maxQuantizationError
00246        *  from the estimated analog line.
00247        *  If this value is greater than 1.0 the line detection will
00248        *  also extract lines that are not completely straight, which
00249        *  may be useful for estimation of lines.
00250        *  possible values are
00251        *  <pre>
00252        *  0.5 < maxQuantizationError
00253        *  </pre>
00254        *  A high maxQuantizationError value will extract longer lines
00255        *  at the cost of precision. Low values result in better pixel
00256        *  matching but also in shorter lines.
00257        *  Best compromise between pixel matching and good detection
00258        *  is a value between 0.6 and 0.7 (the default is 1.0)
00259        */
00260       float maxQuantizationError;
00261 
00262 
00263       /**
00264        *  This constant defines how much the value of two adjacent pixels  
00265        *  may differ and still be considered pixels of the same segment.
00266        *  A <code>segmentTolerance</code> of 0 will only group pixels
00267        *  of the same value to one segment. When analyzing binary maps
00268        *  such as edge-images a value of 0 should be used.
00269        *  possible values are
00270        *  <pre>
00271        *  0 <= segmentTolerance <= 254
00272        *  </pre>
00273        *  Higher segmentTolerance values allow non-binary
00274        *  images to be analysed but may also result in wrong 
00275        *  segment start/end detection. 
00276        *  The default is 0
00277        */
00278       int segmentTolerance;
00279 
00280 
00281       /**
00282        *  The maximum gap two line segments may have and
00283        *  still be considered segments of the same line.
00284        *  This parameter changes the size of the searching window
00285        *  for line segments. Small sizes allow fast processing but may
00286        *  also cause detection failures (as well as too high values)
00287        *  A <code>maxSegmentGap</code> of 1 will only group
00288        *  contiguous segments to a line.
00289        *  possible values are
00290        *  <pre>
00291        *  maxSegmentGap >= 1 (pixel)
00292        *  </pre>
00293        *  Higher maxSegmentGap values also allow extraction of
00294        *  non-contiguous lines such as found in corrupted images.
00295        *  The default is 1
00296        */
00297       int maxSegmentGap;
00298 
00299 
00300       /**
00301        *  The minimum length a line must have to get extracted.
00302        *  The parameter \c minLineLen is used as 
00303        *  threshold, smaller lines will be ignored.
00304        *  possible values are
00305        *  <pre>
00306        *  minLineLen >= 3 (pixel)
00307        *  </pre>
00308        *  Values greater than 3 will strongly decrease
00309        *  the number of extracted lines.
00310        *  The default is 3
00311        */
00312       int minLineLen;
00313 
00314 
00315       /**
00316        *  The minimum length a line segment must have to be detected.
00317        *  The parameter <code>minSegmLen</code> is used as 
00318        *  threshold, smaller segments will be ignored.
00319        *  Values greater than 2 strongly decrease the number
00320        *  of detected segments and the size of the segment lists.
00321        *  possible values are
00322        *  <pre>
00323        *  minSegmLen >= 2 (pixel)
00324        *  </pre>
00325        *  Values greater than 2 result in smaller segment lists
00326        *  and therefore allow slightly faster line detection.
00327        *  But mostly good line detection is more important than
00328        *  a small speedup, so don't change this parameter unless
00329        *  there is a good reason to do so.
00330        *  The default is 2
00331        */
00332       int minSegmLen;
00333     };
00334 
00335 ////////////////////////////////////////////////////////////////////////////
00336 
00337     /**
00338      * default constructor
00339      */
00340     fastLineExtraction();
00341 
00342     /**
00343      * Construct a functor using the given parameters
00344      */
00345     fastLineExtraction(const parameters& par);
00346 
00347     /**
00348      * copy constructor
00349      * @param other the object to be copied
00350      */
00351     fastLineExtraction(const fastLineExtraction& other);
00352 
00353     /**
00354      * destructor
00355      */
00356     virtual ~fastLineExtraction();
00357 
00358     /**
00359      * returns the name of this type ("fastLineExtraction")
00360      */
00361     virtual const char* getTypeName() const;
00362 
00363     
00364     /**
00365      * Applies fast line detection on-place.
00366      * @param srcdest channel8 with the source data.
00367      * @return true if apply was successful or false otherwise.
00368      */
00369     bool apply(const channel8& srcdest);
00370 
00371     /**
00372      * Applies fast line detection on-place.
00373      * @param srcdest channel with the source data.
00374      * @return true if apply was successful or false otherwise.
00375      */
00376     bool apply(const channel& srcdest);
00377 
00378     /**
00379      * copy data of "other" functor.
00380      * @param other the functor to be copied
00381      * @return a reference to this functor object
00382      */
00383     fastLineExtraction& copy(const fastLineExtraction& other);
00384 
00385     /**
00386      * alias for copy member
00387      * @param other the functor to be copied
00388      * @return a reference to this functor object
00389      */
00390     fastLineExtraction& operator=(const fastLineExtraction& other);
00391 
00392     /**
00393      * returns a pointer to a clone of this functor.
00394      */
00395     virtual functor* clone() const;
00396 
00397     /**
00398      * returns used parameters
00399      */
00400     const parameters& getParameters() const;
00401 
00402 ///////////////////////////////////////////////////////////
00403 
00404     /**
00405      * returns a vector with line segments of the specified group
00406      * @param group_number number of the line segment group (1,2,3,4)
00407      * @return vector with detected line segments
00408      */
00409     virtual std::vector<segmEntry>& getSegmentList(const int group_number);
00410 
00411     /**
00412      * returns a vector with lines of the specified group
00413      * @param group_number number of the line group (1,2,3,4, or 0 for all lines)
00414      * @return vector with extracted lines
00415      */
00416     virtual std::vector<segmEntry>& getLineList(const int group_number);
00417 
00418     /**
00419      * returns number of segments that could not be grouped to a line
00420      * @param group_number number of the line group (1,2,3,4)
00421      * @return number of non-grouped line segments
00422      */
00423     virtual const int getNonGroupedSegmentCount(const int group_number) const;
00424 
00425     /**
00426      * returns number of segments that are used in several lines
00427      * @param group_number number of the line group (1,2,3,4)
00428      * @return number of multi-grouped line segments
00429      */
00430     virtual const int getMultiGroupedSegmentCount(const int group_number) const;
00431 
00432 
00433 private:
00434 
00435     /**
00436      * The segment detection methods. They detect segments by scanning pixel rows.
00437      * For performance and review reasons there are 4 methods (one per segment group).
00438      * Results are stored in STL vectors of type <segmEntry>. These vectors can
00439      * be accessed by the method getSegmentList().
00440      * @param src channel with source data
00441      */
00442     virtual void detectGroup1Segments(const channel8& src);
00443     virtual void detectGroup2Segments(const channel8& src);
00444     virtual void detectGroup3Segments(const channel8& src);
00445     virtual void detectGroup4Segments(const channel8& src);
00446 
00447     /**
00448      * The line extraction methods. They extract lines by tracking line segments.
00449      * For performance and review reasons there are 4 methods (one per segment group).
00450      * Results are stored in STL vectors of type <segmEntry>. These vectors can
00451      * be accessed by the method getLineList().
00452      */
00453     virtual void extractGroup1Lines();
00454     virtual void extractGroup2Lines();
00455     virtual void extractGroup3Lines();
00456     virtual void extractGroup4Lines();
00457     
00458     /**
00459      * The line containers. 
00460      * m_vecLines[1..4] contain line groups I..IV,
00461      * m_vecLines[0] contains all lines.
00462      */
00463     std::vector<segmEntry> m_vecLines[5];
00464 
00465     /**
00466      * The segment containers. (to allow easier implementation
00467      * the arraysize is 5 although only 4 conatainers are used)
00468      * m_vecSegments[1..4] contain segment groups I..IV,
00469      * m_vecSegments[0] is not used. 
00470      */
00471     std::vector<segmEntry> m_vecSegments[5];
00472     
00473     /**
00474      * The input image width. Needed for coordinate transformation 
00475      * when extracting diagonal lines.
00476      */
00477     int m_iWidth;
00478 
00479     /**
00480      * The number of pre-allocated vector entries.
00481      */
00482     static const int SegmPreallocation;
00483     static const int LinePreallocation;
00484   };
00485 }
00486 
00487 #endif

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