VIGRA - VIGRA: vigra/cornerdetection.hxx Source File

[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

# vigra/cornerdetection.hxx

    00001 /************************************************************************/
    00002 /*                                                                      */
    00003 /*               Copyright 1998-2004 by Ullrich Koethe                  */
    00004 /*       Cognitive Systems Group, University of Hamburg, Germany        */
    00005 /*                                                                      */
    00006 /*    This file is part of the VIGRA computer vision library.           */
    00007 /*    ( Version 1.6.0, Aug 13 2008 )                                    */
    00008 /*    The VIGRA Website is                                              */
    00009 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
    00010 /*    Please direct questions, bug reports, and contributions to        */
    00011 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
    00012 /*        vigra@informatik.uni-hamburg.de                               */
    00013 /*                                                                      */
    00014 /*    Permission is hereby granted, free of charge, to any person       */
    00015 /*    obtaining a copy of this software and associated documentation    */
    00016 /*    files (the "Software"), to deal in the Software without           */
    00017 /*    restriction, including without limitation the rights to use,      */
    00018 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
    00019 /*    sell copies of the Software, and to permit persons to whom the    */
    00020 /*    Software is furnished to do so, subject to the following          */
    00021 /*    conditions:                                                       */
    00022 /*                                                                      */
    00023 /*    The above copyright notice and this permission notice shall be    */
    00024 /*    included in all copies or substantial portions of the             */
    00025 /*    Software.                                                         */
    00026 /*                                                                      */
    00027 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
    00028 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
    00029 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
    00030 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
    00031 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
    00032 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
    00033 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
    00034 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
    00035 /*                                                                      */
    00036 /************************************************************************/
    00037
    00038
    00039 #ifndef VIGRA_CORNERDETECTION_HXX
    00040 #define VIGRA_CORNERDETECTION_HXX
    00041
    00042 #include "utilities.hxx"
    00043 #include "numerictraits.hxx"
    00044 #include "stdimage.hxx"
    00045 #include "combineimages.hxx"
    00046 #include "convolution.hxx"
    00047 #include "functortraits.hxx"
    00048
    00049 namespace vigra {
    00050
    00051 template <class SrcType>
    00052 struct CornerResponseFunctor
    00053 {
    00054     typedef typename NumericTraits<SrcType>::RealPromote argument_type;
    00055     typedef argument_type result_type;
    00056
    00057     result_type operator()(argument_type a1,
    00058                         argument_type a2, argument_type a3) const
    00059     {
    00060         return (a1*a2 - a3*a3) - 0.04 * (a1 + a2) * (a1 + a2);
    00061     }
    00062 };
    00063
    00064 template <class T>
    00065 class FunctorTraits<CornerResponseFunctor<T> >
    00066 : public FunctorTraitsBase<CornerResponseFunctor<T> >
    00067 {
    00068   public:
    00069     typedef VigraTrueType isTernaryFunctor;
    00070 };
    00071
    00072 template <class SrcType>
    00073 struct FoerstnerCornerFunctor
    00074 {
    00075     typedef typename NumericTraits<SrcType>::RealPromote argument_type;
    00076     typedef argument_type result_type;
    00077
    00078     result_type operator()(argument_type a1,
    00079                            argument_type a2, argument_type a3) const
    00080     {
    00081         return (a1*a2 - a3*a3) / (a1 + a2);
    00082     }
    00083 };
    00084
    00085 template <class T>
    00086 class FunctorTraits<FoerstnerCornerFunctor<T> >
    00087 : public FunctorTraitsBase<FoerstnerCornerFunctor<T> >
    00088 {
    00089   public:
    00090     typedef VigraTrueType isTernaryFunctor;
    00091 };
    00092
    00093 template <class SrcType>
    00094 struct RohrCornerFunctor
    00095 {
    00096     typedef typename NumericTraits<SrcType>::RealPromote argument_type;
    00097     typedef argument_type result_type;
    00098
    00099     result_type operator()(argument_type a1,
    00100                         argument_type a2, argument_type a3) const
    00101     {
    00102         return (a1*a2 - a3*a3);
    00103     }
    00104 };
    00105
    00106 template <class T>
    00107 class FunctorTraits<RohrCornerFunctor<T> >
    00108 : public FunctorTraitsBase<RohrCornerFunctor<T> >
    00109 {
    00110   public:
    00111     typedef VigraTrueType isTernaryFunctor;
    00112 };
    00113
    00114 template <class SrcType>
    00115 struct BeaudetCornerFunctor
    00116 {
    00117     typedef typename NumericTraits<SrcType>::RealPromote argument_type;
    00118     typedef argument_type result_type;
    00119
    00120     result_type operator()(argument_type a1,
    00121                         argument_type a2, argument_type a3) const
    00122     {
    00123         return (a3*a3 - a1*a2);
    00124     }
    00125 };
    00126
    00127 template <class T>
    00128 class FunctorTraits<BeaudetCornerFunctor<T> >
    00129 : public FunctorTraitsBase<BeaudetCornerFunctor<T> >
    00130 {
    00131   public:
    00132     typedef VigraTrueType isTernaryFunctor;
    00133 };
    00134
    00135 /** \addtogroup CornerDetection Corner Detection
    00136     Measure the 'cornerness' at each pixel.
    00137     Note: The Kitchen-Rosenfeld detector is not implemented because of its
    00138     inferior performance. The SUSAN detector is missing because it's patented.
    00139 */
    00140 //@{
    00141
    00142 /********************************************************/
    00143 /*                                                      */
    00144 /*                 cornerResponseFunction               */
    00145 /*                                                      */
    00146 /********************************************************/
    00147
    00148 /** \brief Find corners in an image (1).
    00149
    00150     This algorithm implements the so called 'corner response function'
    00151     to measure the 'cornerness' of each pixel in the image, according to
    00152     [C.G. Harris and M.J. Stevens: <em> "A Combined Corner and Edge Detector"</em>,
    00153     Proc. of 4th Alvey Vision Conference, 1988]. Several studies have found this to be a
    00154     very robust corner detector, although it moves the corners somewhat into one
    00155     region, depending on the scale.
    00156
    00157     The algorithm first determines the structure tensor at each pixel by calling
    00158     \ref structureTensor(). Then the entries of the structure tensor are combined as
    00159
    00160     \f[
    00161         \mbox{\rm CornerResponse} = \mbox{\rm det(StructureTensor)} - 0.04 \mbox{\rm tr(StructureTensor)}^2
    00162         = A B - C^2 - 0.04 (A + B)^2
    00163     \f]
    00164
    00165     The local maxima of the corner response denote the corners in the gray level
    00166     image.
    00167
    00168     The source value type must be a linaer algebra, i.e. addition, subtraction, and
    00169     multiplication with itself, multiplication with doubles and
    00170     \ref NumericTraits "NumericTraits" must
    00171     be defined.
    00172
    00173     <b> Declarations:</b>
    00174
    00175     pass arguments explicitly:
    00176     \code
    00177     namespace vigra {
    00178         template <class SrcIterator, class SrcAccessor,
    00179                   class DestIterator, class DestAccessor>
    00180         void
    00181         cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00182                                DestIterator dul, DestAccessor ad,
    00183                                double scale)
    00184     }
    00185     \endcode
    00186
    00187     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00188     \code
    00189     namespace vigra {
    00190         template <class SrcIterator, class SrcAccessor,
    00191                   class DestIterator, class DestAccessor>
    00192         inline
    00193         void cornerResponseFunction(
    00194                    triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00195                    pair<DestIterator, DestAccessor> dest,
    00196                    double scale)
    00197     }
    00198     \endcode
    00199
    00200     <b> Usage:</b>
    00201
    00202         <b>\#include</b> <<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>><br>
    00203     Namespace: vigra
    00204
    00205     \code
    00206     vigra::BImage src(w,h), corners(w,h);
    00207     vigra::FImage corner_response(w,h);
    00208
    00209     // empty corner image
    00210     corners.init(0.0);
    00211     ...
    00212
    00213     // find corner response at scale 1.0
    00214     vigra::cornerResponseFunction(srcImageRange(src), destImage(corner_response),
    00215                            1.0);
    00216
    00217     // find local maxima of corner response, mark with 1
    00218     vigra::localMaxima(srcImageRange(corner_response), destImage(corners));
    00219
    00220     // threshold corner response to keep only strong corners (above 400.0)
    00221     transformImage(srcImageRange(corner_response), destImage(corner_response),
    00222           vigra::Threshold<double, double>(
    00223                400.0, std::numeric_limits<double>::max(), 0.0, 1.0));
    00224
    00225     // combine thresholding and local maxima
    00226     vigra::combineTwoImages(srcImageRange(corners), srcImage(corner_response),
    00227                      destImage(corners), std::multiplies<float>());
    00228     \endcode
    00229
    00230     <b> Required Interface:</b>
    00231
    00232     \code
    00233     SrcImageIterator src_upperleft, src_lowerright;
    00234     DestImageIterator dest_upperleft;
    00235
    00236     SrcAccessor src_accessor;
    00237     DestAccessor dest_accessor;
    00238
    00239     SrcAccessor::value_type u = src_accessor(src_upperleft);
    00240     double d;
    00241
    00242     u = u + u
    00243     u = u - u
    00244     u = u * u
    00245     u = d * u
    00246
    00247     dest_accessor.set(u, dest_upperleft);
    00248     \endcode
    00249 */
    00250 doxygen_overloaded_function(template <...> void cornerResponseFunction)
    00251
    00252 template <class SrcIterator, class SrcAccessor,
    00253           class DestIterator, class DestAccessor>
    00254 void
    00255 cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00256                        DestIterator dul, DestAccessor ad,
    00257                        double scale)
    00258 {
    00259     vigra_precondition(scale > 0.0,
    00260                  "cornerResponseFunction(): Scale must be > 0");
    00261
    00262     int w = slr.x - sul.x;
    00263     int h = slr.y - sul.y;
    00264
    00265     if(w <= 0 || h <= 0) return;
    00266
    00267     typedef typename
    00268         NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
    00269
    00270     typedef BasicImage<TmpType> TmpImage;
    00271
    00272     TmpImage gx(w,h);
    00273     TmpImage gy(w,h);
    00274     TmpImage gxy(w,h);
    00275
    00276     structureTensor(srcIterRange(sul, slr, as),
    00277                     destImage(gx), destImage(gxy), destImage(gy),
    00278                     scale, scale);
    00279     CornerResponseFunctor<typename SrcAccessor::value_type > cf;
    00280
    00281     combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy),
    00282                        destIter(dul, ad), cf );
    00283 }
    00284
    00285 template <class SrcIterator, class SrcAccessor,
    00286           class DestIterator, class DestAccessor>
    00287 inline
    00288 void cornerResponseFunction(
    00289            triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00290            pair<DestIterator, DestAccessor> dest,
    00291            double scale)
    00292 {
    00293     cornerResponseFunction(src.first, src.second, src.third,
    00294                             dest.first, dest.second,
    00295                             scale);
    00296 }
    00297
    00298 /********************************************************/
    00299 /*                                                      */
    00300 /*               foerstnerCornerDetector                */
    00301 /*                                                      */
    00302 /********************************************************/
    00303
    00304 /** \brief Find corners in an image (2).
    00305
    00306     This algorithm implements the so called 'Foerstner Corner Detector'
    00307     to measure the 'cornerness' of each pixel in the image, according to
    00308     [W. F&ouml;rstner: <em> "A feature based correspondence algorithms for image
    00309     matching"</em>, Intl. Arch. Photogrammetry and Remote Sensing, vol. 24, pp 160-166,
    00310     1986]. It is also known as the "Plessey Detector" by Harris. However, it should not
    00311     be confused with the
    00312     "\link cornerResponseFunction Corner Response Function\endlink ",
    00313     another detector invented by Harris.
    00314
    00315     The algorithm first determines the structure tensor at each pixel by calling
    00316     \ref structureTensor(). Then the entries of the structure tensor are combined as
    00317
    00318     \f[
    00319         \mbox{\rm FoerstnerCornerStrength} = \frac{\mbox{\rm det(StructureTensor)}}{\mbox{\rm tr(StructureTensor)}} =
    00320         \frac{A B - C^2}{A + B}
    00321     \f]
    00322
    00323     The local maxima of the corner strength denote the corners in the gray level
    00324     image. Its performance is similar to the \ref cornerResponseFunction().
    00325
    00326     The source value type must be a division algebra, i.e. addition, subtraction,
    00327     multiplication, and division with itself, multiplication with doubles and
    00328     \ref NumericTraits "NumericTraits" must
    00329     be defined.
    00330
    00331     <b> Declarations:</b>
    00332
    00333     pass arguments explicitly:
    00334     \code
    00335     namespace vigra {
    00336         template <class SrcIterator, class SrcAccessor,
    00337                   class DestIterator, class DestAccessor>
    00338         void
    00339         foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00340                                DestIterator dul, DestAccessor ad,
    00341                                double scale)
    00342     }
    00343     \endcode
    00344
    00345     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00346     \code
    00347     namespace vigra {
    00348         template <class SrcIterator, class SrcAccessor,
    00349                   class DestIterator, class DestAccessor>
    00350         inline
    00351         void foerstnerCornerDetector(
    00352                    triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00353                    pair<DestIterator, DestAccessor> dest,
    00354                    double scale)
    00355     }
    00356     \endcode
    00357
    00358     <b> Usage:</b>
    00359
    00360         <b>\#include</b> <<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>><br>
    00361     Namespace: vigra
    00362
    00363     \code
    00364     vigra::BImage src(w,h), corners(w,h);
    00365     vigra::FImage foerstner_corner_strength(w,h);
    00366
    00367     // empty corner image
    00368     corners.init(0.0);
    00369     ...
    00370
    00371     // find corner response at scale 1.0
    00372     vigra::foerstnerCornerDetector(srcImageRange(src), destImage(foerstner_corner_strength),
    00373                                    1.0);
    00374
    00375     // find local maxima of corner response, mark with 1
    00376     vigra::localMaxima(srcImageRange(foerstner_corner_strength), destImage(corners));
    00377     \endcode
    00378
    00379     <b> Required Interface:</b>
    00380
    00381     \code
    00382     SrcImageIterator src_upperleft, src_lowerright;
    00383     DestImageIterator dest_upperleft;
    00384
    00385     SrcAccessor src_accessor;
    00386     DestAccessor dest_accessor;
    00387
    00388     SrcAccessor::value_type u = src_accessor(src_upperleft);
    00389     double d;
    00390
    00391     u = u + u
    00392     u = u - u
    00393     u = u * u
    00394     u = u / u
    00395     u = d * u
    00396
    00397     dest_accessor.set(u, dest_upperleft);
    00398     \endcode
    00399 */
    00400 doxygen_overloaded_function(template <...> void foerstnerCornerDetector)
    00401
    00402 template <class SrcIterator, class SrcAccessor,
    00403           class DestIterator, class DestAccessor>
    00404 void
    00405 foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00406                        DestIterator dul, DestAccessor ad,
    00407                        double scale)
    00408 {
    00409     vigra_precondition(scale > 0.0,
    00410                  "foerstnerCornerDetector(): Scale must be > 0");
    00411
    00412     int w = slr.x - sul.x;
    00413     int h = slr.y - sul.y;
    00414
    00415     if(w <= 0 || h <= 0) return;
    00416
    00417     typedef typename
    00418         NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
    00419
    00420     typedef BasicImage<TmpType> TmpImage;
    00421
    00422     TmpImage gx(w,h);
    00423     TmpImage gy(w,h);
    00424     TmpImage gxy(w,h);
    00425
    00426     structureTensor(srcIterRange(sul, slr, as),
    00427                     destImage(gx), destImage(gxy), destImage(gy),
    00428                     scale, scale);
    00429     FoerstnerCornerFunctor<typename SrcAccessor::value_type > cf;
    00430
    00431     combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy),
    00432                        destIter(dul, ad), cf );
    00433 }
    00434
    00435 template <class SrcIterator, class SrcAccessor,
    00436           class DestIterator, class DestAccessor>
    00437 inline
    00438 void foerstnerCornerDetector(
    00439            triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00440            pair<DestIterator, DestAccessor> dest,
    00441            double scale)
    00442 {
    00443     foerstnerCornerDetector(src.first, src.second, src.third,
    00444                             dest.first, dest.second,
    00445                             scale);
    00446 }
    00447
    00448 /********************************************************/
    00449 /*                                                      */
    00450 /*                   rohrCornerDetector                 */
    00451 /*                                                      */
    00452 /********************************************************/
    00453
    00454 /** \brief Find corners in an image (3).
    00455
    00456     This algorithm implements yet another structure tensor-based corner detector,
    00457     according to [K. Rohr: <em>"Untersuchung von grauwertabh&auml;ngigen
    00458     Transformationen zur Ermittlung der optischen Flusses in Bildfolgen"</em>,
    00459     Diploma thesis, Inst. f&uuml;r Nachrichtensysteme, Univ. Karlsruhe, 1987, see also
    00460     K. Rohr: <em>"Modelling and Identification of Characteristic Intensity Variations"</em>,
    00461     Image and Vision Computing 10:2 (1992) 66-76 and K. Rohr: <em>"Localization Properties of
    00462     Direct Corner Detectors"</em>, J. of Mathematical Imaging and Vision 4:2 (1994) 139-150].
    00463
    00464     The algorithm first determines the structure tensor at each pixel by calling
    00465     \ref structureTensor(). Then the entries of the structure tensor are combined as
    00466
    00467     \f[
    00468         \mbox{\rm RohrCornerStrength} = \mbox{\rm det(StructureTensor)} = A B - C^2
    00469     \f]
    00470
    00471     The local maxima of the corner strength denote the corners in the gray level
    00472     image. Its performance is similar to the \ref cornerResponseFunction().
    00473
    00474     The source value type must be a linear algebra, i.e. addition, subtraction, and
    00475     multiplication with itself, multiplication with doubles and
    00476     \ref NumericTraits "NumericTraits" must
    00477     be defined.
    00478
    00479     <b> Declarations:</b>
    00480
    00481     pass arguments explicitly:
    00482     \code
    00483     namespace vigra {
    00484         template <class SrcIterator, class SrcAccessor,
    00485                   class DestIterator, class DestAccessor>
    00486         void
    00487         rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00488                            DestIterator dul, DestAccessor ad,
    00489                            double scale)
    00490     }
    00491     \endcode
    00492
    00493     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00494     \code
    00495     namespace vigra {
    00496         template <class SrcIterator, class SrcAccessor,
    00497                   class DestIterator, class DestAccessor>
    00498         inline
    00499         void rohrCornerDetector(
    00500                    triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00501                    pair<DestIterator, DestAccessor> dest,
    00502                    double scale)
    00503     }
    00504     \endcode
    00505
    00506     <b> Usage:</b>
    00507
    00508         <b>\#include</b> <<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>><br>
    00509     Namespace: vigra
    00510
    00511     \code
    00512     vigra::BImage src(w,h), corners(w,h);
    00513     vigra::FImage rohr_corner_strength(w,h);
    00514
    00515     // empty corner image
    00516     corners.init(0.0);
    00517     ...
    00518
    00519     // find corner response at scale 1.0
    00520     vigra::rohrCornerDetector(srcImageRange(src), destImage(rohr_corner_strength),
    00521                               1.0);
    00522
    00523     // find local maxima of corner response, mark with 1
    00524     vigra::localMaxima(srcImageRange(rohr_corner_strength), destImage(corners));
    00525     \endcode
    00526
    00527     <b> Required Interface:</b>
    00528
    00529     \code
    00530     SrcImageIterator src_upperleft, src_lowerright;
    00531     DestImageIterator dest_upperleft;
    00532
    00533     SrcAccessor src_accessor;
    00534     DestAccessor dest_accessor;
    00535
    00536     SrcAccessor::value_type u = src_accessor(src_upperleft);
    00537     double d;
    00538
    00539     u = u + u
    00540     u = u - u
    00541     u = u * u
    00542     u = d * u
    00543
    00544     dest_accessor.set(u, dest_upperleft);
    00545     \endcode
    00546 */
    00547 doxygen_overloaded_function(template <...> void rohrCornerDetector)
    00548
    00549 template <class SrcIterator, class SrcAccessor,
    00550           class DestIterator, class DestAccessor>
    00551 void
    00552 rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00553                        DestIterator dul, DestAccessor ad,
    00554                        double scale)
    00555 {
    00556     vigra_precondition(scale > 0.0,
    00557                  "rohrCornerDetector(): Scale must be > 0");
    00558
    00559     int w = slr.x - sul.x;
    00560     int h = slr.y - sul.y;
    00561
    00562     if(w <= 0 || h <= 0) return;
    00563
    00564     typedef typename
    00565         NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
    00566
    00567     typedef BasicImage<TmpType> TmpImage;
    00568
    00569     TmpImage gx(w,h);
    00570     TmpImage gy(w,h);
    00571     TmpImage gxy(w,h);
    00572
    00573     structureTensor(srcIterRange(sul, slr, as),
    00574                     destImage(gx), destImage(gxy), destImage(gy),
    00575                     scale, scale);
    00576     RohrCornerFunctor<typename SrcAccessor::value_type > cf;
    00577
    00578     combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy),
    00579                        destIter(dul, ad), cf );
    00580 }
    00581
    00582 template <class SrcIterator, class SrcAccessor,
    00583           class DestIterator, class DestAccessor>
    00584 inline
    00585 void rohrCornerDetector(
    00586            triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00587            pair<DestIterator, DestAccessor> dest,
    00588            double scale)
    00589 {
    00590     rohrCornerDetector(src.first, src.second, src.third,
    00591                             dest.first, dest.second,
    00592                             scale);
    00593 }
    00594
    00595 /********************************************************/
    00596 /*                                                      */
    00597 /*                 beaudetCornerDetector                */
    00598 /*                                                      */
    00599 /********************************************************/
    00600
    00601 /** \brief Find corners in an image (4).
    00602
    00603     This algorithm implements a corner detector
    00604     according to [P.R. Beaudet: <em> "Rotationally Invariant Image Operators"</em>,
    00605     Proc. Intl. Joint Conf. on Pattern Recognition, Kyoto, Japan, 1978, pp. 579-583].
    00606
    00607     The algorithm calculates the corner strength as the negative determinant of the
    00608     \link hessianMatrixOfGaussian() Hessian Matrix\endlink.
    00609     The local maxima of the corner strength denote the corners in the gray level
    00610     image.
    00611
    00612     The source value type must be a linear algebra, i.e. addition, subtraction, and
    00613     multiplication with itself, multiplication with doubles and
    00614     \ref NumericTraits "NumericTraits" must
    00615     be defined.
    00616
    00617     <b> Declarations:</b>
    00618
    00619     pass arguments explicitly:
    00620     \code
    00621     namespace vigra {
    00622         template <class SrcIterator, class SrcAccessor,
    00623                   class DestIterator, class DestAccessor>
    00624         void
    00625         beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00626                            DestIterator dul, DestAccessor ad,
    00627                            double scale)
    00628     }
    00629     \endcode
    00630
    00631     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00632     \code
    00633     namespace vigra {
    00634         template <class SrcIterator, class SrcAccessor,
    00635                   class DestIterator, class DestAccessor>
    00636         inline
    00637         void beaudetCornerDetector(
    00638                    triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00639                    pair<DestIterator, DestAccessor> dest,
    00640                    double scale)
    00641     }
    00642     \endcode
    00643
    00644     <b> Usage:</b>
    00645
    00646         <b>\#include</b> <<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>><br>
    00647     Namespace: vigra
    00648
    00649     \code
    00650     vigra::BImage src(w,h), corners(w,h);
    00651     vigra::FImage beaudet_corner_strength(w,h);
    00652
    00653     // empty corner image
    00654     corners.init(0.0);
    00655     ...
    00656
    00657     // find corner response at scale 1.0
    00658     vigra::beaudetCornerDetector(srcImageRange(src), destImage(beaudet_corner_strength),
    00659                               1.0);
    00660
    00661     // find local maxima of corner response, mark with 1
    00662     vigra::localMaxima(srcImageRange(beaudet_corner_strength), destImage(corners));
    00663     \endcode
    00664
    00665     <b> Required Interface:</b>
    00666
    00667     \code
    00668     SrcImageIterator src_upperleft, src_lowerright;
    00669     DestImageIterator dest_upperleft;
    00670
    00671     SrcAccessor src_accessor;
    00672     DestAccessor dest_accessor;
    00673
    00674     SrcAccessor::value_type u = src_accessor(src_upperleft);
    00675     double d;
    00676
    00677     u = u + u
    00678     u = u - u
    00679     u = u * u
    00680     u = d * u
    00681
    00682     dest_accessor.set(u, dest_upperleft);
    00683     \endcode
    00684 */
    00685 doxygen_overloaded_function(template <...> void beaudetCornerDetector)
    00686
    00687 template <class SrcIterator, class SrcAccessor,
    00688           class DestIterator, class DestAccessor>
    00689 void
    00690 beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00691                        DestIterator dul, DestAccessor ad,
    00692                        double scale)
    00693 {
    00694     vigra_precondition(scale > 0.0,
    00695                  "beaudetCornerDetector(): Scale must be > 0");
    00696
    00697     int w = slr.x - sul.x;
    00698     int h = slr.y - sul.y;
    00699
    00700     if(w <= 0 || h <= 0) return;
    00701
    00702     typedef typename
    00703         NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
    00704
    00705     typedef BasicImage<TmpType> TmpImage;
    00706
    00707     TmpImage gx(w,h);
    00708     TmpImage gy(w,h);
    00709     TmpImage gxy(w,h);
    00710
    00711     hessianMatrixOfGaussian(srcIterRange(sul, slr, as),
    00712                     destImage(gx), destImage(gxy), destImage(gy),
    00713                     scale);
    00714     BeaudetCornerFunctor<typename SrcAccessor::value_type > cf;
    00715
    00716     combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy),
    00717                        destIter(dul, ad), cf );
    00718 }
    00719
    00720 template <class SrcIterator, class SrcAccessor,
    00721           class DestIterator, class DestAccessor>
    00722 inline
    00723 void beaudetCornerDetector(
    00724            triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00725            pair<DestIterator, DestAccessor> dest,
    00726            double scale)
    00727 {
    00728     beaudetCornerDetector(src.first, src.second, src.third,
    00729                             dest.first, dest.second,
    00730                             scale);
    00731 }
    00732
    00733
    00734 //@}
    00735
    00736 } // namespace vigra
    00737
    00738 #endif // VIGRA_CORNERDETECTION_HXX

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python VIGRA 1.6.0 (13 Aug 2008)