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

vigra/cornerdetection.hxx

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

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
VIGRA 1.6.0 (13 Aug 2008)