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

ltiCannyEdges.h

00001 /*
00002  * Copyright (C) 2002, 2003, 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 .......: ltiCannyEdges.h
00027  * authors ....: Christian Harte
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 19.7.2002
00030  * revisions ..: $Id: ltiCannyEdges.h,v 1.12 2006/02/07 18:34:34 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_CANNY_EDGES_H_
00034 #define _LTI_CANNY_EDGES_H_
00035 
00036 #include "ltiEdgeDetector.h"
00037 #include "ltiNonMaximaSuppression.h"
00038 #include "ltiColorContrastGradient.h"
00039 #include "ltiArctanLUT.h"
00040 
00041 namespace lti {
00042   /**
00043    * The Canny Edge Detector is a standard algorithm, designed to detect
00044    * "optimal" edges.  Almost every image processing book (e.g. Sonka et.al
00045    * Image Processing, Analysis and Machine Vision) explains the details for
00046    * the algorithm.
00047    *
00048    * As all other edge detectors in this Library, the colors for the edges and
00049    * background are specified in the parameters (see
00050    * lti::edgeDetector::parameters)
00051    *
00052    * The construction of the first cannyEdges functor in your
00053    * application will take some time to initialize a Look-Up-Table
00054    * that allows a much faster edge detection later  (about 0.13 seconds
00055    * on a Pentium III, 450MHz).  The LUT will require about 1MB.
00056    * Please see lti::arctanLUT for more information.
00057    *
00058    * You can also choose between the "classic" simple gradient operator,
00059    * which considers only two neighbors at each axis \c x and \c y or the more
00060    * accurate gradient kernels (see lti::gradientKernelX).  In the latter
00061    * mode, the edge detection is about a factor 2 slower.
00062    *
00063    * For color images the color contrast gradient is used.
00064    *
00065    * @see lti::nonMaximumSuppression
00066    * @see lti::colorContrastGradient
00067    * @see lti::edgeDetector
00068    */
00069   class cannyEdges : public edgeDetector {
00070   public:
00071     /**
00072      * the parameters for the class cannyEdges
00073      */
00074     class parameters : public edgeDetector::parameters {
00075     public:
00076       /**
00077        * default constructor
00078        */
00079       parameters();
00080 
00081       /**
00082        * copy constructor
00083        * @param other the parameters object to be copied
00084        */
00085       parameters(const parameters& other);
00086 
00087       /**
00088        * destructor
00089        */
00090       ~parameters();
00091 
00092       /**
00093        * returns name of this type
00094        */
00095       const char* getTypeName() const;
00096 
00097       /**
00098        * copy the contents of a parameters object
00099        * @param other the parameters object to be copied
00100        * @return a reference to this parameters object
00101        */
00102       parameters& copy(const parameters& other);
00103 
00104       /**
00105        * copy the contents of a parameters object
00106        * @param other the parameters object to be copied
00107        * @return a reference to this parameters object
00108        */
00109       parameters& operator=(const parameters& other);
00110 
00111 
00112       /**
00113        * returns a pointer to a clone of the parameters
00114        */
00115       virtual functor::parameters* clone() const;
00116 
00117       /**
00118        * write the parameters in the given ioHandler
00119        * @param handler the ioHandler to be used
00120        * @param complete if true (the default) the enclosing begin/end will
00121        *        be also written, otherwise only the data block will be written.
00122        * @return true if write was successful
00123        */
00124       virtual bool write(ioHandler& handler,const bool complete=true) const;
00125 
00126       /**
00127        * read the parameters from the given ioHandler
00128        * @param handler the ioHandler to be used
00129        * @param complete if true (the default) the enclosing begin/end will
00130        *        be also written, otherwise only the data block will be written.
00131        * @return true if write was successful
00132        */
00133       virtual bool read(ioHandler& handler,const bool complete=true);
00134 
00135 #     ifdef _LTI_MSC_6
00136       /**
00137        * this function is required by MSVC only, as a workaround for a
00138        * very awful bug, which exists since MSVC V.4.0, and still by
00139        * V.6.0 with all bugfixes (so called "service packs") remains
00140        * there...  This method is also public due to another bug, so please
00141        * NEVER EVER call this method directly: use read() instead
00142        */
00143       bool readMS(ioHandler& handler,const bool complete=true);
00144 
00145       /**
00146        * this function is required by MSVC only, as a workaround for a
00147        * very awful bug, which exists since MSVC V.4.0, and still by
00148        * V.6.0 with all bugfixes (so called "service packs") remains
00149        * there...  This method is also public due to another bug, so please
00150        * NEVER EVER call this method directly: use write() instead
00151        */
00152       bool writeMS(ioHandler& handler,const bool complete=true) const;
00153 #     endif
00154 
00155       // ------------------------------------------------
00156       // the parameters
00157       // ------------------------------------------------
00158 
00159       /**
00160        * Variance for the Gaussian to smooth the image.
00161        * (see also gaussKernel1D<ubyte>::gaussKernel1D())
00162        *
00163        * Default value: 1.0
00164        */
00165       float variance;
00166 
00167       /**
00168        * Size of the Gaussian kernel used to smooth the image
00169        *(see also variance).
00170        *
00171        * Set to zero if you don't want any smoothing.
00172        *
00173        * Default value: 7
00174        */
00175       int kernelSize;
00176 
00177       /**
00178        * If a pixel is detected as part of an edge (a response higher
00179        * than thresholdMax), its neighbors are consider also edges if their
00180        * values are higher than the given percentage of thresholdMax
00181        * (i.e. higher than thresholdMax*thresholdMin)
00182        *
00183        * This value must be between 0.0 and 1.0
00184        *
00185        * Default Value: 0.5
00186        */
00187       float thresholdMin;
00188 
00189       /**
00190        * If an edge response is higher than this value, those pixels will be
00191        * definite an edge.  This value MUST be between 0 and 1.0.
00192        *
00193        * Please note that the older value range between 0 and 255 is 
00194        * deprecated.
00195        *
00196        * Default Value: 0.04f;
00197        */
00198       float thresholdMax;
00199 
00200       /**
00201        * Parameters for gradient computation. 
00202        *
00203        * To provide more alternatives to the gradient computation, the
00204        * lti::gradientFunctor is used.  Here you can select all options
00205        * available for that functor.
00206        *
00207        * The default behaviour is to use the
00208        * lti::gradientFunctor::parameters::Difference kernel, which is the
00209        * fastest but also the less precise.  You can use the optimal
00210        * kernels if you require a more stable orientation detection.
00211        *
00212        * Default value: Difference mode (fast gradient computation)
00213        *
00214        * @see lti::gradientFunctor
00215        */
00216       colorContrastGradient::parameters gradientParameters;
00217     };
00218 
00219     /**
00220      * default constructor
00221      */
00222     cannyEdges();
00223 
00224     /**
00225      * constructor with parameters
00226      */
00227     cannyEdges(const parameters& thePars);
00228 
00229     /**
00230      * copy constructor
00231      * @param other the object to be copied
00232      */
00233     cannyEdges(const cannyEdges& other);
00234 
00235     /**
00236      * destructor
00237      */
00238     virtual ~cannyEdges();
00239 
00240     /**
00241      * returns the name of this type ("cannyEdges")
00242      */
00243     virtual const char* getTypeName() const;
00244 
00245     /**
00246      * operates on the given %parameter.
00247      * @param srcdest channel8 with the source data.  The result
00248      *                 will be left here too.
00249      * @return true if apply successful or false otherwise.
00250      */
00251     virtual bool apply(channel8& srcdest) const;
00252 
00253     /**
00254      * operates on the given %parameter.
00255      * @param srcdest channel with the source data.  The result
00256      *                 will be left here too.
00257      * @return true if apply successful or false otherwise.
00258      */
00259     virtual bool apply(channel& srcdest) const;
00260 
00261     /**
00262      * operates on a copy of the given %parameters.  This one is the fastest,
00263      * because it won't require casting the channel to any other type.
00264      *
00265      * @param src channel8 with the source data.
00266      * @param dest channel8 where the result will be left.
00267      * @return true if apply successful or false otherwise.
00268      */
00269     virtual bool apply(const channel8& src,channel8& dest) const;
00270 
00271     /**
00272      * compute the canny edges for the given source channel.
00273      * The found edges will be left on the edges channel, and the
00274      * orientation angle of the edges (that can be used in other functors, like
00275      * the hough transform) is left on the orientation channel.
00276      *
00277      * @param src channel8 with the source data.
00278      * @param edges channel8 where the result will be left.
00279      * @param orientation channel where the orientation for the channel will
00280      *        be left.
00281      * @return true if apply successful or false otherwise.
00282      */
00283     virtual bool apply(const channel8& src,
00284                              channel8& edges,
00285                              channel& orientation) const;
00286 
00287 
00288     /**
00289      * operates on a copy of the given %parameters.
00290      * @param src channel with the source data.
00291      * @param dest channel where the result will be left.
00292      * @return true if apply successful or false otherwise.
00293      */
00294     virtual bool apply(const channel& src,channel& dest) const;
00295 
00296 
00297     /**
00298      * operates on a copy of the given %parameters.
00299      * @param src channel with the source data.
00300      * @param dest channel where the result will be left.
00301      * @return true if apply successful or false otherwise.
00302      */
00303     virtual bool apply(const channel& src,channel8& dest) const;
00304 
00305     /**
00306      * compute the canny edges for the given source channel.
00307      * The found edges will be left on the edges channel, and the
00308      * orientation angle of the edges (that can be used in other functors, like
00309      * the hough transform) is left on the orientation channel.
00310      *
00311      * @param src channel with the source data.
00312      * @param edges channel8 where the result will be left.
00313      * @param orientation channel where the orientation for the channel will
00314      *        be left.
00315      * @return true if apply successful or false otherwise.
00316      */
00317     virtual bool apply(const channel& src,
00318                              channel8& edges,
00319                              channel& orientation) const;
00320 
00321     /**
00322      * Strictly speaking, this method does not do a Canny Edge
00323      * Detection any more, but, because of the strong similarity with
00324      * the Canny later stages, it is provided here.
00325      *
00326      * The problem lies in the definition of the "gradient" for a
00327      * color channel.  Here, the approach introduced in A. Cumani,
00328      * "Edge Detection in Multispectral Images", Technical Report,
00329      * Istituto Elettrotecnico Nazionale "Galileo Ferraris", 1989 is
00330      * followed.
00331      *
00332      * With this approach, instead of the usual gradient, the maxima of the
00333      * contrast function are searched.  The contrast function defines
00334      * the direction in the (x,y) plane at which the contrast change is
00335      * maximal.  See lti::colorContrastGradient for more information.
00336      *
00337      * The Canny-typical non-maxima suppression procedure is applied on the
00338      * contrast result.
00339      *
00340      * @param src image with the source data.
00341      * @param dest channel where the result will be left.
00342      * @return true if apply successful or false otherwise.
00343      */
00344     virtual bool apply(const image& src,channel8& dest) const;
00345 
00346     /**
00347      * operates on a copy of the given %parameters.
00348      * @param src image with the source data.
00349      * @param dest channel where the result will be left.
00350      * @param orientation channel where the orientation for the channel will
00351      *        be left.
00352      * @return true if apply successful or false otherwise.
00353      */
00354     virtual bool apply(const image& src,
00355                              channel8& dest,
00356                              channel& orientation) const;
00357 
00358     /**
00359      * Compute the edges for the red, green and blue components of the image
00360      * and leave the result in each channel of image.
00361      * @param srcdest image with the source data.  The result
00362      *                will be left here too.
00363      * @return true if apply successful or false otherwise.
00364      */
00365     virtual bool apply(image& srcdest) const;
00366 
00367     /**
00368      * Compute the edges for the red, green and blue components of the image
00369      * and leave the result in each channel of the destination image.
00370      * @param src image with the source data.
00371      * @param dest image where the result will be left.
00372      * @return true if apply successful or false otherwise.
00373      */
00374     virtual bool apply(const image& src,image& dest) const;
00375 
00376     /**
00377      * Strictly speaking, this method does not do a Canny Edge
00378      * Detection any more, but, because of the strong similarity with
00379      * the Canny later stages, it is provided here.
00380      *
00381      * The problem lies in the definition of the "gradient" for a
00382      * color channel.  Here, the approach introduced in A. Cumani,
00383      * "Edge Detection in Multispectral Images", Technical Report,
00384      * Istituto Elettrotecnico Nazionale "Galileo Ferraris", 1989 is
00385      * followed.
00386      *
00387      * With this approach, instead of the usual gradient, the maxima of the
00388      * contrast function are searched.  The contrast function defines
00389      * the direction in the (x,y) plane at which the contrast change is
00390      * maximal.  See lti::colorContrastGradient for more information.
00391      *
00392      * The Canny-typical non-maxima suppression procedure is applied on the
00393      * contrast result.
00394      *
00395      * @param c1 first channel
00396      * @param c2 second channel
00397      * @param c3 third channel
00398      * @param edges the found edges
00399      * @param orientation orientation of the found angles.
00400      * @return true if apply successful or false otherwise.
00401      */
00402     virtual bool apply(const channel& c1,
00403                        const channel& c2,
00404                        const channel& c3,
00405                        channel8& edges,
00406                        channel& orientation) const;
00407 
00408     /**
00409      * copy data of "other" functor.
00410      * @param other the functor to be copied
00411      * @return a reference to this functor object
00412      */
00413     cannyEdges& copy(const cannyEdges& other);
00414 
00415     /**
00416      * alias for copy member
00417      * @param other the functor to be copied
00418      * @return a reference to this functor object
00419      */
00420     cannyEdges& operator=(const cannyEdges& other);
00421 
00422     /**
00423      * returns a pointer to a clone of this functor.
00424      */
00425     virtual functor* clone() const;
00426 
00427     /**
00428      * set functor's parameters.
00429      * This member makes a copy of <em>theParam</em>: the functor
00430      * will keep its own copy of the parameters!
00431      * @return true if successful, false otherwise
00432      */
00433     virtual bool updateParameters();
00434 
00435     /**
00436      * returns used parameters
00437      */
00438     const parameters& getParameters() const;
00439 
00440   private:
00441     
00442     /**
00443      * non maxima suppression functor
00444      */
00445     nonMaximaSuppression suppressor;
00446 
00447     /**
00448      * Look-Up Table for the computations of atan2
00449      */
00450     arctanLUT atan2;
00451 
00452     /**
00453      * convert a pair of values in cartesic system into a pair in
00454      * polar system
00455      *
00456      * The LUT takes care that the returned value lies between 0 and 2*Pi
00457      */
00458     inline void cartToPolar(const int dx,const int dy,
00459                             float& mag,float& angle) const;
00460 
00461     /**
00462      * The gradient functor used
00463      */
00464     colorContrastGradient grad;
00465 
00466   };
00467 }
00468 
00469 #endif

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