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

details vigra/cornerdetection.hxx VIGRA

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.3, Aug 18 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.3 (18 Aug 2005)