[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
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ö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ängigen 00458 Transformationen zur Ermittlung der optischen Flusses in Bildfolgen"</em>, 00459 Diploma thesis, Inst. fü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) |
html generated using doxygen and Python
|