[ 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 linaer 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> <<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>><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> <<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>><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> <<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>><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> <<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>><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.7.0 (Thu Aug 25 2011)