[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]
![]() |
vigra/convolution.hxx | ![]() |
---|
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 1998-2002 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.2.0, Aug 07 2003 ) */ 00008 /* You may use, modify, and distribute this software according */ 00009 /* to the terms stated in the LICENSE file included in */ 00010 /* the VIGRA distribution. */ 00011 /* */ 00012 /* The VIGRA Website is */ 00013 /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ 00014 /* Please direct questions, bug reports, and contributions to */ 00015 /* koethe@informatik.uni-hamburg.de */ 00016 /* */ 00017 /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ 00018 /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ 00019 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ 00020 /* */ 00021 /************************************************************************/ 00022 00023 00024 #ifndef VIGRA_CONVOLUTION_HXX 00025 #define VIGRA_CONVOLUTION_HXX 00026 00027 #include <functional> 00028 #include "stdconvolution.hxx" 00029 #include "vigra/separableconvolution.hxx" 00030 #include "vigra/recursiveconvolution.hxx" 00031 #include "vigra/nonlineardiffusion.hxx" 00032 #include "vigra/combineimages.hxx" 00033 00034 /** \page Convolution Functions to Convolve Images and Signals 00035 00036 1D and 2D filters, including separable and recursive convolution, and non-linear diffusion 00037 00038 <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>"<br> 00039 Namespace: vigra 00040 00041 <DL> 00042 <DT> 00043 <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00044 \ref CommonConvolutionFilters 00045 <DD><em>Short-hands for the most common convolution filters</em> 00046 <DT> 00047 <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00048 \ref BorderTreatmentMode 00049 <DD><em>Choose between different border treatment modes </em> 00050 <DT> 00051 <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00052 \ref StandardConvolution 00053 <DD><em>2D non-separable convolution, with and without ROI mask </em> 00054 <DT> 00055 <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00056 \ref vigra::Kernel2D 00057 <DD><em>Generic 2-dimensional convolution kernel </em> 00058 <DT> 00059 <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00060 \ref SeparableConvolution 00061 <DD> <em>1D convolution and separable filters in 2 dimensions </em> 00062 <DT> 00063 <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00064 \ref vigra::Kernel1D 00065 <DD> <em>Generic 1-dimensional convolution kernel </em> 00066 <DT> 00067 <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00068 \ref RecursiveConvolution 00069 <DD> <em>Recursive implementation of the exponential filter and its derivatives </em> 00070 <DT> 00071 <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00072 \ref NonLinearDiffusion 00073 <DD> <em>Edge-preserving smoothing </em> 00074 <DT> 00075 <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00076 \ref KernelArgumentObjectFactories 00077 <DD> <em>Factory functions to create argument objects to simplify passing kernels</em> 00078 </DL> 00079 */ 00080 00081 /** \page KernelArgumentObjectFactories Kernel Argument Object Factories 00082 00083 These factory functions allow to create argument objects for 1D 00084 and 2D convolution kernel analogously to 00085 \ref ArgumentObjectFactories for images. 00086 00087 \section Kernel1dFactory kernel1d() 00088 00089 Pass a \ref vigra::Kernel1D to a 1D or separable convolution algorithm. 00090 00091 These factories can be used to create argument objects when we 00092 are given instances or subclasses of \ref vigra::Kernel1D 00093 (analogous to the \ref ArgumentObjectFactories for images). 00094 These factory functions access <TT>kernel.center()</TT>, 00095 <TT>kernel.left()</TT>, <TT>kernel.right()</TT>, <TT>kernel.accessor()</TT>, 00096 and <TT>kernel.borderTreatment()</TT> to obtain the necessary 00097 information. The following factory functions are provided: 00098 00099 <table> 00100 <tr><td> 00101 \htmlonly 00102 <th bgcolor="#f0e0c0" colspan=2 align=left> 00103 \endhtmlonly 00104 <TT>\ref vigra::Kernel1D "vigra::Kernel1D<SomeType>" kernel;</TT> 00105 \htmlonly 00106 </th> 00107 \endhtmlonly 00108 </td></tr> 00109 <tr><td> 00110 <TT>kernel1d(kernel)</TT> 00111 </td><td> 00112 create argument object from information provided by 00113 kernel 00114 00115 </td></tr> 00116 <tr><td> 00117 <TT>kernel1d(kernel, vigra::BORDER_TREATMENT_CLIP)</TT> 00118 </td><td> 00119 create argument object from information provided by 00120 kernel, but use given border treatment mode 00121 00122 </td></tr> 00123 <tr><td> 00124 <TT>kernel1d(kerneliterator, kernelaccessor,</TT><br> 00125 <TT> kernelleft, kernelright,</TT><br> 00126 <TT> vigra::BORDER_TREATMENT_CLIP)</TT> 00127 </td><td> 00128 create argument object from explicitly given iterator 00129 (pointing to the center of th kernel), accessor, 00130 left and right boundaries, and border treatment mode 00131 00132 </table> 00133 00134 For usage examples see 00135 \ref SeparableConvolution "one-dimensional and separable convolution functions". 00136 00137 \section Kernel2dFactory kernel2d() 00138 00139 Pass a \ref vigra::Kernel2D to a 2D (non-separable) convolution algorithm. 00140 00141 These factories can be used to create argument objects when we 00142 are given instances or subclasses of \ref vigra::Kernel2D 00143 (analogous to the \ref ArgumentObjectFactories for images). 00144 These factory functions access <TT>kernel.center()</TT>, 00145 <TT>kernel.upperLeft()</TT>, <TT>kernel.lowerRight()</TT>, <TT>kernel.accessor()</TT>, 00146 and <TT>kernel.borderTreatment()</TT> to obtain the necessary 00147 information. The following factory functions are provided: 00148 00149 <table> 00150 <tr><td> 00151 \htmlonly 00152 <th bgcolor="#f0e0c0" colspan=2 align=left> 00153 \endhtmlonly 00154 <TT>\ref vigra::Kernel2D "vigra::Kernel2D<SomeType>" kernel;</TT> 00155 \htmlonly 00156 </th> 00157 \endhtmlonly 00158 </td></tr> 00159 <tr><td> 00160 <TT>kernel2d(kernel)</TT> 00161 </td><td> 00162 create argument object from information provided by 00163 kernel 00164 00165 </td></tr> 00166 <tr><td> 00167 <TT>kernel2d(kernel, vigra::BORDER_TREATMENT_CLIP)</TT> 00168 </td><td> 00169 create argument object from information provided by 00170 kernel, but use given border treatment mode 00171 00172 </td></tr> 00173 <tr><td> 00174 <TT>kernel2d(kerneliterator, kernelaccessor,</TT> 00175 <TT> upperleft, lowerright,</TT> 00176 <TT> vigra::BORDER_TREATMENT_CLIP)</TT> 00177 </td><td> 00178 create argument object from explicitly given iterator 00179 (pointing to the center of th kernel), accessor, 00180 upper left and lower right corners, and border treatment mode 00181 00182 </table> 00183 00184 For usage examples see \ref StandardConvolution "two-dimensional convolution functions". 00185 */ 00186 00187 namespace vigra { 00188 00189 00190 00191 /********************************************************/ 00192 /* */ 00193 /* Common convolution filters */ 00194 /* */ 00195 /********************************************************/ 00196 00197 /** \addtogroup CommonConvolutionFilters Common Filters 00198 00199 These functions calculate common filters by appropriate sequences of calls 00200 to \link SeparableConvolution#separableConvolveX separableConvolveX\endlink() 00201 and \link SeparableConvolution#separableConvolveY separableConvolveY\endlink(). 00202 */ 00203 //@{ 00204 00205 /********************************************************/ 00206 /* */ 00207 /* convolveImage */ 00208 /* */ 00209 /********************************************************/ 00210 00211 /** \brief Apply two separable filters successively, the first in x-direction, 00212 the second in y-direction. 00213 00214 This function is a shorthand for the concatenation of a call to 00215 \link SeparableConvolution#separableConvolveX separableConvolveX\endlink() 00216 and \link SeparableConvolution#separableConvolveY separableConvolveY\endlink() 00217 with the given kernels. 00218 00219 <b> Declarations:</b> 00220 00221 pass arguments explicitly: 00222 \code 00223 namespace vigra { 00224 template <class SrcIterator, class SrcAccessor, 00225 class DestIterator, class DestAccessor, 00226 class T> 00227 void convolveImage(SrcIterator supperleft, 00228 SrcIterator slowerright, SrcAccessor sa, 00229 DestIterator dupperleft, DestAccessor da, 00230 Kernel1D<T> const & kx, Kernel1D<T> const & ky); 00231 } 00232 \endcode 00233 00234 00235 use argument objects in conjuction with \ref ArgumentObjectFactories: 00236 \code 00237 namespace vigra { 00238 template <class SrcIterator, class SrcAccessor, 00239 class DestIterator, class DestAccessor, 00240 class T> 00241 inline void 00242 convolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00243 pair<DestIterator, DestAccessor> dest, 00244 Kernel1D<T> const & kx, Kernel1D<T> const & ky); 00245 } 00246 \endcode 00247 00248 <b> Usage:</b> 00249 00250 <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>" 00251 00252 00253 \code 00254 vigra::FImage src(w,h), dest(w,h); 00255 ... 00256 00257 // implement sobel filter in x-direction 00258 Kernel1D<double> kx, ky; 00259 kx.initSymmetricGradient(); 00260 ky.initBinomial(1); 00261 00262 vigra::convolveImage(srcImageRange(src), destImage(dest), kx, ky); 00263 00264 \endcode 00265 00266 */ 00267 template <class SrcIterator, class SrcAccessor, 00268 class DestIterator, class DestAccessor, 00269 class T> 00270 void convolveImage(SrcIterator supperleft, 00271 SrcIterator slowerright, SrcAccessor sa, 00272 DestIterator dupperleft, DestAccessor da, 00273 Kernel1D<T> const & kx, Kernel1D<T> const & ky) 00274 { 00275 typedef typename 00276 NumericTraits<typename SrcAccessor::value_type>::RealPromote 00277 TmpType; 00278 BasicImage<TmpType> tmp(slowerright - supperleft); 00279 00280 separableConvolveX(srcIterRange(supperleft, slowerright, sa), 00281 destImage(tmp), kernel1d(kx)); 00282 separableConvolveY(srcImageRange(tmp), 00283 destIter(dupperleft, da), kernel1d(ky)); 00284 } 00285 00286 template <class SrcIterator, class SrcAccessor, 00287 class DestIterator, class DestAccessor, 00288 class T> 00289 inline void 00290 convolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00291 pair<DestIterator, DestAccessor> dest, 00292 Kernel1D<T> const & kx, Kernel1D<T> const & ky) 00293 { 00294 convolveImage(src.first, src.second, src.third, 00295 dest.first, dest.second, kx, ky); 00296 } 00297 00298 /********************************************************/ 00299 /* */ 00300 /* simpleSharpening */ 00301 /* */ 00302 /********************************************************/ 00303 00304 /** \brief Perform simple sharpening function. 00305 00306 This function use \link StandardConvolution#convolveImage convolveImage\endlink( ) with following filter: 00307 00308 \code 00309 -sharpening_factor/16.0, -sharpening_factor/8.0, -sharpening_factor/16.0, 00310 -sharpening_factor/8.0, 1.0+sharpening_factor*0.75, -sharpening_factor/8.0, 00311 -sharpening_factor/16.0, -sharpening_factor/8.0, -sharpening_factor/16.0; 00312 \endcode 00313 00314 and use <TT>BORDER_TREATMENT_REFLECT</TT> as border treatment mode. 00315 00316 <b> Preconditions:</b> 00317 \code 00318 1. sharpening_factor >= 0 00319 2. scale >= 0 00320 \endcode 00321 00322 <b> Declarations:</b> 00323 00324 <b> Declarations:</b> 00325 00326 pass arguments explicitly: 00327 \code 00328 namespace vigra { 00329 template <class SrcIterator, class SrcAccessor, 00330 class DestIterator, class DestAccessor> 00331 void simpleSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc, 00332 DestIterator dest_ul, DestAccessor dest_acc, double sharpening_factor) 00333 00334 } 00335 \endcode 00336 00337 00338 use argument objects in conjuction with \ref ArgumentObjectFactories: 00339 \code 00340 namespace vigra { 00341 template <class SrcIterator, class SrcAccessor, 00342 class DestIterator, class DestAccessor> 00343 inline 00344 void simpleSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00345 pair<DestIterator, DestAccessor> dest, double sharpening_factor) 00346 { 00347 simpleSharpening(src.first, src.second, src.third, 00348 dest.first, dest.second, sharpening_factor); 00349 } 00350 00351 } 00352 \endcode 00353 00354 <b> Usage:</b> 00355 00356 <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>" 00357 00358 00359 \code 00360 vigra::FImage src(w,h), dest(w,h); 00361 ... 00362 00363 // sharpening with sharpening_factor = 0.1 00364 vigra::simpleSharpening(srcImageRange(src), destImage(dest), 0.1); 00365 00366 \endcode 00367 00368 */ 00369 template <class SrcIterator, class SrcAccessor, 00370 class DestIterator, class DestAccessor> 00371 void simpleSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc, 00372 DestIterator dest_ul, DestAccessor dest_acc, double sharpening_factor) 00373 { 00374 00375 vigra_precondition(sharpening_factor >= 0.0, 00376 "simpleSharpening(): amount of sharpening must be >= 0."); 00377 00378 Kernel2D<double> kernel; 00379 00380 kernel.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) = -sharpening_factor/16.0, -sharpening_factor/8.0, -sharpening_factor/16.0, 00381 -sharpening_factor/8.0, 1.0+sharpening_factor*0.75, -sharpening_factor/8.0, 00382 -sharpening_factor/16.0, -sharpening_factor/8.0, -sharpening_factor/16.0; 00383 00384 convolveImage(src_ul, src_lr, src_acc, dest_ul, dest_acc, 00385 kernel.center(), kernel.accessor(), 00386 kernel.upperLeft(), kernel.lowerRight() , BORDER_TREATMENT_REFLECT ); 00387 } 00388 00389 template <class SrcIterator, class SrcAccessor, 00390 class DestIterator, class DestAccessor> 00391 inline 00392 void simpleSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00393 pair<DestIterator, DestAccessor> dest, double sharpening_factor) 00394 { 00395 simpleSharpening(src.first, src.second, src.third, 00396 dest.first, dest.second, sharpening_factor); 00397 } 00398 00399 00400 /********************************************************/ 00401 /* */ 00402 /* gaussianSharpening */ 00403 /* */ 00404 /********************************************************/ 00405 00406 /** \brief Perform sharpening function with gaussian filter. 00407 00408 00409 This function use the 00410 \link vigra::gaussianSmoothing gaussianSmoothing \endlink() 00411 at first and scale the source image 00412 (\code src \endcode) with the \code scale \endcode 00413 factor in an temporary image (\code tmp \endcode). At second the new 00414 pixel in the destination image will be with following 00415 formel calculate: 00416 \code 00417 dest = (1 + sharpening_factor)*src - sharpening_factor*tmp 00418 \endcode 00419 00420 <b> Preconditions:</b> 00421 \code 00422 1. sharpening_factor >= 0 00423 2. scale >= 0 00424 \endcode 00425 00426 <b> Declarations:</b> 00427 00428 pass arguments explicitly: 00429 \code 00430 namespace vigra { 00431 template <class SrcIterator, class SrcAccessor, 00432 class DestIterator, class DestAccessor> 00433 void gaussianSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc, 00434 DestIterator dest_ul, DestAccessor dest_acc, double sharpening_factor, 00435 double scale) 00436 } 00437 \endcode 00438 00439 00440 use argument objects in conjuction with \ref ArgumentObjectFactories: 00441 \code 00442 namespace vigra { 00443 template <class SrcIterator, class SrcAccessor, 00444 class DestIterator, class DestAccessor> 00445 void gaussianSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00446 pair<DestIterator, DestAccessor> dest, double sharpening_factor, 00447 double scale) 00448 } 00449 \endcode 00450 00451 <b> Usage:</b> 00452 00453 <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>" 00454 00455 00456 \code 00457 vigra::FImage src(w,h), dest(w,h); 00458 ... 00459 00460 // sharpening with sharpening_factor = 3.0 00461 // smoothing with scale = 0.5 00462 vigra::gaussianSmoothing(srcImageRange(src), destImage(dest), 3.0, 0.5); 00463 00464 \endcode 00465 00466 */ 00467 template <class SrcIterator, class SrcAccessor, 00468 class DestIterator, class DestAccessor> 00469 void gaussianSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc, 00470 DestIterator dest_ul, DestAccessor dest_acc, double sharpening_factor, 00471 double scale) 00472 { 00473 vigra_precondition(sharpening_factor >= 0.0, 00474 "gaussianSharpening(): amount of sharpening must be >= 0"); 00475 vigra_precondition(scale >= 0.0, 00476 "gaussianSharpening(): scale parameter should be >= 0."); 00477 00478 typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote ValueType; 00479 00480 BasicImage<ValueType> tmp(src_lr - src_ul); 00481 typename BasicImage<ValueType>::Accessor tmp_acc = tmp.accessor(); 00482 00483 gaussianSmoothing(src_ul, src_lr, src_acc, tmp.upperLeft(), tmp_acc, scale); 00484 00485 SrcIterator i_src = src_ul; 00486 DestIterator i_dest = dest_ul; 00487 typename BasicImage<ValueType>::traverser tmp_ul = tmp.upperLeft(); 00488 typename BasicImage<ValueType>::traverser i_tmp = tmp_ul; 00489 00490 for(; i_src.y != src_lr.y ; i_src.y++, i_dest.y++, i_tmp.y++ ) 00491 { 00492 for (;i_src.x != src_lr.x ; i_src.x++, i_dest.x++, i_tmp.x++ ) 00493 { 00494 dest_acc.set((1.0 + sharpening_factor)*src_acc(i_src) - sharpening_factor*tmp_acc(i_tmp), i_dest); 00495 } 00496 i_src.x = src_ul.x; 00497 i_dest.x = dest_ul.x; 00498 i_tmp.x = tmp_ul.x; 00499 } 00500 } 00501 00502 template <class SrcIterator, class SrcAccessor, 00503 class DestIterator, class DestAccessor> 00504 void gaussianSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00505 pair<DestIterator, DestAccessor> dest, double sharpening_factor, 00506 double scale) 00507 { 00508 gaussianSharpening(src.first, src.second, src.third, 00509 dest.first, dest.second, 00510 sharpening_factor, scale); 00511 } 00512 00513 00514 00515 /********************************************************/ 00516 /* */ 00517 /* gaussianSmoothing */ 00518 /* */ 00519 /********************************************************/ 00520 00521 /** \brief Perform isotropic Gaussian convolution. 00522 00523 This function is a shorthand for the concatenation of a call to 00524 \link SeparableConvolution#separableConvolveX separableConvolveX\endlink() 00525 and \link SeparableConvolution#separableConvolveY separableConvolveY\endlink() with a 00526 Gaussian kernel of the given scale. The function uses 00527 <TT>BORDER_TREATMENT_REFLECT</TT>. 00528 00529 <b> Declarations:</b> 00530 00531 pass arguments explicitly: 00532 \code 00533 namespace vigra { 00534 template <class SrcIterator, class SrcAccessor, 00535 class DestIterator, class DestAccessor> 00536 void gaussianSmoothing(SrcIterator supperleft, 00537 SrcIterator slowerright, SrcAccessor sa, 00538 DestIterator dupperleft, DestAccessor da, 00539 double scale); 00540 } 00541 \endcode 00542 00543 00544 use argument objects in conjuction with \ref ArgumentObjectFactories: 00545 \code 00546 namespace vigra { 00547 template <class SrcIterator, class SrcAccessor, 00548 class DestIterator, class DestAccessor> 00549 inline void 00550 gaussianSmoothing(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00551 pair<DestIterator, DestAccessor> dest, 00552 double scale); 00553 } 00554 \endcode 00555 00556 <b> Usage:</b> 00557 00558 <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>" 00559 00560 00561 \code 00562 vigra::FImage src(w,h), dest(w,h); 00563 ... 00564 00565 // smooth with scale = 3.0 00566 vigra::gaussianSmoothing(srcImageRange(src), destImage(dest), 3.0); 00567 00568 \endcode 00569 00570 */ 00571 template <class SrcIterator, class SrcAccessor, 00572 class DestIterator, class DestAccessor> 00573 void gaussianSmoothing(SrcIterator supperleft, 00574 SrcIterator slowerright, SrcAccessor sa, 00575 DestIterator dupperleft, DestAccessor da, 00576 double scale) 00577 { 00578 typedef typename 00579 NumericTraits<typename SrcAccessor::value_type>::RealPromote 00580 TmpType; 00581 BasicImage<TmpType> tmp(slowerright - supperleft); 00582 00583 Kernel1D<double> smooth; 00584 smooth.initGaussian(scale); 00585 smooth.setBorderTreatment(BORDER_TREATMENT_REFLECT); 00586 00587 separableConvolveX(srcIterRange(supperleft, slowerright, sa), 00588 destImage(tmp), kernel1d(smooth)); 00589 separableConvolveY(srcImageRange(tmp), 00590 destIter(dupperleft, da), kernel1d(smooth)); 00591 } 00592 00593 template <class SrcIterator, class SrcAccessor, 00594 class DestIterator, class DestAccessor> 00595 inline void 00596 gaussianSmoothing(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00597 pair<DestIterator, DestAccessor> dest, 00598 double scale) 00599 { 00600 gaussianSmoothing(src.first, src.second, src.third, 00601 dest.first, dest.second, scale); 00602 } 00603 00604 /********************************************************/ 00605 /* */ 00606 /* gaussianGradient */ 00607 /* */ 00608 /********************************************************/ 00609 00610 /** \brief Calculate the gradient vector by means of a 1st derivatives of 00611 Gaussian filter. 00612 00613 This function is a shorthand for the concatenation of a call to 00614 \link SeparableConvolution#separableConvolveX separableConvolveX\endlink() 00615 and \link SeparableConvolution#separableConvolveY separableConvolveY\endlink() with the 00616 appropriate kernels at the given scale. Note that this function produces 00617 <i>two</i> result images. 00618 00619 <b> Declarations:</b> 00620 00621 pass arguments explicitly: 00622 \code 00623 namespace vigra { 00624 template <class SrcIterator, class SrcAccessor, 00625 class DestIteratorX, class DestAccessorX, 00626 class DestIteratorY, class DestAccessorY> 00627 void gaussianGradient(SrcIterator supperleft, 00628 SrcIterator slowerright, SrcAccessor sa, 00629 DestIteratorX dupperleftx, DestAccessorX dax, 00630 DestIteratorY dupperlefty, DestAccessorY day, 00631 double scale); 00632 } 00633 \endcode 00634 00635 00636 use argument objects in conjuction with \ref ArgumentObjectFactories: 00637 \code 00638 namespace vigra { 00639 template <class SrcIterator, class SrcAccessor, 00640 class DestIteratorX, class DestAccessorX, 00641 class DestIteratorY, class DestAccessorY> 00642 inline void 00643 gaussianGradient(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00644 pair<DestIteratorX, DestAccessorX> destx, 00645 pair<DestIteratorY, DestAccessorY> desty, 00646 double scale); 00647 } 00648 \endcode 00649 00650 <b> Usage:</b> 00651 00652 <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>" 00653 00654 00655 \code 00656 vigra::FImage src(w,h), gradx(w,h), grady(w,h); 00657 ... 00658 00659 // calculate gradient vector at scale = 3.0 00660 vigra::gaussianGradient(srcImageRange(src), 00661 destImage(gradx), destImage(grady), 3.0); 00662 00663 \endcode 00664 00665 */ 00666 template <class SrcIterator, class SrcAccessor, 00667 class DestIteratorX, class DestAccessorX, 00668 class DestIteratorY, class DestAccessorY> 00669 void gaussianGradient(SrcIterator supperleft, 00670 SrcIterator slowerright, SrcAccessor sa, 00671 DestIteratorX dupperleftx, DestAccessorX dax, 00672 DestIteratorY dupperlefty, DestAccessorY day, 00673 double scale) 00674 { 00675 typedef typename 00676 NumericTraits<typename SrcAccessor::value_type>::RealPromote 00677 TmpType; 00678 BasicImage<TmpType> tmp(slowerright - supperleft); 00679 00680 Kernel1D<double> smooth, grad; 00681 smooth.initGaussian(scale); 00682 grad.initGaussianDerivative(scale, 1); 00683 00684 separableConvolveX(srcIterRange(supperleft, slowerright, sa), 00685 destImage(tmp), kernel1d(grad)); 00686 separableConvolveY(srcImageRange(tmp), 00687 destIter(dupperleftx, dax), kernel1d(smooth)); 00688 separableConvolveX(srcIterRange(supperleft, slowerright, sa), 00689 destImage(tmp), kernel1d(smooth)); 00690 separableConvolveY(srcImageRange(tmp), 00691 destIter(dupperlefty, day), kernel1d(grad)); 00692 } 00693 00694 template <class SrcIterator, class SrcAccessor, 00695 class DestIteratorX, class DestAccessorX, 00696 class DestIteratorY, class DestAccessorY> 00697 inline void 00698 gaussianGradient(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00699 pair<DestIteratorX, DestAccessorX> destx, 00700 pair<DestIteratorY, DestAccessorY> desty, 00701 double scale) 00702 { 00703 gaussianGradient(src.first, src.second, src.third, 00704 destx.first, destx.second, desty.first, desty.second, scale); 00705 } 00706 00707 /********************************************************/ 00708 /* */ 00709 /* laplacianOfGaussian */ 00710 /* */ 00711 /********************************************************/ 00712 00713 /** \brief Filter image with the Laplacian of Gaussian operator 00714 at the given scale. 00715 00716 This function calls \link SeparableConvolution#separableConvolveX separableConvolveX\endlink() and 00717 \link SeparableConvolution#separableConvolveY separableConvolveY\endlink() with the appropriate 2nd derivative 00718 of Gaussian kernels in x- and y-direction and then sums the results 00719 to get the Laplacian. 00720 00721 <b> Declarations:</b> 00722 00723 pass arguments explicitly: 00724 \code 00725 namespace vigra { 00726 template <class SrcIterator, class SrcAccessor, 00727 class DestIterator, class DestAccessor> 00728 void laplacianOfGaussian(SrcIterator supperleft, 00729 SrcIterator slowerright, SrcAccessor sa, 00730 DestIterator dupperleft, DestAccessor da, 00731 double scale); 00732 } 00733 \endcode 00734 00735 00736 use argument objects in conjuction with \ref ArgumentObjectFactories: 00737 \code 00738 namespace vigra { 00739 template <class SrcIterator, class SrcAccessor, 00740 class DestIterator, class DestAccessor> 00741 inline void 00742 laplacianOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00743 pair<DestIterator, DestAccessor> dest, 00744 double scale); 00745 } 00746 \endcode 00747 00748 <b> Usage:</b> 00749 00750 <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>" 00751 00752 00753 \code 00754 vigra::FImage src(w,h), dest(w,h); 00755 ... 00756 00757 // calculate Laplacian of Gaussian at scale = 3.0 00758 vigra::laplacianOfGaussian(srcImageRange(src), destImage(dest), 3.0); 00759 00760 \endcode 00761 00762 */ 00763 template <class SrcIterator, class SrcAccessor, 00764 class DestIterator, class DestAccessor> 00765 void laplacianOfGaussian(SrcIterator supperleft, 00766 SrcIterator slowerright, SrcAccessor sa, 00767 DestIterator dupperleft, DestAccessor da, 00768 double scale) 00769 { 00770 typedef typename 00771 NumericTraits<typename SrcAccessor::value_type>::RealPromote 00772 TmpType; 00773 BasicImage<TmpType> tmp(slowerright - supperleft), 00774 tmpx(slowerright - supperleft), 00775 tmpy(slowerright - supperleft); 00776 00777 Kernel1D<double> smooth, deriv; 00778 smooth.initGaussian(scale); 00779 deriv.initGaussianDerivative(scale, 2); 00780 00781 separableConvolveX(srcIterRange(supperleft, slowerright, sa), 00782 destImage(tmp), kernel1d(deriv)); 00783 separableConvolveY(srcImageRange(tmp), 00784 destImage(tmpx), kernel1d(smooth)); 00785 separableConvolveX(srcIterRange(supperleft, slowerright, sa), 00786 destImage(tmp), kernel1d(smooth)); 00787 separableConvolveY(srcImageRange(tmp), 00788 destImage(tmpy), kernel1d(deriv)); 00789 combineTwoImages(srcImageRange(tmpx), srcImage(tmpy), 00790 destIter(dupperleft, da), std::plus<TmpType>()); 00791 } 00792 00793 template <class SrcIterator, class SrcAccessor, 00794 class DestIterator, class DestAccessor> 00795 inline void 00796 laplacianOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00797 pair<DestIterator, DestAccessor> dest, 00798 double scale) 00799 { 00800 laplacianOfGaussian(src.first, src.second, src.third, 00801 dest.first, dest.second, scale); 00802 } 00803 00804 /********************************************************/ 00805 /* */ 00806 /* hessianMatrixOfGaussian */ 00807 /* */ 00808 /********************************************************/ 00809 00810 /** \brief Filter image with the 2nd derivatives of the Gaussian 00811 at the given scale to get the Hessian matrix. 00812 00813 The Hessian matrix is a symmetric matrix defined as: 00814 00815 \f[ 00816 \mbox{\rm Hessian}(I) = \left( 00817 \begin{array}{cc} 00818 G_{xx} \ast I & G_{xy} \ast I \\ 00819 G_{xy} \ast I & G_{yy} \ast I 00820 \end{array} \right) 00821 \f] 00822 00823 where \f$G_{xx}, G_{xy}, G_{yy}\f$ denote 2nd derivatives of Gaussians 00824 at the given scale, and 00825 \f$\ast\f$ is the convolution symbol. This function calls 00826 \link SeparableConvolution#separableConvolveX separableConvolveX\endlink() and 00827 \link SeparableConvolution#separableConvolveY separableConvolveY\endlink() 00828 with the appropriate 2nd derivative 00829 of Gaussian kernels and puts the results in 00830 the three destination images. The first destination image will 00831 contain the second derivative in x-direction, the second one the mixed 00832 derivative, and the third one holds the derivative in y-direction. 00833 00834 <b> Declarations:</b> 00835 00836 pass arguments explicitly: 00837 \code 00838 namespace vigra { 00839 template <class SrcIterator, class SrcAccessor, 00840 class DestIteratorX, class DestAccessorX, 00841 class DestIteratorXY, class DestAccessorXY, 00842 class DestIteratorY, class DestAccessorY> 00843 void hessianMatrixOfGaussian(SrcIterator supperleft, 00844 SrcIterator slowerright, SrcAccessor sa, 00845 DestIteratorX dupperleftx, DestAccessorX dax, 00846 DestIteratorXY dupperleftxy, DestAccessorXY daxy, 00847 DestIteratorY dupperlefty, DestAccessorY day, 00848 double scale); 00849 } 00850 \endcode 00851 00852 00853 use argument objects in conjuction with \ref ArgumentObjectFactories: 00854 \code 00855 namespace vigra { 00856 template <class SrcIterator, class SrcAccessor, 00857 class DestIteratorX, class DestAccessorX, 00858 class DestIteratorXY, class DestAccessorXY, 00859 class DestIteratorY, class DestAccessorY> 00860 inline void 00861 hessianMatrixOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00862 pair<DestIteratorX, DestAccessorX> destx, 00863 pair<DestIteratorXY, DestAccessorXY> destxy, 00864 pair<DestIteratorY, DestAccessorY> desty, 00865 double scale); 00866 } 00867 \endcode 00868 00869 <b> Usage:</b> 00870 00871 <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>" 00872 00873 00874 \code 00875 vigra::FImage src(w,h), hxx(w,h), hxy(w,h), hyy(w,h); 00876 ... 00877 00878 // calculate Hessian of Gaussian at scale = 3.0 00879 vigra::hessianMatrixOfGaussian(srcImageRange(src), 00880 destImage(hxx), destImage(hxy), destImage(hyy), 3.0); 00881 00882 \endcode 00883 00884 */ 00885 template <class SrcIterator, class SrcAccessor, 00886 class DestIteratorX, class DestAccessorX, 00887 class DestIteratorXY, class DestAccessorXY, 00888 class DestIteratorY, class DestAccessorY> 00889 void hessianMatrixOfGaussian(SrcIterator supperleft, 00890 SrcIterator slowerright, SrcAccessor sa, 00891 DestIteratorX dupperleftx, DestAccessorX dax, 00892 DestIteratorXY dupperleftxy, DestAccessorXY daxy, 00893 DestIteratorY dupperlefty, DestAccessorY day, 00894 double scale) 00895 { 00896 typedef typename 00897 NumericTraits<typename SrcAccessor::value_type>::RealPromote 00898 TmpType; 00899 BasicImage<TmpType> tmp(slowerright - supperleft); 00900 00901 Kernel1D<double> smooth, deriv1, deriv2; 00902 smooth.initGaussian(scale); 00903 deriv1.initGaussianDerivative(scale, 1); 00904 deriv2.initGaussianDerivative(scale, 2); 00905 00906 separableConvolveX(srcIterRange(supperleft, slowerright, sa), 00907 destImage(tmp), kernel1d(deriv2)); 00908 separableConvolveY(srcImageRange(tmp), 00909 destIter(dupperleftx, dax), kernel1d(smooth)); 00910 separableConvolveX(srcIterRange(supperleft, slowerright, sa), 00911 destImage(tmp), kernel1d(smooth)); 00912 separableConvolveY(srcImageRange(tmp), 00913 destIter(dupperlefty, day), kernel1d(deriv2)); 00914 separableConvolveX(srcIterRange(supperleft, slowerright, sa), 00915 destImage(tmp), kernel1d(deriv1)); 00916 separableConvolveY(srcImageRange(tmp), 00917 destIter(dupperleftxy, daxy), kernel1d(deriv1)); 00918 } 00919 00920 template <class SrcIterator, class SrcAccessor, 00921 class DestIteratorX, class DestAccessorX, 00922 class DestIteratorXY, class DestAccessorXY, 00923 class DestIteratorY, class DestAccessorY> 00924 inline void 00925 hessianMatrixOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00926 pair<DestIteratorX, DestAccessorX> destx, 00927 pair<DestIteratorXY, DestAccessorXY> destxy, 00928 pair<DestIteratorY, DestAccessorY> desty, 00929 double scale) 00930 { 00931 hessianMatrixOfGaussian(src.first, src.second, src.third, 00932 destx.first, destx.second, 00933 destxy.first, destxy.second, 00934 desty.first, desty.second, 00935 scale); 00936 } 00937 00938 /********************************************************/ 00939 /* */ 00940 /* structureTensor */ 00941 /* */ 00942 /********************************************************/ 00943 00944 /** \brief Calculate the Structure Tensor for each pixel of 00945 and image, using Gaussian (derivative) filters. 00946 00947 The Structure Tensor is is a smoothed version of the Euclidean product 00948 of the gradient vector with itself. I.e. it's a symmetric matrix defined as: 00949 00950 \f[ 00951 \mbox{\rm StructurTensor}(I) = \left( 00952 \begin{array}{cc} 00953 G \ast (I_x I_x) & G \ast (I_x I_y) \\ 00954 G \ast (I_x I_y) & G \ast (I_y I_y) 00955 \end{array} \right) = \left( 00956 \begin{array}{cc} 00957 A & C \\ 00958 C & B 00959 \end{array} \right) 00960 \f] 00961 00962 where \f$G\f$ denotes Gaussian smoothing at the <i>outer scale</i>, 00963 \f$I_x, I_y\f$ are the gradient components taken at the <i>inner scale</i>, 00964 \f$\ast\f$ is the convolution symbol, and \f$I_x I_x\f$ etc. are pixelwise 00965 products of the 1st derivative images. This function calls 00966 \link SeparableConvolution#separableConvolveX separableConvolveX\endlink() 00967 and \link SeparableConvolution#separableConvolveY separableConvolveY\endlink() with the 00968 appropriate Gaussian kernels and puts the results in 00969 the three destination images. The first destination image will 00970 contain \f$G \ast (I_x I_x)\f$, the second one \f$G \ast (I_x I_y)\f$, and the 00971 third one holds \f$G \ast (I_y I_y)\f$. 00972 00973 <b> Declarations:</b> 00974 00975 pass arguments explicitly: 00976 \code 00977 namespace vigra { 00978 template <class SrcIterator, class SrcAccessor, 00979 class DestIteratorX, class DestAccessorX, 00980 class DestIteratorXY, class DestAccessorXY, 00981 class DestIteratorY, class DestAccessorY> 00982 void structureTensor(SrcIterator supperleft, 00983 SrcIterator slowerright, SrcAccessor sa, 00984 DestIteratorX dupperleftx, DestAccessorX dax, 00985 DestIteratorXY dupperleftxy, DestAccessorXY daxy, 00986 DestIteratorY dupperlefty, DestAccessorY day, 00987 double inner_scale, double outer_scale); 00988 } 00989 \endcode 00990 00991 00992 use argument objects in conjuction with \ref ArgumentObjectFactories: 00993 \code 00994 namespace vigra { 00995 template <class SrcIterator, class SrcAccessor, 00996 class DestIteratorX, class DestAccessorX, 00997 class DestIteratorXY, class DestAccessorXY, 00998 class DestIteratorY, class DestAccessorY> 00999 inline void 01000 structureTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01001 pair<DestIteratorX, DestAccessorX> destx, 01002 pair<DestIteratorXY, DestAccessorXY> destxy, 01003 pair<DestIteratorY, DestAccessorY> desty, 01004 double nner_scale, double outer_scale); 01005 } 01006 \endcode 01007 01008 <b> Usage:</b> 01009 01010 <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>" 01011 01012 01013 \code 01014 vigra::FImage src(w,h), stxx(w,h), stxy(w,h), styy(w,h); 01015 ... 01016 01017 // calculate Structure Tensor at inner scale = 1.0 and outer scale = 3.0 01018 vigra::structureTensor(srcImageRange(src), 01019 destImage(stxx), destImage(stxy), destImage(styy), 1.0, 3.0); 01020 01021 \endcode 01022 01023 */ 01024 template <class SrcIterator, class SrcAccessor, 01025 class DestIteratorX, class DestAccessorX, 01026 class DestIteratorXY, class DestAccessorXY, 01027 class DestIteratorY, class DestAccessorY> 01028 void structureTensor(SrcIterator supperleft, 01029 SrcIterator slowerright, SrcAccessor sa, 01030 DestIteratorX dupperleftx, DestAccessorX dax, 01031 DestIteratorXY dupperleftxy, DestAccessorXY daxy, 01032 DestIteratorY dupperlefty, DestAccessorY day, 01033 double inner_scale, double outer_scale) 01034 { 01035 typedef typename 01036 NumericTraits<typename SrcAccessor::value_type>::RealPromote 01037 TmpType; 01038 BasicImage<TmpType> tmp(slowerright - supperleft), 01039 tmpx(slowerright - supperleft), 01040 tmpy(slowerright - supperleft); 01041 01042 gaussianGradient(srcIterRange(supperleft, slowerright, sa), 01043 destImage(tmpx), destImage(tmpy), inner_scale); 01044 combineTwoImages(srcImageRange(tmpx), srcImage(tmpx), 01045 destImage(tmp), std::multiplies<TmpType>()); 01046 gaussianSmoothing(srcImageRange(tmp), 01047 destIter(dupperleftx, dax), outer_scale); 01048 combineTwoImages(srcImageRange(tmpy), srcImage(tmpy), 01049 destImage(tmp), std::multiplies<TmpType>()); 01050 gaussianSmoothing(srcImageRange(tmp), 01051 destIter(dupperlefty, day), outer_scale); 01052 combineTwoImages(srcImageRange(tmpx), srcImage(tmpy), 01053 destImage(tmp), std::multiplies<TmpType>()); 01054 gaussianSmoothing(srcImageRange(tmp), 01055 destIter(dupperleftxy, daxy), outer_scale); 01056 } 01057 01058 template <class SrcIterator, class SrcAccessor, 01059 class DestIteratorX, class DestAccessorX, 01060 class DestIteratorXY, class DestAccessorXY, 01061 class DestIteratorY, class DestAccessorY> 01062 inline void 01063 structureTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01064 pair<DestIteratorX, DestAccessorX> destx, 01065 pair<DestIteratorXY, DestAccessorXY> destxy, 01066 pair<DestIteratorY, DestAccessorY> desty, 01067 double inner_scale, double outer_scale) 01068 { 01069 structureTensor(src.first, src.second, src.third, 01070 destx.first, destx.second, 01071 destxy.first, destxy.second, 01072 desty.first, desty.second, 01073 inner_scale, outer_scale); 01074 } 01075 01076 //@} 01077 01078 } // namespace vigra 01079 01080 #endif // VIGRA_CONVOLUTION_HXX
© Ullrich Köthe (koethe@informatik.uni-hamburg.de) |
html generated using doxygen and Python
|