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

vigra/cornerdetection.hxx |

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