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