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