[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | 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.6.0, Aug 13 2008 )                                    */
    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 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
    00014 /*        vigra@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 doxygen_overloaded_function(template <...> void separableConvolveMultiArray)
    00227
    00228 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00229           class DestIterator, class DestAccessor, class KernelIterator>
    00230 void
    00231 separableConvolveMultiArray( SrcIterator s, SrcShape const & shape, SrcAccessor src,
    00232                              DestIterator d, DestAccessor dest, KernelIterator kernels )
    00233 {
    00234     typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType;
    00235
    00236     if(!IsSameType<TmpType, typename DestAccessor::value_type>::boolResult)
    00237     {
    00238         // need a temporary array to avoid rounding errors
    00239         MultiArray<SrcShape::static_size, TmpType> tmpArray(shape);
    00240         detail::internalSeparableConvolveMultiArrayTmp( s, shape, src,
    00241              tmpArray.traverser_begin(), typename AccessorTraits<TmpType>::default_accessor(), kernels );
    00242         copyMultiArray(srcMultiArrayRange(tmpArray), destIter(d, dest));
    00243     }
    00244     else
    00245     {
    00246         // work directly on the destination array
    00247         detail::internalSeparableConvolveMultiArrayTmp( s, shape, src, d, dest, kernels );
    00248     }
    00249 }
    00250
    00251 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00252           class DestIterator, class DestAccessor, class KernelIterator>
    00253 inline
    00254 void separableConvolveMultiArray(
    00255     triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00256     pair<DestIterator, DestAccessor> const & dest, KernelIterator kit )
    00257 {
    00258     separableConvolveMultiArray( source.first, source.second, source.third,
    00259                                  dest.first, dest.second, kit );
    00260 }
    00261
    00262 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00263           class DestIterator, class DestAccessor, class T>
    00264 inline void
    00265 separableConvolveMultiArray( SrcIterator s, SrcShape const & shape, SrcAccessor src,
    00266                              DestIterator d, DestAccessor dest,
    00267                              Kernel1D<T> const & kernel )
    00268 {
    00269     ArrayVector<Kernel1D<T> > kernels(shape.size(), kernel);
    00270
    00271     separableConvolveMultiArray( s, shape, src, d, dest, kernels.begin() );
    00272 }
    00273
    00274 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00275           class DestIterator, class DestAccessor, class T>
    00276 inline void
    00277 separableConvolveMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00278                             pair<DestIterator, DestAccessor> const & dest,
    00279                             Kernel1D<T> const & kernel )
    00280 {
    00281     ArrayVector<Kernel1D<T> > kernels(source.second.size(), kernel);
    00282
    00283     separableConvolveMultiArray( source.first, source.second, source.third,
    00284                                  dest.first, dest.second, kernels.begin() );
    00285 }
    00286
    00287 /********************************************************/
    00288 /*                                                      */
    00289 /*            convolveMultiArrayOneDimension            */
    00290 /*                                                      */
    00291 /********************************************************/
    00292
    00293 /** \brief Convolution along a single dimension of a multi-dimensional arrays.
    00294
    00295     This function computes a convolution along one dimension (specified by
    00296     the parameter <tt>dim</tt> of the given multi-dimensional array with the given
    00297     <tt>kernel</tt>. Both source and destination arrays are represented by
    00298     iterators, shape objects and accessors. The destination array is required to
    00299     already have the correct size.
    00300
    00301     This function may work in-place, which means that <tt>siter == diter</tt> is allowed.
    00302
    00303     <b> Declarations:</b>
    00304
    00305     pass arguments explicitly:
    00306     \code
    00307     namespace vigra {
    00308         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00309                   class DestIterator, class DestAccessor, class T>
    00310         void
    00311         convolveMultiArrayOneDimension(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
    00312                                        DestIterator diter, DestAccessor dest,
    00313                                        unsigned int dim, vigra::Kernel1D<T> const & kernel);
    00314     }
    00315     \endcode
    00316
    00317     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00318     \code
    00319     namespace vigra {
    00320         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00321                   class DestIterator, class DestAccessor, class T>
    00322         void
    00323         convolveMultiArrayOneDimension(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00324                                        pair<DestIterator, DestAccessor> const & dest,
    00325                                        unsigned int dim, vigra::Kernel1D<T> const & kernel);
    00326     }
    00327     \endcode
    00328
    00329     <b> Usage:</b>
    00330
    00331     <b>\#include</b> <<a href="multi__convolution_8hxx-source.html">vigra/multi_convolution.hxx</a>>
    00332
    00333     \code
    00334     MultiArray<3, unsigned char>::size_type shape(width, height, depth);
    00335     MultiArray<3, unsigned char> source(shape);
    00336     MultiArray<3, float> dest(shape);
    00337     ...
    00338     Kernel1D<float> gauss;
    00339     gauss.initGaussian(sigma);
    00340
    00341     // perform Gaussian smoothing along dimensions 1 (height)
    00342     convolveMultiArrayOneDimension(srcMultiArrayRange(source), destMultiArray(dest), 1, gauss);
    00343     \endcode
    00344
    00345     \see separableConvolveMultiArray()
    00346 */
    00347 doxygen_overloaded_function(template <...> void convolveMultiArrayOneDimension)
    00348
    00349 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00350           class DestIterator, class DestAccessor, class T>
    00351 void
    00352 convolveMultiArrayOneDimension(SrcIterator s, SrcShape const & shape, SrcAccessor src,
    00353                                DestIterator d, DestAccessor dest,
    00354                                unsigned int dim, vigra::Kernel1D<T> const & kernel )
    00355 {
    00356     enum { N = 1 + SrcIterator::level };
    00357     vigra_precondition( dim < N,
    00358                         "convolveMultiArrayOneDimension(): The dimension number to convolve must be smaller "
    00359                         "than the data dimensionality" );
    00360
    00361     typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType;
    00362     ArrayVector<TmpType> tmp( shape[dim] );
    00363
    00364     typedef MultiArrayNavigator<SrcIterator, N> SNavigator;
    00365     typedef MultiArrayNavigator<DestIterator, N> DNavigator;
    00366
    00367     SNavigator snav( s, shape, dim );
    00368     DNavigator dnav( d, shape, dim );
    00369
    00370     for( ; snav.hasMore(); snav++, dnav++ )
    00371     {
    00372          // first copy source to temp for maximum cache efficiency
    00373          copyLine( snav.begin(), snav.end(), src,
    00374            tmp.begin(), typename AccessorTraits<TmpType>::default_accessor() );
    00375
    00376          convolveLine( srcIterRange( tmp.begin(), tmp.end(), typename AccessorTraits<TmpType>::default_const_accessor()),
    00377                        destIter( dnav.begin(), dest ),
    00378                        kernel1d( kernel ) );
    00379     }
    00380 }
    00381
    00382 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00383           class DestIterator, class DestAccessor, class T>
    00384 inline void
    00385 convolveMultiArrayOneDimension(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00386                                pair<DestIterator, DestAccessor> const & dest,
    00387                                unsigned int dim, vigra::Kernel1D<T> const & kernel )
    00388 {
    00389     convolveMultiArrayOneDimension( source.first, source.second, source.third,
    00390                                    dest.first, dest.second, dim, kernel );
    00391 }
    00392
    00393 /********************************************************/
    00394 /*                                                      */
    00395 /*             gaussianSmoothMultiArray                 */
    00396 /*                                                      */
    00397 /********************************************************/
    00398
    00399 /** \brief Isotropic Gaussian smoothing of a multi-dimensional arrays.
    00400
    00401     This function computes an isotropic convolution of the given multi-dimensional
    00402     array with a Gaussian filter at the given standard deviation <tt>sigma</tt>.
    00403     Both source and destination arrays are represented by
    00404     iterators, shape objects and accessors. The destination array is required to
    00405     already have the correct size. This function may work in-place, which means
    00406     that <tt>siter == diter</tt> is allowed. It is implemented by a call to
    00407     \ref separableConvolveMultiArray() with the appropriate kernel.
    00408     If the data are anisotropic (different pixel size along different dimensions)
    00409     you should call \ref separableConvolveMultiArray() directly with the appropriate
    00410     anisotropic Gaussians.
    00411
    00412     <b> Declarations:</b>
    00413
    00414     pass arguments explicitly:
    00415     \code
    00416     namespace vigra {
    00417         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00418                   class DestIterator, class DestAccessor>
    00419         void
    00420         gaussianSmoothMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
    00421                                  DestIterator diter, DestAccessor dest,
    00422                                  double sigma);
    00423     }
    00424     \endcode
    00425
    00426     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00427     \code
    00428     namespace vigra {
    00429         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00430                   class DestIterator, class DestAccessor>
    00431         void
    00432         gaussianSmoothMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00433                                  pair<DestIterator, DestAccessor> const & dest,
    00434                                  double sigma);
    00435     }
    00436     \endcode
    00437
    00438     <b> Usage:</b>
    00439
    00440     <b>\#include</b> <<a href="multi__convolution_8hxx-source.html">vigra/multi_convolution.hxx</a>>
    00441
    00442     \code
    00443     MultiArray<3, unsigned char>::size_type shape(width, height, depth);
    00444     MultiArray<3, unsigned char> source(shape);
    00445     MultiArray<3, float> dest(shape);
    00446     ...
    00447     // perform isotropic Gaussian smoothing at scale `sigma³
    00448     gaussianSmoothMultiArray(srcMultiArrayRange(source), destMultiArray(dest), sigma);
    00449     \endcode
    00450
    00451     \see separableConvolveMultiArray()
    00452 */
    00453 doxygen_overloaded_function(template <...> void gaussianSmoothMultiArray)
    00454
    00455 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00456           class DestIterator, class DestAccessor>
    00457 void
    00458 gaussianSmoothMultiArray( SrcIterator s, SrcShape const & shape, SrcAccessor src,
    00459                    DestIterator d, DestAccessor dest, double sigma )
    00460 {
    00461     typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote kernel_type;
    00462     Kernel1D<kernel_type> gauss;
    00463     gauss.initGaussian( sigma );
    00464
    00465     separableConvolveMultiArray( s, shape, src, d, dest, gauss);
    00466 }
    00467
    00468 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00469           class DestIterator, class DestAccessor>
    00470 inline void
    00471 gaussianSmoothMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00472                   pair<DestIterator, DestAccessor> const & dest,
    00473                   double sigma )
    00474 {
    00475     gaussianSmoothMultiArray( source.first, source.second, source.third,
    00476                               dest.first, dest.second, sigma );
    00477 }
    00478
    00479 /********************************************************/
    00480 /*                                                      */
    00481 /*             gaussianGradientMultiArray               */
    00482 /*                                                      */
    00483 /********************************************************/
    00484
    00485 /** \brief Calculate Gaussian gradient of a multi-dimensional arrays.
    00486
    00487     This function computes the Gaussian gradient of the given multi-dimensional
    00488     array with a sequence of first-derivative-of-Gaussian filters at the given
    00489     standard deviation <tt>sigma</tt> (differentiation is applied to each dimension
    00490     in turn, starting with the innermost dimension). Both source and destination arrays
    00491     are represented by iterators, shape objects and accessors. The destination array is
    00492     required to have a vector valued pixel type with as many elements as the number of
    00493     dimensions. This function is implemented by calls to
    00494     \ref separableConvolveMultiArray() with the appropriate kernels.
    00495     If the data are anisotropic (different pixel size along different dimensions)
    00496     you should call \ref separableConvolveMultiArray() directly with the appropriate
    00497     anisotropic Gaussian derivatives.
    00498
    00499     <b> Declarations:</b>
    00500
    00501     pass arguments explicitly:
    00502     \code
    00503     namespace vigra {
    00504         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00505                   class DestIterator, class DestAccessor>
    00506         void
    00507         gaussianGradientMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
    00508                                    DestIterator diter, DestAccessor dest,
    00509                                    double sigma);
    00510     }
    00511     \endcode
    00512
    00513     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00514     \code
    00515     namespace vigra {
    00516         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00517                   class DestIterator, class DestAccessor>
    00518         void
    00519         gaussianGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00520                                    pair<DestIterator, DestAccessor> const & dest,
    00521                                    double sigma);
    00522     }
    00523     \endcode
    00524
    00525     <b> Usage:</b>
    00526
    00527     <b>\#include</b> <<a href="multi__convolution_8hxx-source.html">vigra/multi_convolution.hxx</a>>
    00528
    00529     \code
    00530     MultiArray<3, unsigned char>::size_type shape(width, height, depth);
    00531     MultiArray<3, unsigned char> source(shape);
    00532     MultiArray<3, TinyVector<float, 3> > dest(shape);
    00533     ...
    00534     // compute Gaussian gradient at scale sigma
    00535     gaussianGradientMultiArray(srcMultiArrayRange(source), destMultiArray(dest), sigma);
    00536     \endcode
    00537
    00538     <b> Required Interface:</b>
    00539
    00540     see \ref convolveImage(), in addition:
    00541
    00542     \code
    00543     int dimension = 0;
    00544     VectorElementAccessor<DestAccessor> elementAccessor(0, dest);
    00545     \endcode
    00546
    00547     \see separableConvolveMultiArray()
    00548 */
    00549 doxygen_overloaded_function(template <...> void gaussianGradientMultiArray)
    00550
    00551 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00552           class DestIterator, class DestAccessor>
    00553 void
    00554 gaussianGradientMultiArray( SrcIterator si, SrcShape const & shape, SrcAccessor src,
    00555                 DestIterator di, DestAccessor dest, double sigma )
    00556 {
    00557     typedef typename DestAccessor::value_type DestType;
    00558     typedef typename NumericTraits<typename DestType::value_type>::RealPromote kernel_type;
    00559
    00560     Kernel1D<kernel_type> gauss, derivative;
    00561     gauss.initGaussian(sigma);
    00562     derivative.initGaussianDerivative(sigma, 1);
    00563
    00564     typedef VectorElementAccessor<DestAccessor> ElementAccessor;
    00565
    00566     // compute gradient components
    00567     for(unsigned int d = 0; d < shape.size(); ++d )
    00568     {
    00569         ArrayVector<Kernel1D<kernel_type> > kernels(shape.size(), gauss);
    00570         kernels[d] = derivative;
    00571         separableConvolveMultiArray( si, shape, src, di, ElementAccessor(d, dest), kernels.begin());
    00572     }
    00573 }
    00574
    00575 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00576           class DestIterator, class DestAccessor>
    00577 inline void
    00578 gaussianGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00579                   pair<DestIterator, DestAccessor> const & dest, double sigma )
    00580 {
    00581     gaussianGradientMultiArray( source.first, source.second, source.third,
    00582                               dest.first, dest.second, sigma );
    00583 }
    00584
    00585 /********************************************************/
    00586 /*                                                      */
    00587 /*             symmetricGradientMultiArray              */
    00588 /*                                                      */
    00589 /********************************************************/
    00590
    00591 /** \brief Calculate gradient of a multi-dimensional arrays using symmetric difference filters.
    00592
    00593     This function computes the gradient of the given multi-dimensional
    00594     array with a sequence of symmetric difference filters a (differentiation is applied
    00595     to each dimension in turn, starting with the innermost dimension). Both source and
    00596     destination arrays are represented by iterators, shape objects and accessors.
    00597     The destination array is required to have a vector valued pixel type with as many
    00598     elements as the number of dimensions. This function is implemented by calls to
    00599     \ref convolveMultiArrayOneDimension() with the symmetric difference kernel.
    00600
    00601     <b> Declarations:</b>
    00602
    00603     pass arguments explicitly:
    00604     \code
    00605     namespace vigra {
    00606         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00607                   class DestIterator, class DestAccessor>
    00608         void
    00609         symmetricGradientMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
    00610                                     DestIterator diter, DestAccessor dest);
    00611     }
    00612     \endcode
    00613
    00614     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00615     \code
    00616     namespace vigra {
    00617         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00618                   class DestIterator, class DestAccessor>
    00619         void
    00620         symmetricGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00621                                     pair<DestIterator, DestAccessor> const & dest);
    00622     }
    00623     \endcode
    00624
    00625     <b> Usage:</b>
    00626
    00627     <b>\#include</b> <<a href="multi__convolution_8hxx-source.html">vigra/multi_convolution.hxx</a>>
    00628
    00629     \code
    00630     MultiArray<3, unsigned char>::size_type shape(width, height, depth);
    00631     MultiArray<3, unsigned char> source(shape);
    00632     MultiArray<3, TinyVector<float, 3> > dest(shape);
    00633     ...
    00634     // compute gradient
    00635     symmetricGradientMultiArray(srcMultiArrayRange(source), destMultiArray(dest));
    00636     \endcode
    00637
    00638     <b> Required Interface:</b>
    00639
    00640     see \ref convolveImage(), in addition:
    00641
    00642     \code
    00643     int dimension = 0;
    00644     VectorElementAccessor<DestAccessor> elementAccessor(0, dest);
    00645     \endcode
    00646
    00647     \see convolveMultiArrayOneDimension()
    00648 */
    00649 doxygen_overloaded_function(template <...> void symmetricGradientMultiArray)
    00650
    00651 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00652           class DestIterator, class DestAccessor>
    00653 void
    00654 symmetricGradientMultiArray(SrcIterator si, SrcShape const & shape, SrcAccessor src,
    00655                    DestIterator di, DestAccessor dest)
    00656 {
    00657     typedef typename DestAccessor::value_type DestType;
    00658     typedef typename NumericTraits<typename DestType::value_type>::RealPromote kernel_type;
    00659
    00660     Kernel1D<kernel_type> filter;
    00661     filter.initSymmetricGradient();
    00662
    00663     typedef VectorElementAccessor<DestAccessor> ElementAccessor;
    00664
    00665     // compute gradient components
    00666     for(unsigned int d = 0; d < shape.size(); ++d )
    00667     {
    00668         convolveMultiArrayOneDimension(si, shape, src,
    00669                                        di, ElementAccessor(d, dest),
    00670                                        d, filter);
    00671     }
    00672 }
    00673
    00674 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00675           class DestIterator, class DestAccessor>
    00676 inline void
    00677 symmetricGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00678                             pair<DestIterator, DestAccessor> const & dest )
    00679 {
    00680     symmetricGradientMultiArray(source.first, source.second, source.third,
    00681                                 dest.first, dest.second);
    00682 }
    00683
    00684 //@}
    00685
    00686 } //-- namespace vigra
    00687
    00688
    00689 #endif        //-- VIGRA_MULTI_CONVOLUTION_H

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python VIGRA 1.6.0 (13 Aug 2008)