[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]
![]() |
vigra/multi_convolution.hxx | ![]() |
---|
00001 //-- -*- c++ -*- 00002 /************************************************************************/ 00003 /* */ 00004 /* Copyright 2003 by Christian-Dennis Rahn */ 00005 /* and Ullrich Koethe */ 00006 /* Cognitive Systems Group, University of Hamburg, Germany */ 00007 /* */ 00008 /* This file is part of the VIGRA computer vision library. */ 00009 /* ( Version 1.5.0, Dec 07 2006 ) */ 00010 /* The VIGRA Website is */ 00011 /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ 00012 /* Please direct questions, bug reports, and contributions to */ 00013 /* koethe@informatik.uni-hamburg.de or */ 00014 /* vigra@kogs1.informatik.uni-hamburg.de */ 00015 /* */ 00016 /* Permission is hereby granted, free of charge, to any person */ 00017 /* obtaining a copy of this software and associated documentation */ 00018 /* files (the "Software"), to deal in the Software without */ 00019 /* restriction, including without limitation the rights to use, */ 00020 /* copy, modify, merge, publish, distribute, sublicense, and/or */ 00021 /* sell copies of the Software, and to permit persons to whom the */ 00022 /* Software is furnished to do so, subject to the following */ 00023 /* conditions: */ 00024 /* */ 00025 /* The above copyright notice and this permission notice shall be */ 00026 /* included in all copies or substantial portions of the */ 00027 /* Software. */ 00028 /* */ 00029 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ 00030 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ 00031 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ 00032 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ 00033 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ 00034 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ 00035 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ 00036 /* OTHER DEALINGS IN THE SOFTWARE. */ 00037 /* */ 00038 /************************************************************************/ 00039 00040 #ifndef VIGRA_MULTI_CONVOLUTION_H 00041 #define VIGRA_MULTI_CONVOLUTION_H 00042 00043 #include "separableconvolution.hxx" 00044 #include "array_vector.hxx" 00045 #include "multi_array.hxx" 00046 #include "accessor.hxx" 00047 #include "numerictraits.hxx" 00048 #include "navigator.hxx" 00049 #include "metaprogramming.hxx" 00050 #include "multi_pointoperators.hxx" 00051 00052 00053 namespace vigra 00054 { 00055 00056 00057 namespace detail 00058 { 00059 00060 /********************************************************/ 00061 /* */ 00062 /* internalSeparableConvolveMultiArray */ 00063 /* */ 00064 /********************************************************/ 00065 00066 template <class SrcIterator, class SrcShape, class SrcAccessor, 00067 class DestIterator, class DestAccessor, class KernelIterator> 00068 void 00069 internalSeparableConvolveMultiArrayTmp( 00070 SrcIterator si, SrcShape const & shape, SrcAccessor src, 00071 DestIterator di, DestAccessor dest, KernelIterator kit) 00072 { 00073 enum { N = 1 + SrcIterator::level }; 00074 00075 typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType; 00076 00077 // temporay array to hold the current line to enable in-place operation 00078 ArrayVector<TmpType> tmp( shape[0] ); 00079 00080 typedef MultiArrayNavigator<SrcIterator, N> SNavigator; 00081 typedef MultiArrayNavigator<DestIterator, N> DNavigator; 00082 00083 { // only operate on first dimension here 00084 SNavigator snav( si, shape, 0 ); 00085 DNavigator dnav( di, shape, 0 ); 00086 00087 for( ; snav.hasMore(); snav++, dnav++ ) 00088 { 00089 // first copy source to temp for maximum cache efficiency 00090 copyLine( snav.begin(), snav.end(), src, 00091 tmp.begin(), typename AccessorTraits<TmpType>::default_accessor() ); 00092 00093 convolveLine( srcIterRange(tmp.begin(), tmp.end(), 00094 typename AccessorTraits<TmpType>::default_const_accessor()), 00095 destIter( dnav.begin(), dest ), 00096 kernel1d( *kit ) ); 00097 } 00098 ++kit; 00099 } 00100 00101 // operate on further dimensions 00102 for( int d = 1; d < N; ++d, ++kit ) 00103 { 00104 DNavigator dnav( di, shape, d ); 00105 00106 tmp.resize( shape[d] ); 00107 00108 for( ; dnav.hasMore(); dnav++ ) 00109 { 00110 // first copy source to temp for maximum cache efficiency 00111 copyLine( dnav.begin(), dnav.end(), dest, 00112 tmp.begin(), typename AccessorTraits<TmpType>::default_accessor() ); 00113 00114 convolveLine( srcIterRange(tmp.begin(), tmp.end(), 00115 typename AccessorTraits<TmpType>::default_const_accessor()), 00116 destIter( dnav.begin(), dest ), 00117 kernel1d( *kit ) ); 00118 } 00119 } 00120 } 00121 00122 00123 } // namespace detail 00124 00125 /** \addtogroup MultiArrayConvolutionFilters Convolution filters for multi-dimensional arrays. 00126 00127 These functions realize a separable convolution on an arbitrary dimensional 00128 array that is specified by iterators (compatible to \ref MultiIteratorPage) 00129 and shape objects. It can therefore be applied to a wide range of data structures 00130 (\ref vigra::MultiArrayView, \ref vigra::MultiArray etc.). 00131 */ 00132 //@{ 00133 00134 /********************************************************/ 00135 /* */ 00136 /* separableConvolveMultiArray */ 00137 /* */ 00138 /********************************************************/ 00139 00140 /** \brief Separated convolution on multi-dimensional arrays. 00141 00142 This function computes a separated convolution on all dimensions 00143 of the given multi-dimensional array. Both source and destination 00144 arrays are represented by iterators, shape objects and accessors. 00145 The destination array is required to already have the correct size. 00146 00147 There are two variants of this functions: one takes a single kernel 00148 of type \ref vigra::Kernel1D which is then applied to all dimensions, 00149 whereas the other requires an iterator referencing a sequence of 00150 \ref vigra::Kernel1D objects, one for every dimension of the data. 00151 Then the first kernel in this sequence is applied to the innermost 00152 dimension (e.g. the x-dimension of an image), while the last is applied to the 00153 outermost dimension (e.g. the z-dimension in a 3D image). 00154 00155 This function may work in-place, which means that <tt>siter == diter</tt> is allowed. 00156 A full-sized internal array is only allocated if working on the destination 00157 array directly would cause round-off errors (i.e. if 00158 <tt>typeid(typename NumericTraits<typename DestAccessor::value_type>::RealPromote) 00159 != typeid(typename DestAccessor::value_type)</tt>. 00160 00161 <b> Declarations:</b> 00162 00163 pass arguments explicitly: 00164 \code 00165 namespace vigra { 00166 // apply the same kernel to all dimensions 00167 template <class SrcIterator, class SrcShape, class SrcAccessor, 00168 class DestIterator, class DestAccessor, class T> 00169 void 00170 separableConvolveMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src, 00171 DestIterator diter, DestAccessor dest, 00172 Kernel1D<T> const & kernel); 00173 00174 // apply each kernel from the sequence `kernels³ in turn 00175 template <class SrcIterator, class SrcShape, class SrcAccessor, 00176 class DestIterator, class DestAccessor, class KernelIterator> 00177 void 00178 separableConvolveMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src, 00179 DestIterator diter, DestAccessor dest, 00180 KernelIterator kernels); 00181 } 00182 \endcode 00183 00184 use argument objects in conjunction with \ref ArgumentObjectFactories: 00185 \code 00186 namespace vigra { 00187 // apply the same kernel to all dimensions 00188 template <class SrcIterator, class SrcShape, class SrcAccessor, 00189 class DestIterator, class DestAccessor, class T> 00190 void 00191 separableConvolveMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source, 00192 pair<DestIterator, DestAccessor> const & dest, 00193 Kernel1D<T> const & kernel); 00194 00195 // apply each kernel from the sequence `kernels³ in turn 00196 template <class SrcIterator, class SrcShape, class SrcAccessor, 00197 class DestIterator, class DestAccessor, class KernelIterator> 00198 void 00199 separableConvolveMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source, 00200 pair<DestIterator, DestAccessor> const & dest, 00201 KernelIterator kernels); 00202 } 00203 \endcode 00204 00205 <b> Usage:</b> 00206 00207 <b>\#include</b> "<a href="multi__convolution_8hxx-source.html">vigra/multi_convolution.hxx</a>" 00208 00209 \code 00210 MultiArray<3, unsigned char>::size_type shape(width, height, depth); 00211 MultiArray<3, unsigned char> source(shape); 00212 MultiArray<3, float> dest(shape); 00213 ... 00214 Kernel1D<float> gauss; 00215 gauss.initGaussian(sigma); 00216 // create 3 Gauss kernels, one for each dimension 00217 ArrayVector<Kernel1D<float> > kernels(3, gauss); 00218 00219 // perform Gaussian smoothing on all dimensions 00220 separableConvolveMultiArray(srcMultiArrayRange(source), destMultiArray(dest), 00221 kernels.begin()); 00222 \endcode 00223 00224 \see vigra::Kernel1D, convolveLine() 00225 */ 00226 template <class SrcIterator, class SrcShape, class SrcAccessor, 00227 class DestIterator, class DestAccessor, class KernelIterator> 00228 void 00229 separableConvolveMultiArray( SrcIterator s, SrcShape const & shape, SrcAccessor src, 00230 DestIterator d, DestAccessor dest, KernelIterator kernels ) 00231 { 00232 typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType; 00233 00234 if(!IsSameType<TmpType, typename DestAccessor::value_type>::boolResult) 00235 { 00236 // need a temporary array to avoid rounding errors 00237 MultiArray<SrcShape::static_size, TmpType> tmpArray(shape); 00238 detail::internalSeparableConvolveMultiArrayTmp( s, shape, src, 00239 tmpArray.traverser_begin(), typename AccessorTraits<TmpType>::default_accessor(), kernels ); 00240 copyMultiArray(srcMultiArrayRange(tmpArray), destIter(d, dest)); 00241 } 00242 else 00243 { 00244 // work directly on the destination array 00245 detail::internalSeparableConvolveMultiArrayTmp( s, shape, src, d, dest, kernels ); 00246 } 00247 } 00248 00249 template <class SrcIterator, class SrcShape, class SrcAccessor, 00250 class DestIterator, class DestAccessor, class KernelIterator> 00251 inline 00252 void separableConvolveMultiArray( 00253 triple<SrcIterator, SrcShape, SrcAccessor> const & source, 00254 pair<DestIterator, DestAccessor> const & dest, KernelIterator kit ) 00255 { 00256 separableConvolveMultiArray( source.first, source.second, source.third, 00257 dest.first, dest.second, kit ); 00258 } 00259 00260 template <class SrcIterator, class SrcShape, class SrcAccessor, 00261 class DestIterator, class DestAccessor, class T> 00262 inline void 00263 separableConvolveMultiArray( SrcIterator s, SrcShape const & shape, SrcAccessor src, 00264 DestIterator d, DestAccessor dest, 00265 Kernel1D<T> const & kernel ) 00266 { 00267 ArrayVector<Kernel1D<T> > kernels(shape.size(), kernel); 00268 00269 separableConvolveMultiArray( s, shape, src, d, dest, kernels.begin() ); 00270 } 00271 00272 template <class SrcIterator, class SrcShape, class SrcAccessor, 00273 class DestIterator, class DestAccessor, class T> 00274 inline void 00275 separableConvolveMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source, 00276 pair<DestIterator, DestAccessor> const & dest, 00277 Kernel1D<T> const & kernel ) 00278 { 00279 ArrayVector<Kernel1D<T> > kernels(source.second.size(), kernel); 00280 00281 separableConvolveMultiArray( source.first, source.second, source.third, 00282 dest.first, dest.second, kernels.begin() ); 00283 } 00284 00285 /********************************************************/ 00286 /* */ 00287 /* convolveMultiArrayOneDimension */ 00288 /* */ 00289 /********************************************************/ 00290 00291 /** \brief Convolution along a single dimension of a multi-dimensional arrays. 00292 00293 This function computes a convolution along one dimension (specified by 00294 the parameter <tt>dim</tt> of the given multi-dimensional array with the given 00295 <tt>kernel</tt>. Both source and destination arrays are represented by 00296 iterators, shape objects and accessors. The destination array is required to 00297 already have the correct size. 00298 00299 This function may work in-place, which means that <tt>siter == diter</tt> is allowed. 00300 00301 <b> Declarations:</b> 00302 00303 pass arguments explicitly: 00304 \code 00305 namespace vigra { 00306 template <class SrcIterator, class SrcShape, class SrcAccessor, 00307 class DestIterator, class DestAccessor, class T> 00308 void 00309 convolveMultiArrayOneDimension(SrcIterator siter, SrcShape const & shape, SrcAccessor src, 00310 DestIterator diter, DestAccessor dest, 00311 unsigned int dim, vigra::Kernel1D<T> const & kernel); 00312 } 00313 \endcode 00314 00315 use argument objects in conjunction with \ref ArgumentObjectFactories: 00316 \code 00317 namespace vigra { 00318 template <class SrcIterator, class SrcShape, class SrcAccessor, 00319 class DestIterator, class DestAccessor, class T> 00320 void 00321 convolveMultiArrayOneDimension(triple<SrcIterator, SrcShape, SrcAccessor> const & source, 00322 pair<DestIterator, DestAccessor> const & dest, 00323 unsigned int dim, vigra::Kernel1D<T> const & kernel); 00324 } 00325 \endcode 00326 00327 <b> Usage:</b> 00328 00329 <b>\#include</b> "<a href="multi__convolution_8hxx-source.html">vigra/multi_convolution.hxx</a>" 00330 00331 \code 00332 MultiArray<3, unsigned char>::size_type shape(width, height, depth); 00333 MultiArray<3, unsigned char> source(shape); 00334 MultiArray<3, float> dest(shape); 00335 ... 00336 Kernel1D<float> gauss; 00337 gauss.initGaussian(sigma); 00338 00339 // perform Gaussian smoothing along dimensions 1 (height) 00340 convolveMultiArrayOneDimension(srcMultiArrayRange(source), destMultiArray(dest), 1, gauss); 00341 \endcode 00342 00343 \see separableConvolveMultiArray() 00344 */ 00345 template <class SrcIterator, class SrcShape, class SrcAccessor, 00346 class DestIterator, class DestAccessor, class T> 00347 void 00348 convolveMultiArrayOneDimension(SrcIterator s, SrcShape const & shape, SrcAccessor src, 00349 DestIterator d, DestAccessor dest, 00350 unsigned int dim, vigra::Kernel1D<T> const & kernel ) 00351 { 00352 enum { N = 1 + SrcIterator::level }; 00353 vigra_precondition( dim < N, 00354 "convolveMultiArrayOneDimension(): The dimension number to convolve must be smaller " 00355 "than the data dimensionality" ); 00356 00357 typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType; 00358 ArrayVector<TmpType> tmp( shape[dim] ); 00359 00360 typedef MultiArrayNavigator<SrcIterator, N> SNavigator; 00361 typedef MultiArrayNavigator<DestIterator, N> DNavigator; 00362 00363 SNavigator snav( s, shape, dim ); 00364 DNavigator dnav( d, shape, dim ); 00365 00366 for( ; snav.hasMore(); snav++, dnav++ ) 00367 { 00368 // first copy source to temp for maximum cache efficiency 00369 copyLine( snav.begin(), snav.end(), src, 00370 tmp.begin(), typename AccessorTraits<TmpType>::default_accessor() ); 00371 00372 convolveLine( srcIterRange( tmp.begin(), tmp.end(), typename AccessorTraits<TmpType>::default_const_accessor()), 00373 destIter( dnav.begin(), dest ), 00374 kernel1d( kernel ) ); 00375 } 00376 } 00377 00378 template <class SrcIterator, class SrcShape, class SrcAccessor, 00379 class DestIterator, class DestAccessor, class T> 00380 inline void 00381 convolveMultiArrayOneDimension(triple<SrcIterator, SrcShape, SrcAccessor> const & source, 00382 pair<DestIterator, DestAccessor> const & dest, 00383 unsigned int dim, vigra::Kernel1D<T> const & kernel ) 00384 { 00385 convolveMultiArrayOneDimension( source.first, source.second, source.third, 00386 dest.first, dest.second, dim, kernel ); 00387 } 00388 00389 /********************************************************/ 00390 /* */ 00391 /* gaussianSmoothMultiArray */ 00392 /* */ 00393 /********************************************************/ 00394 00395 /** \brief Isotropic Gaussian smoothing of a multi-dimensional arrays. 00396 00397 This function computes an isotropic convolution of the given multi-dimensional 00398 array with a Gaussian filter at the given standard deviation <tt>sigma</tt>. 00399 Both source and destination arrays are represented by 00400 iterators, shape objects and accessors. The destination array is required to 00401 already have the correct size. This function may work in-place, which means 00402 that <tt>siter == diter</tt> is allowed. It is implemented by a call to 00403 \ref separableConvolveMultiArray() with the appropriate kernel. 00404 If the data are anisotropic (different pixel size along different dimensions) 00405 you should call \ref separableConvolveMultiArray() directly with the appropriate 00406 anisotropic Gaussians. 00407 00408 <b> Declarations:</b> 00409 00410 pass arguments explicitly: 00411 \code 00412 namespace vigra { 00413 template <class SrcIterator, class SrcShape, class SrcAccessor, 00414 class DestIterator, class DestAccessor> 00415 void 00416 gaussianSmoothMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src, 00417 DestIterator diter, DestAccessor dest, 00418 double sigma); 00419 } 00420 \endcode 00421 00422 use argument objects in conjunction with \ref ArgumentObjectFactories: 00423 \code 00424 namespace vigra { 00425 template <class SrcIterator, class SrcShape, class SrcAccessor, 00426 class DestIterator, class DestAccessor> 00427 void 00428 gaussianSmoothMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source, 00429 pair<DestIterator, DestAccessor> const & dest, 00430 double sigma); 00431 } 00432 \endcode 00433 00434 <b> Usage:</b> 00435 00436 <b>\#include</b> "<a href="multi__convolution_8hxx-source.html">vigra/multi_convolution.hxx</a>" 00437 00438 \code 00439 MultiArray<3, unsigned char>::size_type shape(width, height, depth); 00440 MultiArray<3, unsigned char> source(shape); 00441 MultiArray<3, float> dest(shape); 00442 ... 00443 // perform isotropic Gaussian smoothing at scale `sigma³ 00444 gaussianSmoothMultiArray(srcMultiArrayRange(source), destMultiArray(dest), sigma); 00445 \endcode 00446 00447 \see separableConvolveMultiArray() 00448 */ 00449 template <class SrcIterator, class SrcShape, class SrcAccessor, 00450 class DestIterator, class DestAccessor> 00451 void 00452 gaussianSmoothMultiArray( SrcIterator s, SrcShape const & shape, SrcAccessor src, 00453 DestIterator d, DestAccessor dest, double sigma ) 00454 { 00455 typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote kernel_type; 00456 Kernel1D<kernel_type> gauss; 00457 gauss.initGaussian( sigma ); 00458 00459 separableConvolveMultiArray( s, shape, src, d, dest, gauss); 00460 } 00461 00462 template <class SrcIterator, class SrcShape, class SrcAccessor, 00463 class DestIterator, class DestAccessor> 00464 inline void 00465 gaussianSmoothMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source, 00466 pair<DestIterator, DestAccessor> const & dest, 00467 double sigma ) 00468 { 00469 gaussianSmoothMultiArray( source.first, source.second, source.third, 00470 dest.first, dest.second, sigma ); 00471 } 00472 00473 /********************************************************/ 00474 /* */ 00475 /* gaussianGradientMultiArray */ 00476 /* */ 00477 /********************************************************/ 00478 00479 /** \brief Calculate Gaussian gradient of a multi-dimensional arrays. 00480 00481 This function computes the Gaussian gradient of the given multi-dimensional 00482 array with a sequence of first-derivative-of-Gaussian filters at the given 00483 standard deviation <tt>sigma</tt> (differentiation is applied to each dimension 00484 in turn, starting with the innermost dimension). Both source and destination arrays 00485 are represented by iterators, shape objects and accessors. The destination array is 00486 required to have a vector valued pixel type with as many elements as the number of 00487 dimensions. This function is implemented by calls to 00488 \ref separableConvolveMultiArray() with the appropriate kernels. 00489 If the data are anisotropic (different pixel size along different dimensions) 00490 you should call \ref separableConvolveMultiArray() directly with the appropriate 00491 anisotropic Gaussian derivatives. 00492 00493 <b> Declarations:</b> 00494 00495 pass arguments explicitly: 00496 \code 00497 namespace vigra { 00498 template <class SrcIterator, class SrcShape, class SrcAccessor, 00499 class DestIterator, class DestAccessor> 00500 void 00501 gaussianGradientMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src, 00502 DestIterator diter, DestAccessor dest, 00503 double sigma); 00504 } 00505 \endcode 00506 00507 use argument objects in conjunction with \ref ArgumentObjectFactories: 00508 \code 00509 namespace vigra { 00510 template <class SrcIterator, class SrcShape, class SrcAccessor, 00511 class DestIterator, class DestAccessor> 00512 void 00513 gaussianGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source, 00514 pair<DestIterator, DestAccessor> const & dest, 00515 double sigma); 00516 } 00517 \endcode 00518 00519 <b> Usage:</b> 00520 00521 <b>\#include</b> "<a href="multi__convolution_8hxx-source.html">vigra/multi_convolution.hxx</a>" 00522 00523 \code 00524 MultiArray<3, unsigned char>::size_type shape(width, height, depth); 00525 MultiArray<3, unsigned char> source(shape); 00526 MultiArray<3, TinyVector<float, 3> > dest(shape); 00527 ... 00528 // compute Gaussian gradient at scale sigma 00529 gaussianGradientMultiArray(srcMultiArrayRange(source), destMultiArray(dest), sigma); 00530 \endcode 00531 00532 <b> Required Interface:</b> 00533 00534 see \ref convolveImage(), in addition: 00535 00536 \code 00537 int dimension = 0; 00538 VectorElementAccessor<DestAccessor> elementAccessor(0, dest); 00539 \endcode 00540 00541 \see separableConvolveMultiArray() 00542 */ 00543 template <class SrcIterator, class SrcShape, class SrcAccessor, 00544 class DestIterator, class DestAccessor> 00545 void 00546 gaussianGradientMultiArray( SrcIterator si, SrcShape const & shape, SrcAccessor src, 00547 DestIterator di, DestAccessor dest, double sigma ) 00548 { 00549 typedef typename DestAccessor::value_type DestType; 00550 typedef typename NumericTraits<typename DestType::value_type>::RealPromote kernel_type; 00551 00552 Kernel1D<kernel_type> gauss, derivative; 00553 gauss.initGaussian(sigma); 00554 derivative.initGaussianDerivative(sigma, 1); 00555 00556 typedef VectorElementAccessor<DestAccessor> ElementAccessor; 00557 00558 // compute gradient components 00559 for(unsigned int d = 0; d < shape.size(); ++d ) 00560 { 00561 ArrayVector<Kernel1D<kernel_type> > kernels(shape.size(), gauss); 00562 kernels[d] = derivative; 00563 separableConvolveMultiArray( si, shape, src, di, ElementAccessor(d, dest), kernels.begin()); 00564 } 00565 } 00566 00567 template <class SrcIterator, class SrcShape, class SrcAccessor, 00568 class DestIterator, class DestAccessor> 00569 inline void 00570 gaussianGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source, 00571 pair<DestIterator, DestAccessor> const & dest, double sigma ) 00572 { 00573 gaussianGradientMultiArray( source.first, source.second, source.third, 00574 dest.first, dest.second, sigma ); 00575 } 00576 00577 /********************************************************/ 00578 /* */ 00579 /* symmetricGradientMultiArray */ 00580 /* */ 00581 /********************************************************/ 00582 00583 /** \brief Calculate gradient of a multi-dimensional arrays using symmetric difference filters. 00584 00585 This function computes the gradient of the given multi-dimensional 00586 array with a sequence of symmetric difference filters a (differentiation is applied 00587 to each dimension in turn, starting with the innermost dimension). Both source and 00588 destination arrays are represented by iterators, shape objects and accessors. 00589 The destination array is required to have a vector valued pixel type with as many 00590 elements as the number of dimensions. This function is implemented by calls to 00591 \ref convolveMultiArrayOneDimension() with the symmetric difference kernel. 00592 00593 <b> Declarations:</b> 00594 00595 pass arguments explicitly: 00596 \code 00597 namespace vigra { 00598 template <class SrcIterator, class SrcShape, class SrcAccessor, 00599 class DestIterator, class DestAccessor> 00600 void 00601 symmetricGradientMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src, 00602 DestIterator diter, DestAccessor dest); 00603 } 00604 \endcode 00605 00606 use argument objects in conjunction with \ref ArgumentObjectFactories: 00607 \code 00608 namespace vigra { 00609 template <class SrcIterator, class SrcShape, class SrcAccessor, 00610 class DestIterator, class DestAccessor> 00611 void 00612 symmetricGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source, 00613 pair<DestIterator, DestAccessor> const & dest); 00614 } 00615 \endcode 00616 00617 <b> Usage:</b> 00618 00619 <b>\#include</b> "<a href="multi__convolution_8hxx-source.html">vigra/multi_convolution.hxx</a>" 00620 00621 \code 00622 MultiArray<3, unsigned char>::size_type shape(width, height, depth); 00623 MultiArray<3, unsigned char> source(shape); 00624 MultiArray<3, TinyVector<float, 3> > dest(shape); 00625 ... 00626 // compute gradient 00627 symmetricGradientMultiArray(srcMultiArrayRange(source), destMultiArray(dest)); 00628 \endcode 00629 00630 <b> Required Interface:</b> 00631 00632 see \ref convolveImage(), in addition: 00633 00634 \code 00635 int dimension = 0; 00636 VectorElementAccessor<DestAccessor> elementAccessor(0, dest); 00637 \endcode 00638 00639 \see convolveMultiArrayOneDimension() 00640 */ 00641 template <class SrcIterator, class SrcShape, class SrcAccessor, 00642 class DestIterator, class DestAccessor> 00643 void 00644 symmetricGradientMultiArray(SrcIterator si, SrcShape const & shape, SrcAccessor src, 00645 DestIterator di, DestAccessor dest) 00646 { 00647 typedef typename DestAccessor::value_type DestType; 00648 typedef typename NumericTraits<typename DestType::value_type>::RealPromote kernel_type; 00649 00650 Kernel1D<kernel_type> filter; 00651 filter.initSymmetricGradient(); 00652 00653 typedef VectorElementAccessor<DestAccessor> ElementAccessor; 00654 00655 // compute gradient components 00656 for(unsigned int d = 0; d < shape.size(); ++d ) 00657 { 00658 convolveMultiArrayOneDimension(si, shape, src, 00659 di, ElementAccessor(d, dest), 00660 d, filter); 00661 } 00662 } 00663 00664 template <class SrcIterator, class SrcShape, class SrcAccessor, 00665 class DestIterator, class DestAccessor> 00666 inline void 00667 symmetricGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source, 00668 pair<DestIterator, DestAccessor> const & dest ) 00669 { 00670 symmetricGradientMultiArray(source.first, source.second, source.third, 00671 dest.first, dest.second); 00672 } 00673 00674 //@} 00675 00676 } //-- namespace vigra 00677 00678 00679 #endif //-- VIGRA_MULTI_CONVOLUTION_H
© Ullrich Köthe (koethe@informatik.uni-hamburg.de) |
html generated using doxygen and Python
|