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