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