[ 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 /* 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ö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ängigen 00457 Transformationen zur Ermittlung der optischen Flusses in Bildfolgen"</em>, 00458 Diploma thesis, Inst. fü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) |
html generated using doxygen and Python
|