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