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