VIGRA - vigra/cornerdetection.hxx Source File

[ VIGRA Homepage | Class Index | Function Index | File Index | 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.5.0, Dec 07 2006 )                                    */
    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 /*        koethe@informatik.uni-hamburg.de          or                  */
    00012 /*        vigra@kogs1.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     \link CommonConvolutionFilters#structureTensor structureTensor\endlink().
    00159     Then the entries of the structure tensor are combined as
    00160
    00161     \f[
    00162         \mbox{\rm CornerResponse} = \mbox{\rm det(StructureTensor)} - 0.04 \mbox{\rm tr(StructureTensor)}^2
    00163         = A B - C^2 - 0.04 (A + B)^2
    00164     \f]
    00165
    00166     The local maxima of the corner response denote the corners in the gray level
    00167     image.
    00168
    00169     The source value type must be a linaer algebra, i.e. addition, subtraction, and
    00170     multiplication with itself, multiplication with doubles and
    00171     \ref NumericTraits "NumericTraits" must
    00172     be defined.
    00173
    00174     <b> Declarations:</b>
    00175
    00176     pass arguments explicitly:
    00177     \code
    00178     namespace vigra {
    00179         template <class SrcIterator, class SrcAccessor,
    00180                   class DestIterator, class DestAccessor>
    00181         void
    00182         cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00183                                DestIterator dul, DestAccessor ad,
    00184                                double scale)
    00185     }
    00186     \endcode
    00187
    00188     use argument objects in conjunction with \ref ArgumentObjectFactories:
    00189     \code
    00190     namespace vigra {
    00191         template <class SrcIterator, class SrcAccessor,
    00192                   class DestIterator, class DestAccessor>
    00193         inline
    00194         void cornerResponseFunction(
    00195                    triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00196                    pair<DestIterator, DestAccessor> dest,
    00197                    double scale)
    00198     }
    00199     \endcode
    00200
    00201     <b> Usage:</b>
    00202
    00203         <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>"<br>
    00204     Namespace: vigra
    00205
    00206     \code
    00207     vigra::BImage src(w,h), corners(w,h);
    00208     vigra::FImage corner_response(w,h);
    00209
    00210     // empty corner image
    00211     corners.init(0.0);
    00212     ...
    00213
    00214     // find corner response at scale 1.0
    00215     vigra::cornerResponseFunction(srcImageRange(src), destImage(corner_response),
    00216                            1.0);
    00217
    00218     // find local maxima of corner response, mark with 1
    00219     vigra::localMaxima(srcImageRange(corner_response), destImage(corners));
    00220
    00221     // threshold corner response to keep only strong corners (above 400.0)
    00222     transformImage(srcImageRange(corner_response), destImage(corner_response),
    00223           vigra::Threshold<double, double>(
    00224                400.0, std::numeric_limits<double>::max(), 0.0, 1.0));
    00225
    00226     // combine thresholding and local maxima
    00227     vigra::combineTwoImages(srcImageRange(corners), srcImage(corner_response),
    00228                      destImage(corners), std::multiplies<float>());
    00229     \endcode
    00230
    00231     <b> Required Interface:</b>
    00232
    00233     \code
    00234     SrcImageIterator src_upperleft, src_lowerright;
    00235     DestImageIterator dest_upperleft;
    00236
    00237     SrcAccessor src_accessor;
    00238     DestAccessor dest_accessor;
    00239
    00240     SrcAccessor::value_type u = src_accessor(src_upperleft);
    00241     double d;
    00242
    00243     u = u + u
    00244     u = u - u
    00245     u = u * u
    00246     u = d * u
    00247
    00248     dest_accessor.set(u, dest_upperleft);
    00249     \endcode
    00250 */
    00251 template <class SrcIterator, class SrcAccessor,
    00252           class DestIterator, class DestAccessor>
    00253 void
    00254 cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00255                        DestIterator dul, DestAccessor ad,
    00256                        double scale)
    00257 {
    00258     vigra_precondition(scale > 0.0,
    00259                  "cornerResponseFunction(): Scale must be > 0");
    00260
    00261     int w = slr.x - sul.x;
    00262     int h = slr.y - sul.y;
    00263
    00264     if(w <= 0 || h <= 0) return;
    00265
    00266     typedef typename
    00267         NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
    00268
    00269     typedef BasicImage<TmpType> TmpImage;
    00270
    00271     TmpImage gx(w,h);
    00272     TmpImage gy(w,h);
    00273     TmpImage gxy(w,h);
    00274
    00275     structureTensor(srcIterRange(sul, slr, as),
    00276                     destImage(gx), destImage(gxy), destImage(gy),
    00277                     scale, scale);
    00278     CornerResponseFunctor<typename SrcAccessor::value_type > cf;
    00279
    00280     combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy),
    00281                        destIter(dul, ad), cf );
    00282 }
    00283
    00284 template <class SrcIterator, class SrcAccessor,
    00285           class DestIterator, class DestAccessor>
    00286 inline
    00287 void cornerResponseFunction(
    00288            triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00289            pair<DestIterator, DestAccessor> dest,
    00290            double scale)
    00291 {
    00292     cornerResponseFunction(src.first, src.second, src.third,
    00293                             dest.first, dest.second,
    00294                             scale);
    00295 }
    00296
    00297 /********************************************************/
    00298 /*                                                      */
    00299 /*               foerstnerCornerDetector                */
    00300 /*                                                      */
    00301 /********************************************************/
    00302
    00303 /** \brief Find corners in an image (2).
    00304
    00305     This algorithm implements the so called 'Foerstner Corner Detector'
    00306     to measure the 'cornerness' of each pixel in the image, according to
    00307     [W. F&ouml;rstner: <em> "A feature based correspondence algorithms for image
    00308     matching"</em>, Intl. Arch. Photogrammetry and Remote Sensing, vol. 24, pp 160-166,
    00309     1986]. It is also known as the "Plessey Detector" by Harris. However, it should not
    00310     be confused with the
    00311     "\link CornerDetection#cornerResponseFunction Corner Repsonse Function\endlink ",
    00312     another detector invented by Harris.
    00313
    00314     The algorithm first determines the structure tensor at each pixel by calling
    00315     \link CommonConvolutionFilters#structureTensor structureTensor\endlink().
    00316     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
    00325     \link CornerDetection#cornerResponseFunction cornerResponseFunction\endlink().
    00326
    00327     The source value type must be a division algebra, i.e. addition, subtraction,
    00328     multiplication, and division with itself, multiplication with doubles and
    00329     \ref NumericTraits "NumericTraits" must
    00330     be defined.
    00331
    00332     <b> Declarations:</b>
    00333
    00334     pass arguments explicitly:
    00335     \code
    00336     namespace vigra {
    00337         template <class SrcIterator, class SrcAccessor,
    00338                   class DestIterator, class DestAccessor>
    00339         void
    00340         foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00341                                DestIterator dul, DestAccessor ad,
    00342                                double scale)
    00343     }
    00344     \endcode
    00345
    00346     use argument objects in conjunction with \ref ArgumentObjectFactories:
    00347     \code
    00348     namespace vigra {
    00349         template <class SrcIterator, class SrcAccessor,
    00350                   class DestIterator, class DestAccessor>
    00351         inline
    00352         void foerstnerCornerDetector(
    00353                    triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00354                    pair<DestIterator, DestAccessor> dest,
    00355                    double scale)
    00356     }
    00357     \endcode
    00358
    00359     <b> Usage:</b>
    00360
    00361         <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>"<br>
    00362     Namespace: vigra
    00363
    00364     \code
    00365     vigra::BImage src(w,h), corners(w,h);
    00366     vigra::FImage foerstner_corner_strength(w,h);
    00367
    00368     // empty corner image
    00369     corners.init(0.0);
    00370     ...
    00371
    00372     // find corner response at scale 1.0
    00373     vigra::foerstnerCornerDetector(srcImageRange(src), destImage(foerstner_corner_strength),
    00374                                    1.0);
    00375
    00376     // find local maxima of corner response, mark with 1
    00377     vigra::localMaxima(srcImageRange(foerstner_corner_strength), destImage(corners));
    00378     \endcode
    00379
    00380     <b> Required Interface:</b>
    00381
    00382     \code
    00383     SrcImageIterator src_upperleft, src_lowerright;
    00384     DestImageIterator dest_upperleft;
    00385
    00386     SrcAccessor src_accessor;
    00387     DestAccessor dest_accessor;
    00388
    00389     SrcAccessor::value_type u = src_accessor(src_upperleft);
    00390     double d;
    00391
    00392     u = u + u
    00393     u = u - u
    00394     u = u * u
    00395     u = u / u
    00396     u = d * u
    00397
    00398     dest_accessor.set(u, dest_upperleft);
    00399     \endcode
    00400 */
    00401 template <class SrcIterator, class SrcAccessor,
    00402           class DestIterator, class DestAccessor>
    00403 void
    00404 foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00405                        DestIterator dul, DestAccessor ad,
    00406                        double scale)
    00407 {
    00408     vigra_precondition(scale > 0.0,
    00409                  "foerstnerCornerDetector(): Scale must be > 0");
    00410
    00411     int w = slr.x - sul.x;
    00412     int h = slr.y - sul.y;
    00413
    00414     if(w <= 0 || h <= 0) return;
    00415
    00416     typedef typename
    00417         NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
    00418
    00419     typedef BasicImage<TmpType> TmpImage;
    00420
    00421     TmpImage gx(w,h);
    00422     TmpImage gy(w,h);
    00423     TmpImage gxy(w,h);
    00424
    00425     structureTensor(srcIterRange(sul, slr, as),
    00426                     destImage(gx), destImage(gxy), destImage(gy),
    00427                     scale, scale);
    00428     FoerstnerCornerFunctor<typename SrcAccessor::value_type > cf;
    00429
    00430     combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy),
    00431                        destIter(dul, ad), cf );
    00432 }
    00433
    00434 template <class SrcIterator, class SrcAccessor,
    00435           class DestIterator, class DestAccessor>
    00436 inline
    00437 void foerstnerCornerDetector(
    00438            triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00439            pair<DestIterator, DestAccessor> dest,
    00440            double scale)
    00441 {
    00442     foerstnerCornerDetector(src.first, src.second, src.third,
    00443                             dest.first, dest.second,
    00444                             scale);
    00445 }
    00446
    00447 /********************************************************/
    00448 /*                                                      */
    00449 /*                   rohrCornerDetector                 */
    00450 /*                                                      */
    00451 /********************************************************/
    00452
    00453 /** \brief Find corners in an image (3).
    00454
    00455     This algorithm implements yet another structure tensor-based corner detector,
    00456     according to [K. Rohr: <em>"Untersuchung von grauwertabh&auml;ngigen
    00457     Transformationen zur Ermittlung der optischen Flusses in Bildfolgen"</em>,
    00458     Diploma thesis, Inst. f&uuml;r Nachrichtensysteme, Univ. Karlsruhe, 1987, see also
    00459     K. Rohr: <em>"Modelling and Identification of Characteristic Intensity Variations"</em>,
    00460     Image and Vision Computing 10:2 (1992) 66-76 and K. Rohr: <em>"Localization Properties of
    00461     Direct Corner Detectors"</em>, J. of Mathematical Imaging and Vision 4:2 (1994) 139-150].
    00462
    00463     The algorithm first determines the structure tensor at each pixel by calling
    00464     \link CommonConvolutionFilters#structureTensor structureTensor\endlink().
    00465     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
    00473     \link CornerDetection#cornerResponseFunction cornerResponseFunction\endlink().
    00474
    00475     The source value type must be a linear algebra, i.e. addition, subtraction, and
    00476     multiplication with itself, multiplication with doubles and
    00477     \ref NumericTraits "NumericTraits" must
    00478     be defined.
    00479
    00480     <b> Declarations:</b>
    00481
    00482     pass arguments explicitly:
    00483     \code
    00484     namespace vigra {
    00485         template <class SrcIterator, class SrcAccessor,
    00486                   class DestIterator, class DestAccessor>
    00487         void
    00488         rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00489                            DestIterator dul, DestAccessor ad,
    00490                            double scale)
    00491     }
    00492     \endcode
    00493
    00494     use argument objects in conjunction with \ref ArgumentObjectFactories:
    00495     \code
    00496     namespace vigra {
    00497         template <class SrcIterator, class SrcAccessor,
    00498                   class DestIterator, class DestAccessor>
    00499         inline
    00500         void rohrCornerDetector(
    00501                    triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00502                    pair<DestIterator, DestAccessor> dest,
    00503                    double scale)
    00504     }
    00505     \endcode
    00506
    00507     <b> Usage:</b>
    00508
    00509         <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>"<br>
    00510     Namespace: vigra
    00511
    00512     \code
    00513     vigra::BImage src(w,h), corners(w,h);
    00514     vigra::FImage rohr_corner_strength(w,h);
    00515
    00516     // empty corner image
    00517     corners.init(0.0);
    00518     ...
    00519
    00520     // find corner response at scale 1.0
    00521     vigra::rohrCornerDetector(srcImageRange(src), destImage(rohr_corner_strength),
    00522                               1.0);
    00523
    00524     // find local maxima of corner response, mark with 1
    00525     vigra::localMaxima(srcImageRange(rohr_corner_strength), destImage(corners));
    00526     \endcode
    00527
    00528     <b> Required Interface:</b>
    00529
    00530     \code
    00531     SrcImageIterator src_upperleft, src_lowerright;
    00532     DestImageIterator dest_upperleft;
    00533
    00534     SrcAccessor src_accessor;
    00535     DestAccessor dest_accessor;
    00536
    00537     SrcAccessor::value_type u = src_accessor(src_upperleft);
    00538     double d;
    00539
    00540     u = u + u
    00541     u = u - u
    00542     u = u * u
    00543     u = d * u
    00544
    00545     dest_accessor.set(u, dest_upperleft);
    00546     \endcode
    00547 */
    00548 template <class SrcIterator, class SrcAccessor,
    00549           class DestIterator, class DestAccessor>
    00550 void
    00551 rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00552                        DestIterator dul, DestAccessor ad,
    00553                        double scale)
    00554 {
    00555     vigra_precondition(scale > 0.0,
    00556                  "rohrCornerDetector(): Scale must be > 0");
    00557
    00558     int w = slr.x - sul.x;
    00559     int h = slr.y - sul.y;
    00560
    00561     if(w <= 0 || h <= 0) return;
    00562
    00563     typedef typename
    00564         NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
    00565
    00566     typedef BasicImage<TmpType> TmpImage;
    00567
    00568     TmpImage gx(w,h);
    00569     TmpImage gy(w,h);
    00570     TmpImage gxy(w,h);
    00571
    00572     structureTensor(srcIterRange(sul, slr, as),
    00573                     destImage(gx), destImage(gxy), destImage(gy),
    00574                     scale, scale);
    00575     RohrCornerFunctor<typename SrcAccessor::value_type > cf;
    00576
    00577     combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy),
    00578                        destIter(dul, ad), cf );
    00579 }
    00580
    00581 template <class SrcIterator, class SrcAccessor,
    00582           class DestIterator, class DestAccessor>
    00583 inline
    00584 void rohrCornerDetector(
    00585            triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00586            pair<DestIterator, DestAccessor> dest,
    00587            double scale)
    00588 {
    00589     rohrCornerDetector(src.first, src.second, src.third,
    00590                             dest.first, dest.second,
    00591                             scale);
    00592 }
    00593
    00594 /********************************************************/
    00595 /*                                                      */
    00596 /*                 beaudetCornerDetector                */
    00597 /*                                                      */
    00598 /********************************************************/
    00599
    00600 /** \brief Find corners in an image (4).
    00601
    00602     This algorithm implements a corner detector
    00603     according to [P.R. Beaudet: <em> "Rotationally Invariant Image Operators"</em>,
    00604     Proc. Intl. Joint Conf. on Pattern Recognition, Kyoto, Japan, 1978, pp. 579-583].
    00605
    00606     The algorithm calculates the corner strength as the negative determinant of the
    00607     \link CommonConvolutionFilters#hessianMatrixOfGaussian Hessian Matrix\endlink.
    00608     The local maxima of the corner strength denote the corners in the gray level
    00609     image.
    00610
    00611     The source value type must be a linear algebra, i.e. addition, subtraction, and
    00612     multiplication with itself, multiplication with doubles and
    00613     \ref NumericTraits "NumericTraits" must
    00614     be defined.
    00615
    00616     <b> Declarations:</b>
    00617
    00618     pass arguments explicitly:
    00619     \code
    00620     namespace vigra {
    00621         template <class SrcIterator, class SrcAccessor,
    00622                   class DestIterator, class DestAccessor>
    00623         void
    00624         beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00625                            DestIterator dul, DestAccessor ad,
    00626                            double scale)
    00627     }
    00628     \endcode
    00629
    00630     use argument objects in conjunction with \ref ArgumentObjectFactories:
    00631     \code
    00632     namespace vigra {
    00633         template <class SrcIterator, class SrcAccessor,
    00634                   class DestIterator, class DestAccessor>
    00635         inline
    00636         void beaudetCornerDetector(
    00637                    triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00638                    pair<DestIterator, DestAccessor> dest,
    00639                    double scale)
    00640     }
    00641     \endcode
    00642
    00643     <b> Usage:</b>
    00644
    00645         <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>"<br>
    00646     Namespace: vigra
    00647
    00648     \code
    00649     vigra::BImage src(w,h), corners(w,h);
    00650     vigra::FImage beaudet_corner_strength(w,h);
    00651
    00652     // empty corner image
    00653     corners.init(0.0);
    00654     ...
    00655
    00656     // find corner response at scale 1.0
    00657     vigra::beaudetCornerDetector(srcImageRange(src), destImage(beaudet_corner_strength),
    00658                               1.0);
    00659
    00660     // find local maxima of corner response, mark with 1
    00661     vigra::localMaxima(srcImageRange(beaudet_corner_strength), destImage(corners));
    00662     \endcode
    00663
    00664     <b> Required Interface:</b>
    00665
    00666     \code
    00667     SrcImageIterator src_upperleft, src_lowerright;
    00668     DestImageIterator dest_upperleft;
    00669
    00670     SrcAccessor src_accessor;
    00671     DestAccessor dest_accessor;
    00672
    00673     SrcAccessor::value_type u = src_accessor(src_upperleft);
    00674     double d;
    00675
    00676     u = u + u
    00677     u = u - u
    00678     u = u * u
    00679     u = d * u
    00680
    00681     dest_accessor.set(u, dest_upperleft);
    00682     \endcode
    00683 */
    00684 template <class SrcIterator, class SrcAccessor,
    00685           class DestIterator, class DestAccessor>
    00686 void
    00687 beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00688                        DestIterator dul, DestAccessor ad,
    00689                        double scale)
    00690 {
    00691     vigra_precondition(scale > 0.0,
    00692                  "beaudetCornerDetector(): Scale must be > 0");
    00693
    00694     int w = slr.x - sul.x;
    00695     int h = slr.y - sul.y;
    00696
    00697     if(w <= 0 || h <= 0) return;
    00698
    00699     typedef typename
    00700         NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
    00701
    00702     typedef BasicImage<TmpType> TmpImage;
    00703
    00704     TmpImage gx(w,h);
    00705     TmpImage gy(w,h);
    00706     TmpImage gxy(w,h);
    00707
    00708     hessianMatrixOfGaussian(srcIterRange(sul, slr, as),
    00709                     destImage(gx), destImage(gxy), destImage(gy),
    00710                     scale);
    00711     BeaudetCornerFunctor<typename SrcAccessor::value_type > cf;
    00712
    00713     combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy),
    00714                        destIter(dul, ad), cf );
    00715 }
    00716
    00717 template <class SrcIterator, class SrcAccessor,
    00718           class DestIterator, class DestAccessor>
    00719 inline
    00720 void beaudetCornerDetector(
    00721            triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00722            pair<DestIterator, DestAccessor> dest,
    00723            double scale)
    00724 {
    00725     beaudetCornerDetector(src.first, src.second, src.third,
    00726                             dest.first, dest.second,
    00727                             scale);
    00728 }
    00729
    00730
    00731 //@}
    00732
    00733 } // namespace vigra
    00734
    00735 #endif // VIGRA_CORNERDETECTION_HXX

© Ullrich Köthe (koethe@informatik.uni-hamburg.de) Cognitive Systems Group, University of Hamburg, Germany | html generated using doxygen and Python VIGRA 1.5.0 (7 Dec 2006)