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

© Ullrich Köthe (koethe@informatik.uni-hamburg.de) Cognitive Systems Group, University of Hamburg, Germany | html generated using doxygen and Python VIGRA 1.4.0 (21 Dec 2005)