[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

vigra/multi_morphology.hxx |

    00001 /************************************************************************/
    00002 /*                                                                      */
    00003 /*     Copyright 2003-2007 by Kasim Terzic, Christian-Dennis Rahn       */
    00004 /*                        and Ullrich Koethe                            */
    00005 /*                                                                      */
    00006 /*    This file is part of the VIGRA computer vision library.           */
    00007 /*    The VIGRA Website is                                              */
    00008 /*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
    00009 /*    Please direct questions, bug reports, and contributions to        */
    00010 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
    00011 /*        vigra@informatik.uni-hamburg.de                               */
    00012 /*                                                                      */
    00013 /*    Permission is hereby granted, free of charge, to any person       */
    00014 /*    obtaining a copy of this software and associated documentation    */
    00015 /*    files (the "Software"), to deal in the Software without           */
    00016 /*    restriction, including without limitation the rights to use,      */
    00017 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
    00018 /*    sell copies of the Software, and to permit persons to whom the    */
    00019 /*    Software is furnished to do so, subject to the following          */
    00020 /*    conditions:                                                       */
    00021 /*                                                                      */
    00022 /*    The above copyright notice and this permission notice shall be    */
    00023 /*    included in all copies or substantial portions of the             */
    00024 /*    Software.                                                         */
    00025 /*                                                                      */
    00026 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
    00027 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
    00028 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
    00029 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
    00030 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
    00031 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
    00032 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
    00033 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
    00034 /*                                                                      */
    00035 /************************************************************************/
    00036
    00037 #ifndef VIGRA_MULTI_MORPHOLOGY_HXX
    00038 #define VIGRA_MULTI_MORPHOLOGY_HXX
    00039
    00040 #include <vector>
    00041 #include <cmath>
    00042 #include "multi_distance.hxx"
    00043 #include "array_vector.hxx"
    00044 #include "multi_array.hxx"
    00045 #include "accessor.hxx"
    00046 #include "numerictraits.hxx"
    00047 #include "navigator.hxx"
    00048 #include "metaprogramming.hxx"
    00049 #include "multi_pointoperators.hxx"
    00050 #include "functorexpression.hxx"
    00051
    00052 namespace vigra
    00053 {
    00054
    00055 namespace detail {
    00056
    00057 // this class simplfies the design, but more importantly, it makes sure
    00058 // that the in-place code doesn't get compiled for boolean arrays
    00059 // (were it would never executed anyway -- see the specializations below)
    00060 template <class DestType, class TmpType>
    00061 struct MultiBinaryMorphologyImpl
    00062 {
    00063     template <class SrcIterator, class SrcShape, class SrcAccessor,
    00064               class DestIterator, class DestAccessor>
    00065     static void
    00066     exec( SrcIterator s, SrcShape const & shape, SrcAccessor src,
    00067           DestIterator d, DestAccessor dest,
    00068           double radius, bool dilation)
    00069     {
    00070         using namespace vigra::functor;
    00071
    00072         // Allocate a new temporary array if the distances squared wouldn't fit
    00073         MultiArray<SrcShape::static_size, TmpType> tmpArray(shape);
    00074
    00075         separableMultiDistSquared(s, shape, src,
    00076                                   tmpArray.traverser_begin(), typename AccessorTraits<TmpType>::default_accessor(), dilation );
    00077
    00078         // threshold everything less than radius away from the edge
    00079         double radius2 = radius * radius;
    00080         DestType foreground = dilation
    00081                                  ? NumericTraits<DestType>::zero()
    00082                                  : NumericTraits<DestType>::one(),
    00083                  background = dilation
    00084                                  ? NumericTraits<DestType>::one()
    00085                                  : NumericTraits<DestType>::zero();
    00086         transformMultiArray( tmpArray.traverser_begin(), shape, StandardValueAccessor<double>(),
    00087                              d, dest,
    00088                              ifThenElse( Arg1() >= Param(radius2),
    00089                                          Param(foreground), Param(background) ) );
    00090     }
    00091 };
    00092
    00093 template <class DestType>
    00094 struct MultiBinaryMorphologyImpl<DestType, DestType>
    00095 {
    00096     template <class SrcIterator, class SrcShape, class SrcAccessor,
    00097               class DestIterator, class DestAccessor>
    00098     static void
    00099     exec( SrcIterator s, SrcShape const & shape, SrcAccessor src,
    00100           DestIterator d, DestAccessor dest,
    00101           double radius, bool dilation)
    00102     {
    00103         using namespace vigra::functor;
    00104
    00105         separableMultiDistSquared( s, shape, src, d, dest, dilation );
    00106
    00107         // threshold everything less than radius away from the edge
    00108         DestType radius2 = detail::RequiresExplicitCast<DestType>::cast(radius * radius);
    00109         DestType foreground = dilation
    00110                                  ? NumericTraits<DestType>::zero()
    00111                                  : NumericTraits<DestType>::one(),
    00112                  background = dilation
    00113                                  ? NumericTraits<DestType>::one()
    00114                                  : NumericTraits<DestType>::zero();
    00115         transformMultiArray( d, shape, dest, d, dest,
    00116                              ifThenElse( Arg1() > Param(radius2),
    00117                                          Param(foreground), Param(background) ) );
    00118     }
    00119 };
    00120
    00121 template <>
    00122 struct MultiBinaryMorphologyImpl<bool, bool>
    00123 {
    00124     template <class SrcIterator, class SrcShape, class SrcAccessor,
    00125               class DestIterator, class DestAccessor>
    00126     static void
    00127     exec( SrcIterator s, SrcShape const & shape, SrcAccessor src,
    00128           DestIterator d, DestAccessor dest, double radius, bool dilation)
    00129     {
    00130         vigra_fail("multiBinaryMorphology(): Internal error (this function should never be called).");
    00131     }
    00132 };
    00133
    00134 } // namespace detail
    00135
    00136 /** \addtogroup MultiArrayMorphology Morphological operators for multi-dimensional arrays.
    00137
    00138     These functions perform morphological operations on an arbitrary
    00139     dimensional array that is specified by iterators (compatible to \ref MultiIteratorPage)
    00140     and shape objects. It can therefore be applied to a wide range of data structures
    00141     (\ref vigra::MultiArrayView, \ref vigra::MultiArray etc.).
    00142 */
    00143 //@{
    00144
    00145 /********************************************************/
    00146 /*                                                      */
    00147 /*             multiBinaryErosion                       */
    00148 /*                                                      */
    00149 /********************************************************/
    00150 /** \brief Binary erosion on multi-dimensional arrays.
    00151
    00152     This function applies a flat circular erosion operator with a given radius. The
    00153     operation is isotropic. The input is intepreted as a binary multi-dimensional
    00154     array where non-zero pixels represent foreground and zero pixels represent
    00155     background. In the output, foregound is always represented by ones
    00156     (i.e. NumericTrais<typename DestAccessor::value_type>::one()).
    00157
    00158     This function may work in-place, which means that <tt>siter == diter</tt> is allowed.
    00159     A temporary internal array is only allocated if working on the destination
    00160     array directly would cause overflow errors (that is if
    00161     <tt> NumericTraits<typename DestAccessor::value_type>::max() < squaredNorm(shape)</tt>,
    00162     i.e. the squared length of the image diagonal doesn't fit into the destination type).
    00163
    00164     <b> Declarations:</b>
    00165
    00166     pass arguments explicitly:
    00167     \code
    00168     namespace vigra {
    00169         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00170                   class DestIterator, class DestAccessor>
    00171         void
    00172         multiBinaryErosion(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
    00173                                     DestIterator diter, DestAccessor dest, int radius);
    00174
    00175     }
    00176     \endcode
    00177
    00178     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00179     \code
    00180     namespace vigra {
    00181         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00182                   class DestIterator, class DestAccessor>
    00183         void
    00184         multiBinaryErosion(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00185                                     pair<DestIterator, DestAccessor> const & dest,
    00186                                     int radius);
    00187
    00188     }
    00189     \endcode
    00190
    00191     <b> Usage:</b>
    00192
    00193     <b>\#include</b> <<a href="multi__morphology_8hxx-source.html">vigra/multi_morphology.hxx</a>>
    00194
    00195     \code
    00196     MultiArray<3, unsigned char>::size_type shape(width, height, depth);
    00197     MultiArray<3, unsigned char> source(shape);
    00198     MultiArray<3, unsigned char> dest(shape);
    00199     ...
    00200
    00201     // perform isotropic binary erosion
    00202     multiBinaryErosion(srcMultiArrayRange(source), destMultiArray(dest), 3);
    00203     \endcode
    00204
    00205     \see vigra::discErosion()
    00206 */
    00207 doxygen_overloaded_function(template <...> void multiBinaryErosion)
    00208
    00209 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00210           class DestIterator, class DestAccessor>
    00211 void
    00212 multiBinaryErosion( SrcIterator s, SrcShape const & shape, SrcAccessor src,
    00213                              DestIterator d, DestAccessor dest, double radius)
    00214 {
    00215     typedef typename DestAccessor::value_type DestType;
    00216     typedef Int32 TmpType;
    00217
    00218     double dmax = squaredNorm(shape);
    00219
    00220     // Get the distance squared transform of the image
    00221     if(dmax > NumericTraits<DestType>::toRealPromote(NumericTraits<DestType>::max()))
    00222     {
    00223         detail::MultiBinaryMorphologyImpl<DestType, TmpType>::exec(s, shape, src, d, dest, radius, false);
    00224     }
    00225     else    // work directly on the destination array
    00226     {
    00227         detail::MultiBinaryMorphologyImpl<DestType, DestType>::exec(s, shape, src, d, dest, radius, false);
    00228     }
    00229 }
    00230
    00231 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00232           class DestIterator, class DestAccessor>
    00233 inline
    00234 void multiBinaryErosion(
    00235     triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00236     pair<DestIterator, DestAccessor> const & dest, double radius)
    00237 {
    00238     multiBinaryErosion( source.first, source.second, source.third,
    00239                                  dest.first, dest.second, radius );
    00240 }
    00241
    00242
    00243 /********************************************************/
    00244 /*                                                      */
    00245 /*             multiBinaryDilation                      */
    00246 /*                                                      */
    00247 /********************************************************/
    00248
    00249 /** \brief Binary dilation on multi-dimensional arrays.
    00250
    00251     This function applies a flat circular dilation operator with a given radius. The
    00252     operation is isotropic. The input is intepreted as a binary multi-dimensional
    00253     array where non-zero pixels represent foreground and zero pixels represent
    00254     background. In the output, foregound is always represented by ones
    00255     (i.e. NumericTrais<typename DestAccessor::value_type>::one()).
    00256
    00257     This function may work in-place, which means that <tt>siter == diter</tt> is allowed.
    00258     A temporary internal array is only allocated if working on the destination
    00259     array directly would cause overflow errors (that is if
    00260     <tt> NumericTraits<typename DestAccessor::value_type>::max() < squaredNorm(shape)</tt>,
    00261     i.e. the squared length of the image diagonal doesn't fit into the destination type).
    00262
    00263     <b> Declarations:</b>
    00264
    00265     pass arguments explicitly:
    00266     \code
    00267     namespace vigra {
    00268         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00269                   class DestIterator, class DestAccessor>
    00270         void
    00271         multiBinaryDilation(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
    00272                                     DestIterator diter, DestAccessor dest, int radius);
    00273
    00274     }
    00275     \endcode
    00276
    00277     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00278     \code
    00279     namespace vigra {
    00280         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00281                   class DestIterator, class DestAccessor>
    00282         void
    00283         multiBinaryDilation(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00284                                     pair<DestIterator, DestAccessor> const & dest,
    00285                                     int radius);
    00286
    00287     }
    00288     \endcode
    00289
    00290     <b> Usage:</b>
    00291
    00292     <b>\#include</b> <<a href="multi__morphology_8hxx-source.html">vigra/multi_morphology.hxx</a>>
    00293
    00294     \code
    00295     MultiArray<3, unsigned char>::size_type shape(width, height, depth);
    00296     MultiArray<3, unsigned char> source(shape);
    00297     MultiArray<3, unsigned char> dest(shape);
    00298     ...
    00299
    00300     // perform isotropic binary erosion
    00301     multiBinaryDilation(srcMultiArrayRange(source), destMultiArray(dest), 3);
    00302     \endcode
    00303
    00304     \see vigra::discDilation()
    00305 */
    00306 doxygen_overloaded_function(template <...> void multiBinaryDilation)
    00307
    00308 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00309           class DestIterator, class DestAccessor>
    00310 void
    00311 multiBinaryDilation( SrcIterator s, SrcShape const & shape, SrcAccessor src,
    00312                              DestIterator d, DestAccessor dest, double radius)
    00313 {
    00314     typedef typename DestAccessor::value_type DestType;
    00315     typedef Int32 TmpType;
    00316
    00317     double dmax = squaredNorm(shape);
    00318
    00319     // Get the distance squared transform of the image
    00320     if(dmax > NumericTraits<DestType>::toRealPromote(NumericTraits<DestType>::max()))
    00321     {
    00322         detail::MultiBinaryMorphologyImpl<DestType, TmpType>::exec(s, shape, src, d, dest, radius, true);
    00323     }
    00324     else    // work directly on the destination array
    00325     {
    00326         detail::MultiBinaryMorphologyImpl<DestType, DestType>::exec(s, shape, src, d, dest, radius, true);
    00327     }
    00328 }
    00329
    00330 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00331           class DestIterator, class DestAccessor>
    00332 inline
    00333 void multiBinaryDilation(
    00334     triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00335     pair<DestIterator, DestAccessor> const & dest, double radius)
    00336 {
    00337     multiBinaryDilation( source.first, source.second, source.third,
    00338                                  dest.first, dest.second, radius );
    00339 }
    00340
    00341 /********************************************************/
    00342 /*                                                      */
    00343 /*             multiGrayscaleErosion                    */
    00344 /*                                                      */
    00345 /********************************************************/
    00346 /** \brief Parabolic grayscale erosion on multi-dimensional arrays.
    00347
    00348     This function applies a parabolic erosion operator with a given spread (sigma) on
    00349     a grayscale array. The operation is isotropic.
    00350     The input is a grayscale multi-dimensional array.
    00351
    00352     This function may work in-place, which means that <tt>siter == diter</tt> is allowed.
    00353     A full-sized internal array is only allocated if working on the destination
    00354     array directly would cause overflow errors (i.e. if
    00355     <tt> typeid(typename DestAccessor::value_type) < N * M*M</tt>, where M is the
    00356     size of the largest dimension of the array.
    00357
    00358     <b> Declarations:</b>
    00359
    00360     pass arguments explicitly:
    00361     \code
    00362     namespace vigra {
    00363         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00364                   class DestIterator, class DestAccessor>
    00365         void
    00366         multiGrayscaleErosion(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
    00367                                     DestIterator diter, DestAccessor dest, double sigma);
    00368
    00369     }
    00370     \endcode
    00371
    00372     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00373     \code
    00374     namespace vigra {
    00375         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00376                   class DestIterator, class DestAccessor>
    00377         void
    00378         multiGrayscaleErosion(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00379                                     pair<DestIterator, DestAccessor> const & dest,
    00380                                     double sigma);
    00381
    00382     }
    00383     \endcode
    00384
    00385     <b> Usage:</b>
    00386
    00387     <b>\#include</b> <<a href="multi__morphology_8hxx-source.html">vigra/multi_morphology.hxx</a>>
    00388
    00389     \code
    00390     MultiArray<3, unsigned char>::size_type shape(width, height, depth);
    00391     MultiArray<3, unsigned char> source(shape);
    00392     MultiArray<3, unsigned char> dest(shape);
    00393     ...
    00394
    00395     // perform isotropic grayscale erosion
    00396     multiGrayscaleErosion(srcMultiArrayRange(source), destMultiArray(dest), 3.0);
    00397     \endcode
    00398
    00399     \see vigra::discErosion()
    00400 */
    00401 doxygen_overloaded_function(template <...> void multiGrayscaleErosion)
    00402
    00403 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00404           class DestIterator, class DestAccessor>
    00405 void
    00406 multiGrayscaleErosion( SrcIterator s, SrcShape const & shape, SrcAccessor src,
    00407                        DestIterator d, DestAccessor dest, double sigma)
    00408 {
    00409     typedef typename NumericTraits<typename DestAccessor::value_type>::ValueType DestType;
    00410     typedef typename NumericTraits<typename DestAccessor::value_type>::Promote TmpType;
    00411     DestType MaxValue = NumericTraits<DestType>::max();
    00412     enum { N = 1 + SrcIterator::level };
    00413
    00414     // temporay array to hold the current line to enable in-place operation
    00415     ArrayVector<TmpType> tmp( shape[0] );
    00416
    00417     typedef MultiArrayNavigator<SrcIterator, N> SNavigator;
    00418     typedef MultiArrayNavigator<DestIterator, N> DNavigator;
    00419
    00420     int MaxDim = 0;
    00421     for( int i=0; i<N; i++)
    00422         if(MaxDim < shape[i]) MaxDim = shape[i];
    00423
    00424     using namespace vigra::functor;
    00425
    00426     ArrayVector<double> sigmas(shape.size(), sigma);
    00427
    00428     // Allocate a new temporary array if the distances squared wouldn't fit
    00429     if(N*MaxDim*MaxDim > MaxValue)
    00430     {
    00431         MultiArray<SrcShape::static_size, TmpType> tmpArray(shape);
    00432
    00433         detail::internalSeparableMultiArrayDistTmp( s, shape, src, tmpArray.traverser_begin(),
    00434             typename AccessorTraits<TmpType>::default_accessor(), sigmas );
    00435
    00436         transformMultiArray( tmpArray.traverser_begin(), shape,
    00437                 typename AccessorTraits<TmpType>::default_accessor(), d, dest,
    00438                 ifThenElse( Arg1() > Param(MaxValue), Param(MaxValue), Arg1() ) );
    00439         //copyMultiArray( tmpArray.traverser_begin(), shape,
    00440         //        typename AccessorTraits<TmpType>::default_accessor(), d, dest );
    00441     }
    00442     else
    00443     {
    00444         detail::internalSeparableMultiArrayDistTmp( s, shape, src, d, dest, sigmas );
    00445     }
    00446
    00447 }
    00448
    00449 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00450           class DestIterator, class DestAccessor>
    00451 inline
    00452 void multiGrayscaleErosion(
    00453     triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00454     pair<DestIterator, DestAccessor> const & dest, double sigma)
    00455 {
    00456     multiGrayscaleErosion( source.first, source.second, source.third,
    00457             dest.first, dest.second, sigma);
    00458 }
    00459
    00460 /********************************************************/
    00461 /*                                                      */
    00462 /*             multiGrayscaleDilation                   */
    00463 /*                                                      */
    00464 /********************************************************/
    00465 /** \brief Parabolic grayscale dilation on multi-dimensional arrays.
    00466
    00467     This function applies a parabolic dilation operator with a given spread (sigma) on
    00468     a grayscale array. The operation is isotropic.
    00469     The input is a grayscale multi-dimensional array.
    00470
    00471     This function may work in-place, which means that <tt>siter == diter</tt> is allowed.
    00472     A full-sized internal array is only allocated if working on the destination
    00473     array directly would cause overflow errors (i.e. if
    00474     <tt> typeid(typename DestAccessor::value_type) < N * M*M</tt>, where M is the
    00475     size of the largest dimension of the array.
    00476
    00477     <b> Declarations:</b>
    00478
    00479     pass arguments explicitly:
    00480     \code
    00481     namespace vigra {
    00482         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00483                   class DestIterator, class DestAccessor>
    00484         void
    00485         multiGrayscaleDilation(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
    00486                                     DestIterator diter, DestAccessor dest, double sigma);
    00487
    00488     }
    00489     \endcode
    00490
    00491     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00492     \code
    00493     namespace vigra {
    00494         template <class SrcIterator, class SrcShape, class SrcAccessor,
    00495                   class DestIterator, class DestAccessor>
    00496         void
    00497         multiGrayscaleDilation(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00498                                     pair<DestIterator, DestAccessor> const & dest,
    00499                                     double sigma);
    00500
    00501     }
    00502     \endcode
    00503
    00504     <b> Usage:</b>
    00505
    00506     <b>\#include</b> <<a href="multi__morphology_8hxx-source.html">vigra/multi_morphology.hxx</a>>
    00507
    00508     \code
    00509     MultiArray<3, unsigned char>::size_type shape(width, height, depth);
    00510     MultiArray<3, unsigned char> source(shape);
    00511     MultiArray<3, unsigned char> dest(shape);
    00512     ...
    00513
    00514     // perform isotropic grayscale erosion
    00515     multiGrayscaleDilation(srcMultiArrayRange(source), destMultiArray(dest), 3.0);
    00516     \endcode
    00517
    00518     \see vigra::discErosion()
    00519 */
    00520 doxygen_overloaded_function(template <...> void multiGrayscaleDilation)
    00521
    00522 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00523           class DestIterator, class DestAccessor>
    00524 void multiGrayscaleDilation( SrcIterator s, SrcShape const & shape, SrcAccessor src,
    00525                              DestIterator d, DestAccessor dest, double sigma)
    00526 {
    00527     typedef typename NumericTraits<typename DestAccessor::value_type>::ValueType DestType;
    00528     typedef typename NumericTraits<typename DestAccessor::value_type>::Promote TmpType;
    00529     DestType MinValue = NumericTraits<DestType>::min();
    00530     DestType MaxValue = NumericTraits<DestType>::max();
    00531     enum { N = 1 + SrcIterator::level };
    00532
    00533     // temporay array to hold the current line to enable in-place operation
    00534     ArrayVector<TmpType> tmp( shape[0] );
    00535
    00536     typedef MultiArrayNavigator<SrcIterator, N> SNavigator;
    00537     typedef MultiArrayNavigator<DestIterator, N> DNavigator;
    00538
    00539     int MaxDim = 0;
    00540     for( int i=0; i<N; i++)
    00541         if(MaxDim < shape[i]) MaxDim = shape[i];
    00542
    00543     using namespace vigra::functor;
    00544
    00545     ArrayVector<double> sigmas(shape.size(), sigma);
    00546
    00547     // Allocate a new temporary array if the distances squared wouldn't fit
    00548     if(-N*MaxDim*MaxDim < MinValue || N*MaxDim*MaxDim > MaxValue)
    00549     {
    00550         MultiArray<SrcShape::static_size, TmpType> tmpArray(shape);
    00551
    00552         detail::internalSeparableMultiArrayDistTmp( s, shape, src, tmpArray.traverser_begin(),
    00553             typename AccessorTraits<TmpType>::default_accessor(), sigmas, true );
    00554
    00555         transformMultiArray( tmpArray.traverser_begin(), shape,
    00556                 typename AccessorTraits<TmpType>::default_accessor(), d, dest,
    00557                 ifThenElse( Arg1() > Param(MaxValue), Param(MaxValue),
    00558                     ifThenElse( Arg1() < Param(MinValue), Param(MinValue), Arg1() ) ) );
    00559     }
    00560     else
    00561     {
    00562         detail::internalSeparableMultiArrayDistTmp( s, shape, src, d, dest, sigmas, true );
    00563     }
    00564
    00565 }
    00566
    00567
    00568 template <class SrcIterator, class SrcShape, class SrcAccessor,
    00569           class DestIterator, class DestAccessor>
    00570 inline
    00571 void multiGrayscaleDilation(
    00572     triple<SrcIterator, SrcShape, SrcAccessor> const & source,
    00573     pair<DestIterator, DestAccessor> const & dest, double sigma)
    00574 {
    00575     multiGrayscaleDilation( source.first, source.second, source.third,
    00576             dest.first, dest.second, sigma);
    00577 }
    00578
    00579
    00580 //@}
    00581
    00582 } //-- namespace vigra
    00583
    00584
    00585 #endif        //-- VIGRA_MULTI_MORPHOLOGY_HXX

© 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.7.1 (3 Dec 2010)