[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]
![]() |
vigra/cornerdetection.hxx | ![]() |
---|
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.5.0, Dec 07 2006 ) */ 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 "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 \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ö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ä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 \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) |
html generated using doxygen and Python
|