[ 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.4.0, Dec 21 2005 )                                    */
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 /*        koethe@informatik.uni-hamburg.de          or                  */
00012 /*        vigra@kogs1.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 <vigra/utilities.hxx>
00043 #include <vigra/numerictraits.hxx>
00044 #include <vigra/stdimage.hxx>
00045 #include <vigra/combineimages.hxx>
00046 #include <vigra/convolution.hxx>
00047 #include <vigra/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     \link CommonConvolutionFilters#structureTensor structureTensor\endlink(). 
00159     Then the entries of the structure tensor are combined as 
00160     
00161     \f[
00162         \mbox{\rm CornerResponse} = \mbox{\rm det(StructureTensor)} - 0.04 \mbox{\rm tr(StructureTensor)}^2
00163         = A B - C^2 - 0.04 (A + B)^2
00164     \f]
00165     
00166     The local maxima of the corner response denote the corners in the gray level 
00167     image.
00168     
00169     The source value type must be a linaer algebra, i.e. addition, subtraction, and
00170     multiplication with itself, multiplication with doubles and 
00171     \ref NumericTraits "NumericTraits" must 
00172     be defined. 
00173     
00174     <b> Declarations:</b>
00175     
00176     pass arguments explicitly:
00177     \code
00178     namespace vigra {
00179         template <class SrcIterator, class SrcAccessor,
00180                   class DestIterator, class DestAccessor>
00181         void
00182         cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccessor as,
00183                                DestIterator dul, DestAccessor ad,
00184                                double scale)
00185     }
00186     \endcode
00187     
00188     use argument objects in conjunction with \ref ArgumentObjectFactories:
00189     \code
00190     namespace vigra {
00191         template <class SrcIterator, class SrcAccessor,
00192                   class DestIterator, class DestAccessor>
00193         inline 
00194         void cornerResponseFunction(
00195                    triple<SrcIterator, SrcIterator, SrcAccessor> src,
00196                    pair<DestIterator, DestAccessor> dest,
00197                    double scale)
00198     }
00199     \endcode
00200     
00201     <b> Usage:</b>
00202     
00203         <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>"<br>
00204     Namespace: vigra
00205     
00206     \code
00207     vigra::BImage src(w,h), corners(w,h);
00208     vigra::FImage corner_response(w,h);
00209     
00210     // empty corner image
00211     corners.init(0.0);
00212     ...
00213     
00214     // find corner response at scale 1.0
00215     vigra::cornerResponseFunction(srcImageRange(src), destImage(corner_response), 
00216                            1.0);
00217     
00218     // find local maxima of corner response, mark with 1
00219     vigra::localMaxima(srcImageRange(corner_response), destImage(corners));
00220     
00221     // threshold corner response to keep only strong corners (above 400.0)
00222     transformImage(srcImageRange(corner_response), destImage(corner_response),
00223           vigra::Threshold<double, double>(
00224                400.0, std::numeric_limits<double>::max(), 0.0, 1.0)); 
00225 
00226     // combine thresholding and local maxima
00227     vigra::combineTwoImages(srcImageRange(corners), srcImage(corner_response),
00228                      destImage(corners), std::multiplies<float>());
00229     \endcode
00230 
00231     <b> Required Interface:</b>
00232     
00233     \code
00234     SrcImageIterator src_upperleft, src_lowerright;
00235     DestImageIterator dest_upperleft;
00236     
00237     SrcAccessor src_accessor;
00238     DestAccessor dest_accessor;
00239     
00240     SrcAccessor::value_type u = src_accessor(src_upperleft);
00241     double d;
00242     
00243     u = u + u
00244     u = u - u
00245     u = u * u
00246     u = d * u
00247     
00248     dest_accessor.set(u, dest_upperleft);
00249     \endcode
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 CornerDetection#cornerResponseFunction Corner Repsonse Function\endlink ",
00312     another detector invented by Harris.
00313     
00314     The algorithm first determines the structure tensor at each pixel by calling
00315     \link CommonConvolutionFilters#structureTensor structureTensor\endlink(). 
00316     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 
00325     \link CornerDetection#cornerResponseFunction cornerResponseFunction\endlink().
00326     
00327     The source value type must be a division algebra, i.e. addition, subtraction,
00328     multiplication, and division with itself, multiplication with doubles and 
00329     \ref NumericTraits "NumericTraits" must 
00330     be defined.
00331     
00332     <b> Declarations:</b>
00333     
00334     pass arguments explicitly:
00335     \code
00336     namespace vigra {
00337         template <class SrcIterator, class SrcAccessor,
00338                   class DestIterator, class DestAccessor>
00339         void
00340         foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
00341                                DestIterator dul, DestAccessor ad,
00342                                double scale)
00343     }
00344     \endcode
00345     
00346     use argument objects in conjunction with \ref ArgumentObjectFactories:
00347     \code
00348     namespace vigra {
00349         template <class SrcIterator, class SrcAccessor,
00350                   class DestIterator, class DestAccessor>
00351         inline 
00352         void foerstnerCornerDetector(
00353                    triple<SrcIterator, SrcIterator, SrcAccessor> src,
00354                    pair<DestIterator, DestAccessor> dest,
00355                    double scale)
00356     }
00357     \endcode
00358     
00359     <b> Usage:</b>
00360     
00361         <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>"<br>
00362     Namespace: vigra
00363     
00364     \code
00365     vigra::BImage src(w,h), corners(w,h);
00366     vigra::FImage foerstner_corner_strength(w,h);
00367     
00368     // empty corner image
00369     corners.init(0.0);
00370     ...
00371     
00372     // find corner response at scale 1.0
00373     vigra::foerstnerCornerDetector(srcImageRange(src), destImage(foerstner_corner_strength), 
00374                                    1.0);
00375     
00376     // find local maxima of corner response, mark with 1
00377     vigra::localMaxima(srcImageRange(foerstner_corner_strength), destImage(corners));
00378     \endcode
00379 
00380     <b> Required Interface:</b>
00381     
00382     \code
00383     SrcImageIterator src_upperleft, src_lowerright;
00384     DestImageIterator dest_upperleft;
00385     
00386     SrcAccessor src_accessor;
00387     DestAccessor dest_accessor;
00388     
00389     SrcAccessor::value_type u = src_accessor(src_upperleft);
00390     double d;
00391     
00392     u = u + u
00393     u = u - u
00394     u = u * u
00395     u = u / u
00396     u = d * u
00397     
00398     dest_accessor.set(u, dest_upperleft);
00399     \endcode
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     \link CommonConvolutionFilters#structureTensor structureTensor\endlink(). 
00465     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 
00473     \link CornerDetection#cornerResponseFunction cornerResponseFunction\endlink().
00474     
00475     The source value type must be a linear algebra, i.e. addition, subtraction, and
00476     multiplication with itself, multiplication with doubles and 
00477     \ref NumericTraits "NumericTraits" must 
00478     be defined.
00479     
00480     <b> Declarations:</b>
00481     
00482     pass arguments explicitly:
00483     \code
00484     namespace vigra {
00485         template <class SrcIterator, class SrcAccessor,
00486                   class DestIterator, class DestAccessor>
00487         void
00488         rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
00489                            DestIterator dul, DestAccessor ad,
00490                            double scale)
00491     }
00492     \endcode
00493     
00494     use argument objects in conjunction with \ref ArgumentObjectFactories:
00495     \code
00496     namespace vigra {
00497         template <class SrcIterator, class SrcAccessor,
00498                   class DestIterator, class DestAccessor>
00499         inline 
00500         void rohrCornerDetector(
00501                    triple<SrcIterator, SrcIterator, SrcAccessor> src,
00502                    pair<DestIterator, DestAccessor> dest,
00503                    double scale)
00504     }
00505     \endcode
00506     
00507     <b> Usage:</b>
00508     
00509         <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/cornerdetection.hxx</a>"<br>
00510     Namespace: vigra
00511     
00512     \code
00513     vigra::BImage src(w,h), corners(w,h);
00514     vigra::FImage rohr_corner_strength(w,h);
00515     
00516     // empty corner image
00517     corners.init(0.0);
00518     ...
00519     
00520     // find corner response at scale 1.0
00521     vigra::rohrCornerDetector(srcImageRange(src), destImage(rohr_corner_strength), 
00522                               1.0);
00523     
00524     // find local maxima of corner response, mark with 1
00525     vigra::localMaxima(srcImageRange(rohr_corner_strength), destImage(corners));
00526     \endcode
00527 
00528     <b> Required Interface:</b>
00529     
00530     \code
00531     SrcImageIterator src_upperleft, src_lowerright;
00532     DestImageIterator dest_upperleft;
00533     
00534     SrcAccessor src_accessor;
00535     DestAccessor dest_accessor;
00536     
00537     SrcAccessor::value_type u = src_accessor(src_upperleft);
00538     double d;
00539     
00540     u = u + u
00541     u = u - u
00542     u = u * u
00543     u = d * u
00544     
00545     dest_accessor.set(u, dest_upperleft);
00546     \endcode
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 CommonConvolutionFilters#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 template <class SrcIterator, class SrcAccessor,
00685           class DestIterator, class DestAccessor>
00686 void
00687 beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
00688                        DestIterator dul, DestAccessor ad,
00689                        double scale)
00690 {
00691     vigra_precondition(scale > 0.0,
00692                  "beaudetCornerDetector(): Scale must be > 0");
00693                  
00694     int w = slr.x - sul.x;
00695     int h = slr.y - sul.y;
00696     
00697     if(w <= 0 || h <= 0) return;
00698     
00699     typedef typename 
00700         NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
00701         
00702     typedef BasicImage<TmpType> TmpImage;
00703     
00704     TmpImage gx(w,h);
00705     TmpImage gy(w,h);
00706     TmpImage gxy(w,h);
00707 
00708     hessianMatrixOfGaussian(srcIterRange(sul, slr, as), 
00709                     destImage(gx), destImage(gxy), destImage(gy), 
00710                     scale);
00711     BeaudetCornerFunctor<typename SrcAccessor::value_type > cf;
00712                     
00713     combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy), 
00714                        destIter(dul, ad), cf );
00715 }
00716 
00717 template <class SrcIterator, class SrcAccessor,
00718           class DestIterator, class DestAccessor>
00719 inline 
00720 void beaudetCornerDetector(
00721            triple<SrcIterator, SrcIterator, SrcAccessor> src,
00722            pair<DestIterator, DestAccessor> dest,
00723            double scale)
00724 {
00725     beaudetCornerDetector(src.first, src.second, src.third,
00726                             dest.first, dest.second,
00727                             scale);
00728 }
00729 
00730 
00731 //@}
00732 
00733 } // namespace vigra
00734 
00735 #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.4.0 (21 Dec 2005)