[ 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.5.0, Dec 07 2006 ) */ 00008 /* The VIGRA Website is */ 00009 /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ 00010 /* Please direct questions, bug reports, and contributions to */ 00011 /* koethe@informatik.uni-hamburg.de or */ 00012 /* vigra@kogs1.informatik.uni-hamburg.de */ 00013 /* */ 00014 /* Permission is hereby granted, free of charge, to any person */ 00015 /* obtaining a copy of this software and associated documentation */ 00016 /* files (the "Software"), to deal in the Software without */ 00017 /* restriction, including without limitation the rights to use, */ 00018 /* copy, modify, merge, publish, distribute, sublicense, and/or */ 00019 /* sell copies of the Software, and to permit persons to whom the */ 00020 /* Software is furnished to do so, subject to the following */ 00021 /* conditions: */ 00022 /* */ 00023 /* The above copyright notice and this permission notice shall be */ 00024 /* included in all copies or substantial portions of the */ 00025 /* Software. */ 00026 /* */ 00027 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ 00028 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ 00029 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ 00030 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ 00031 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ 00032 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ 00033 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ 00034 /* OTHER DEALINGS IN THE SOFTWARE. */ 00035 /* */ 00036 /************************************************************************/ 00037 00038 00039 #ifndef VIGRA_CONVOLUTION_HXX 00040 #define VIGRA_CONVOLUTION_HXX 00041 00042 #include <functional> 00043 #include "stdconvolution.hxx" 00044 #include "separableconvolution.hxx" 00045 #include "recursiveconvolution.hxx" 00046 #include "nonlineardiffusion.hxx" 00047 #include "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 00505 gaussianSmoothing(src_ul, src_lr, src_acc, tmp.upperLeft(), tmp.accessor(), scale); 00506 00507 SrcIterator i_src = src_ul; 00508 DestIterator i_dest = dest_ul; 00509 typename BasicImage<ValueType>::traverser tmp_ul = tmp.upperLeft(); 00510 typename BasicImage<ValueType>::traverser i_tmp = tmp_ul; 00511 typename BasicImage<ValueType>::Accessor tmp_acc = tmp.accessor(); 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 /** \brief Calculate the gradient magnitude by means of a 1st derivatives of 00773 Gaussian filter. 00774 00775 This function calls gaussianGradient() and returns the pixel-wise magnitude of 00776 the resulting gradient vectors. If the original image has multiple bands, 00777 the squared gradient magnitude is computed for each band separately, and the 00778 return value is the square root of the sum of these sqaured magnitudes. 00779 00780 <b> Declarations:</b> 00781 00782 pass arguments explicitly: 00783 \code 00784 namespace vigra { 00785 template <class SrcIterator, class SrcAccessor, 00786 class DestIterator, class DestAccessor> 00787 void gaussianGradientMagnitude(SrcIterator sul, 00788 SrcIterator slr, SrcAccessor src, 00789 DestIterator dupperleft, DestAccessor dest, 00790 double scale); 00791 } 00792 \endcode 00793 00794 00795 use argument objects in conjunction with \ref ArgumentObjectFactories: 00796 \code 00797 namespace vigra { 00798 template <class SrcIterator, class SrcAccessor, 00799 class DestIterator, class DestAccessor> 00800 void 00801 gaussianGradientMagnitude(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00802 pair<DestIterator, DestAccessor> dest, 00803 double scale); 00804 } 00805 \endcode 00806 00807 <b> Usage:</b> 00808 00809 <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>" 00810 00811 00812 \code 00813 vigra::FImage src(w,h), grad(w,h); 00814 ... 00815 00816 // calculate gradient magnitude at scale = 3.0 00817 vigra::gaussianGradientMagnitude(srcImageRange(src), destImage(grad), 3.0); 00818 00819 \endcode 00820 00821 */ 00822 template <class SrcIterator, class SrcAccessor, 00823 class DestIterator, class DestAccessor> 00824 void gaussianGradientMagnitude(SrcIterator sul, 00825 SrcIterator slr, SrcAccessor src, 00826 DestIterator dupperleft, DestAccessor dest, 00827 double scale) 00828 { 00829 typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType; 00830 BasicImage<TmpType> gradx(slr-sul), grady(slr-sul); 00831 00832 gaussianGradient(srcIterRange(sul, slr, src), 00833 destImage(gradx), destImage(grady), scale); 00834 combineTwoImages(srcImageRange(gradx), srcImage(grady), destIter(dupperleft, dest), 00835 MagnitudeFunctor<TmpType>()); 00836 } 00837 00838 template <class SrcIterator, class SrcAccessor, 00839 class DestIterator, class DestAccessor> 00840 inline void 00841 gaussianGradientMagnitude(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00842 pair<DestIterator, DestAccessor> dest, 00843 double scale) 00844 { 00845 gaussianGradientMagnitude(src.first, src.second, src.third, 00846 dest.first, dest.second, scale); 00847 } 00848 00849 /********************************************************/ 00850 /* */ 00851 /* laplacianOfGaussian */ 00852 /* */ 00853 /********************************************************/ 00854 00855 /** \brief Filter image with the Laplacian of Gaussian operator 00856 at the given scale. 00857 00858 This function calls \link SeparableConvolution#separableConvolveX separableConvolveX\endlink() and 00859 \link SeparableConvolution#separableConvolveY separableConvolveY\endlink() with the appropriate 2nd derivative 00860 of Gaussian kernels in x- and y-direction and then sums the results 00861 to get the Laplacian. 00862 00863 <b> Declarations:</b> 00864 00865 pass arguments explicitly: 00866 \code 00867 namespace vigra { 00868 template <class SrcIterator, class SrcAccessor, 00869 class DestIterator, class DestAccessor> 00870 void laplacianOfGaussian(SrcIterator supperleft, 00871 SrcIterator slowerright, SrcAccessor sa, 00872 DestIterator dupperleft, DestAccessor da, 00873 double scale); 00874 } 00875 \endcode 00876 00877 00878 use argument objects in conjunction with \ref ArgumentObjectFactories: 00879 \code 00880 namespace vigra { 00881 template <class SrcIterator, class SrcAccessor, 00882 class DestIterator, class DestAccessor> 00883 inline void 00884 laplacianOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00885 pair<DestIterator, DestAccessor> dest, 00886 double scale); 00887 } 00888 \endcode 00889 00890 <b> Usage:</b> 00891 00892 <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>" 00893 00894 00895 \code 00896 vigra::FImage src(w,h), dest(w,h); 00897 ... 00898 00899 // calculate Laplacian of Gaussian at scale = 3.0 00900 vigra::laplacianOfGaussian(srcImageRange(src), destImage(dest), 3.0); 00901 00902 \endcode 00903 00904 */ 00905 template <class SrcIterator, class SrcAccessor, 00906 class DestIterator, class DestAccessor> 00907 void laplacianOfGaussian(SrcIterator supperleft, 00908 SrcIterator slowerright, SrcAccessor sa, 00909 DestIterator dupperleft, DestAccessor da, 00910 double scale) 00911 { 00912 typedef typename 00913 NumericTraits<typename SrcAccessor::value_type>::RealPromote 00914 TmpType; 00915 BasicImage<TmpType> tmp(slowerright - supperleft), 00916 tmpx(slowerright - supperleft), 00917 tmpy(slowerright - supperleft); 00918 00919 Kernel1D<double> smooth, deriv; 00920 smooth.initGaussian(scale); 00921 deriv.initGaussianDerivative(scale, 2); 00922 00923 separableConvolveX(srcIterRange(supperleft, slowerright, sa), 00924 destImage(tmp), kernel1d(deriv)); 00925 separableConvolveY(srcImageRange(tmp), 00926 destImage(tmpx), kernel1d(smooth)); 00927 separableConvolveX(srcIterRange(supperleft, slowerright, sa), 00928 destImage(tmp), kernel1d(smooth)); 00929 separableConvolveY(srcImageRange(tmp), 00930 destImage(tmpy), kernel1d(deriv)); 00931 combineTwoImages(srcImageRange(tmpx), srcImage(tmpy), 00932 destIter(dupperleft, da), std::plus<TmpType>()); 00933 } 00934 00935 template <class SrcIterator, class SrcAccessor, 00936 class DestIterator, class DestAccessor> 00937 inline void 00938 laplacianOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00939 pair<DestIterator, DestAccessor> dest, 00940 double scale) 00941 { 00942 laplacianOfGaussian(src.first, src.second, src.third, 00943 dest.first, dest.second, scale); 00944 } 00945 00946 /********************************************************/ 00947 /* */ 00948 /* hessianMatrixOfGaussian */ 00949 /* */ 00950 /********************************************************/ 00951 00952 /** \brief Filter image with the 2nd derivatives of the Gaussian 00953 at the given scale to get the Hessian matrix. 00954 00955 The Hessian matrix is a symmetric matrix defined as: 00956 00957 \f[ 00958 \mbox{\rm Hessian}(I) = \left( 00959 \begin{array}{cc} 00960 G_{xx} \ast I & G_{xy} \ast I \\ 00961 G_{xy} \ast I & G_{yy} \ast I 00962 \end{array} \right) 00963 \f] 00964 00965 where \f$G_{xx}, G_{xy}, G_{yy}\f$ denote 2nd derivatives of Gaussians 00966 at the given scale, and 00967 \f$\ast\f$ is the convolution symbol. This function calls 00968 \link SeparableConvolution#separableConvolveX separableConvolveX\endlink() and 00969 \link SeparableConvolution#separableConvolveY separableConvolveY\endlink() 00970 with the appropriate 2nd derivative 00971 of Gaussian kernels and puts the results in 00972 the three destination images. The first destination image will 00973 contain the second derivative in x-direction, the second one the mixed 00974 derivative, and the third one holds the derivative in y-direction. 00975 00976 <b> Declarations:</b> 00977 00978 pass arguments explicitly: 00979 \code 00980 namespace vigra { 00981 template <class SrcIterator, class SrcAccessor, 00982 class DestIteratorX, class DestAccessorX, 00983 class DestIteratorXY, class DestAccessorXY, 00984 class DestIteratorY, class DestAccessorY> 00985 void hessianMatrixOfGaussian(SrcIterator supperleft, 00986 SrcIterator slowerright, SrcAccessor sa, 00987 DestIteratorX dupperleftx, DestAccessorX dax, 00988 DestIteratorXY dupperleftxy, DestAccessorXY daxy, 00989 DestIteratorY dupperlefty, DestAccessorY day, 00990 double scale); 00991 } 00992 \endcode 00993 00994 00995 use argument objects in conjunction with \ref ArgumentObjectFactories: 00996 \code 00997 namespace vigra { 00998 template <class SrcIterator, class SrcAccessor, 00999 class DestIteratorX, class DestAccessorX, 01000 class DestIteratorXY, class DestAccessorXY, 01001 class DestIteratorY, class DestAccessorY> 01002 inline void 01003 hessianMatrixOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01004 pair<DestIteratorX, DestAccessorX> destx, 01005 pair<DestIteratorXY, DestAccessorXY> destxy, 01006 pair<DestIteratorY, DestAccessorY> desty, 01007 double scale); 01008 } 01009 \endcode 01010 01011 <b> Usage:</b> 01012 01013 <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>" 01014 01015 01016 \code 01017 vigra::FImage src(w,h), hxx(w,h), hxy(w,h), hyy(w,h); 01018 ... 01019 01020 // calculate Hessian of Gaussian at scale = 3.0 01021 vigra::hessianMatrixOfGaussian(srcImageRange(src), 01022 destImage(hxx), destImage(hxy), destImage(hyy), 3.0); 01023 01024 \endcode 01025 01026 */ 01027 template <class SrcIterator, class SrcAccessor, 01028 class DestIteratorX, class DestAccessorX, 01029 class DestIteratorXY, class DestAccessorXY, 01030 class DestIteratorY, class DestAccessorY> 01031 void hessianMatrixOfGaussian(SrcIterator supperleft, 01032 SrcIterator slowerright, SrcAccessor sa, 01033 DestIteratorX dupperleftx, DestAccessorX dax, 01034 DestIteratorXY dupperleftxy, DestAccessorXY daxy, 01035 DestIteratorY dupperlefty, DestAccessorY day, 01036 double scale) 01037 { 01038 typedef typename 01039 NumericTraits<typename SrcAccessor::value_type>::RealPromote 01040 TmpType; 01041 BasicImage<TmpType> tmp(slowerright - supperleft); 01042 01043 Kernel1D<double> smooth, deriv1, deriv2; 01044 smooth.initGaussian(scale); 01045 deriv1.initGaussianDerivative(scale, 1); 01046 deriv2.initGaussianDerivative(scale, 2); 01047 01048 separableConvolveX(srcIterRange(supperleft, slowerright, sa), 01049 destImage(tmp), kernel1d(deriv2)); 01050 separableConvolveY(srcImageRange(tmp), 01051 destIter(dupperleftx, dax), kernel1d(smooth)); 01052 separableConvolveX(srcIterRange(supperleft, slowerright, sa), 01053 destImage(tmp), kernel1d(smooth)); 01054 separableConvolveY(srcImageRange(tmp), 01055 destIter(dupperlefty, day), kernel1d(deriv2)); 01056 separableConvolveX(srcIterRange(supperleft, slowerright, sa), 01057 destImage(tmp), kernel1d(deriv1)); 01058 separableConvolveY(srcImageRange(tmp), 01059 destIter(dupperleftxy, daxy), kernel1d(deriv1)); 01060 } 01061 01062 template <class SrcIterator, class SrcAccessor, 01063 class DestIteratorX, class DestAccessorX, 01064 class DestIteratorXY, class DestAccessorXY, 01065 class DestIteratorY, class DestAccessorY> 01066 inline void 01067 hessianMatrixOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01068 pair<DestIteratorX, DestAccessorX> destx, 01069 pair<DestIteratorXY, DestAccessorXY> destxy, 01070 pair<DestIteratorY, DestAccessorY> desty, 01071 double scale) 01072 { 01073 hessianMatrixOfGaussian(src.first, src.second, src.third, 01074 destx.first, destx.second, 01075 destxy.first, destxy.second, 01076 desty.first, desty.second, 01077 scale); 01078 } 01079 01080 /********************************************************/ 01081 /* */ 01082 /* structureTensor */ 01083 /* */ 01084 /********************************************************/ 01085 01086 /** \brief Calculate the Structure Tensor for each pixel of 01087 and image, using Gaussian (derivative) filters. 01088 01089 The Structure Tensor is is a smoothed version of the Euclidean product 01090 of the gradient vector with itself. I.e. it's a symmetric matrix defined as: 01091 01092 \f[ 01093 \mbox{\rm StructurTensor}(I) = \left( 01094 \begin{array}{cc} 01095 G \ast (I_x I_x) & G \ast (I_x I_y) \\ 01096 G \ast (I_x I_y) & G \ast (I_y I_y) 01097 \end{array} \right) = \left( 01098 \begin{array}{cc} 01099 A & C \\ 01100 C & B 01101 \end{array} \right) 01102 \f] 01103 01104 where \f$G\f$ denotes Gaussian smoothing at the <i>outer scale</i>, 01105 \f$I_x, I_y\f$ are the gradient components taken at the <i>inner scale</i>, 01106 \f$\ast\f$ is the convolution symbol, and \f$I_x I_x\f$ etc. are pixelwise 01107 products of the 1st derivative images. This function calls 01108 \link SeparableConvolution#separableConvolveX separableConvolveX\endlink() 01109 and \link SeparableConvolution#separableConvolveY separableConvolveY\endlink() with the 01110 appropriate Gaussian kernels and puts the results in 01111 the three destination images. The first destination image will 01112 contain \f$G \ast (I_x I_x)\f$, the second one \f$G \ast (I_x I_y)\f$, and the 01113 third one holds \f$G \ast (I_y I_y)\f$. 01114 01115 <b> Declarations:</b> 01116 01117 pass arguments explicitly: 01118 \code 01119 namespace vigra { 01120 template <class SrcIterator, class SrcAccessor, 01121 class DestIteratorX, class DestAccessorX, 01122 class DestIteratorXY, class DestAccessorXY, 01123 class DestIteratorY, class DestAccessorY> 01124 void structureTensor(SrcIterator supperleft, 01125 SrcIterator slowerright, SrcAccessor sa, 01126 DestIteratorX dupperleftx, DestAccessorX dax, 01127 DestIteratorXY dupperleftxy, DestAccessorXY daxy, 01128 DestIteratorY dupperlefty, DestAccessorY day, 01129 double inner_scale, double outer_scale); 01130 } 01131 \endcode 01132 01133 01134 use argument objects in conjunction with \ref ArgumentObjectFactories: 01135 \code 01136 namespace vigra { 01137 template <class SrcIterator, class SrcAccessor, 01138 class DestIteratorX, class DestAccessorX, 01139 class DestIteratorXY, class DestAccessorXY, 01140 class DestIteratorY, class DestAccessorY> 01141 inline void 01142 structureTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01143 pair<DestIteratorX, DestAccessorX> destx, 01144 pair<DestIteratorXY, DestAccessorXY> destxy, 01145 pair<DestIteratorY, DestAccessorY> desty, 01146 double nner_scale, double outer_scale); 01147 } 01148 \endcode 01149 01150 <b> Usage:</b> 01151 01152 <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>" 01153 01154 01155 \code 01156 vigra::FImage src(w,h), stxx(w,h), stxy(w,h), styy(w,h); 01157 ... 01158 01159 // calculate Structure Tensor at inner scale = 1.0 and outer scale = 3.0 01160 vigra::structureTensor(srcImageRange(src), 01161 destImage(stxx), destImage(stxy), destImage(styy), 1.0, 3.0); 01162 01163 \endcode 01164 01165 */ 01166 template <class SrcIterator, class SrcAccessor, 01167 class DestIteratorX, class DestAccessorX, 01168 class DestIteratorXY, class DestAccessorXY, 01169 class DestIteratorY, class DestAccessorY> 01170 void structureTensor(SrcIterator supperleft, 01171 SrcIterator slowerright, SrcAccessor sa, 01172 DestIteratorX dupperleftx, DestAccessorX dax, 01173 DestIteratorXY dupperleftxy, DestAccessorXY daxy, 01174 DestIteratorY dupperlefty, DestAccessorY day, 01175 double inner_scale, double outer_scale) 01176 { 01177 typedef typename 01178 NumericTraits<typename SrcAccessor::value_type>::RealPromote 01179 TmpType; 01180 BasicImage<TmpType> tmp(slowerright - supperleft), 01181 tmpx(slowerright - supperleft), 01182 tmpy(slowerright - supperleft); 01183 01184 gaussianGradient(srcIterRange(supperleft, slowerright, sa), 01185 destImage(tmpx), destImage(tmpy), inner_scale); 01186 combineTwoImages(srcImageRange(tmpx), srcImage(tmpx), 01187 destImage(tmp), std::multiplies<TmpType>()); 01188 gaussianSmoothing(srcImageRange(tmp), 01189 destIter(dupperleftx, dax), outer_scale); 01190 combineTwoImages(srcImageRange(tmpy), srcImage(tmpy), 01191 destImage(tmp), std::multiplies<TmpType>()); 01192 gaussianSmoothing(srcImageRange(tmp), 01193 destIter(dupperlefty, day), outer_scale); 01194 combineTwoImages(srcImageRange(tmpx), srcImage(tmpy), 01195 destImage(tmp), std::multiplies<TmpType>()); 01196 gaussianSmoothing(srcImageRange(tmp), 01197 destIter(dupperleftxy, daxy), outer_scale); 01198 } 01199 01200 template <class SrcIterator, class SrcAccessor, 01201 class DestIteratorX, class DestAccessorX, 01202 class DestIteratorXY, class DestAccessorXY, 01203 class DestIteratorY, class DestAccessorY> 01204 inline void 01205 structureTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01206 pair<DestIteratorX, DestAccessorX> destx, 01207 pair<DestIteratorXY, DestAccessorXY> destxy, 01208 pair<DestIteratorY, DestAccessorY> desty, 01209 double inner_scale, double outer_scale) 01210 { 01211 structureTensor(src.first, src.second, src.third, 01212 destx.first, destx.second, 01213 destxy.first, destxy.second, 01214 desty.first, desty.second, 01215 inner_scale, outer_scale); 01216 } 01217 01218 //@} 01219 01220 } // namespace vigra 01221 01222 #endif // VIGRA_CONVOLUTION_HXX
© Ullrich Köthe (koethe@informatik.uni-hamburg.de) |
html generated using doxygen and Python
|