37 #ifndef VIGRA_MULTI_MORPHOLOGY_HXX
38 #define VIGRA_MULTI_MORPHOLOGY_HXX
42 #include "multi_distance.hxx"
43 #include "array_vector.hxx"
44 #include "multi_array.hxx"
45 #include "accessor.hxx"
46 #include "numerictraits.hxx"
47 #include "navigator.hxx"
48 #include "metaprogramming.hxx"
49 #include "multi_pointoperators.hxx"
50 #include "functorexpression.hxx"
60 template <
class DestType,
class TmpType>
61 struct MultiBinaryMorphologyImpl
63 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
64 class DestIterator,
class DestAccessor>
66 exec( SrcIterator s, SrcShape
const & shape, SrcAccessor src,
67 DestIterator d, DestAccessor dest,
68 double radius,
bool dilation)
70 using namespace vigra::functor;
73 MultiArray<SrcShape::static_size, TmpType> tmpArray(shape);
76 tmpArray.traverser_begin(),
typename AccessorTraits<TmpType>::default_accessor(), dilation );
79 double radius2 = radius * radius;
80 DestType foreground = dilation
81 ? NumericTraits<DestType>::zero()
82 : NumericTraits<DestType>::one(),
84 ? NumericTraits<DestType>::one()
85 : NumericTraits<DestType>::zero();
88 ifThenElse( Arg1() >= Param(radius2),
89 Param(foreground), Param(background) ) );
93 template <
class DestType>
94 struct MultiBinaryMorphologyImpl<DestType, DestType>
96 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
97 class DestIterator,
class DestAccessor>
99 exec( SrcIterator s, SrcShape
const & shape, SrcAccessor src,
100 DestIterator d, DestAccessor dest,
101 double radius,
bool dilation)
103 using namespace vigra::functor;
108 DestType radius2 = detail::RequiresExplicitCast<DestType>::cast(radius * radius);
109 DestType foreground = dilation
110 ? NumericTraits<DestType>::zero()
111 : NumericTraits<DestType>::one(),
112 background = dilation
113 ? NumericTraits<DestType>::one()
114 : NumericTraits<DestType>::zero();
116 ifThenElse( Arg1() > Param(radius2),
117 Param(foreground), Param(background) ) );
122 struct MultiBinaryMorphologyImpl<bool, bool>
124 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
125 class DestIterator,
class DestAccessor>
127 exec( SrcIterator s, SrcShape
const & shape, SrcAccessor src,
128 DestIterator d, DestAccessor dest,
double radius,
bool dilation)
130 vigra_fail(
"multiBinaryMorphology(): Internal error (this function should never be called).");
209 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
210 class DestIterator,
class DestAccessor>
213 DestIterator d, DestAccessor dest,
double radius)
215 typedef typename DestAccessor::value_type DestType;
216 typedef Int32 TmpType;
223 detail::MultiBinaryMorphologyImpl<DestType, TmpType>::exec(s, shape, src, d, dest, radius,
false);
227 detail::MultiBinaryMorphologyImpl<DestType, DestType>::exec(s, shape, src, d, dest, radius,
false);
231 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
232 class DestIterator,
class DestAccessor>
235 triple<SrcIterator, SrcShape, SrcAccessor>
const & source,
236 pair<DestIterator, DestAccessor>
const & dest,
double radius)
239 dest.first, dest.second, radius );
308 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
309 class DestIterator,
class DestAccessor>
312 DestIterator d, DestAccessor dest,
double radius)
314 typedef typename DestAccessor::value_type DestType;
315 typedef Int32 TmpType;
322 detail::MultiBinaryMorphologyImpl<DestType, TmpType>::exec(s, shape, src, d, dest, radius,
true);
326 detail::MultiBinaryMorphologyImpl<DestType, DestType>::exec(s, shape, src, d, dest, radius,
true);
330 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
331 class DestIterator,
class DestAccessor>
334 triple<SrcIterator, SrcShape, SrcAccessor>
const & source,
335 pair<DestIterator, DestAccessor>
const & dest,
double radius)
338 dest.first, dest.second, radius );
403 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
404 class DestIterator,
class DestAccessor>
407 DestIterator d, DestAccessor dest,
double sigma)
409 typedef typename NumericTraits<typename DestAccessor::value_type>::ValueType DestType;
410 typedef typename NumericTraits<typename DestAccessor::value_type>::Promote TmpType;
412 enum { N = 1 + SrcIterator::level };
415 ArrayVector<TmpType> tmp( shape[0] );
417 typedef MultiArrayNavigator<SrcIterator, N> SNavigator;
418 typedef MultiArrayNavigator<DestIterator, N> DNavigator;
421 for(
int i=0; i<N; i++)
422 if(MaxDim < shape[i]) MaxDim = shape[i];
424 using namespace vigra::functor;
426 ArrayVector<double> sigmas(shape.size(), sigma);
429 if(N*MaxDim*MaxDim > MaxValue)
431 MultiArray<SrcShape::static_size, TmpType> tmpArray(shape);
433 detail::internalSeparableMultiArrayDistTmp( s, shape, src, tmpArray.traverser_begin(),
434 typename AccessorTraits<TmpType>::default_accessor(), sigmas );
437 typename AccessorTraits<TmpType>::default_accessor(), d, dest,
438 ifThenElse( Arg1() > Param(MaxValue), Param(MaxValue), Arg1() ) );
444 detail::internalSeparableMultiArrayDistTmp( s, shape, src, d, dest, sigmas );
449 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
450 class DestIterator,
class DestAccessor>
453 triple<SrcIterator, SrcShape, SrcAccessor>
const & source,
454 pair<DestIterator, DestAccessor>
const & dest,
double sigma)
457 dest.first, dest.second, sigma);
522 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
523 class DestIterator,
class DestAccessor>
525 DestIterator d, DestAccessor dest,
double sigma)
527 typedef typename NumericTraits<typename DestAccessor::value_type>::ValueType DestType;
528 typedef typename NumericTraits<typename DestAccessor::value_type>::Promote TmpType;
531 enum { N = 1 + SrcIterator::level };
534 ArrayVector<TmpType> tmp( shape[0] );
536 typedef MultiArrayNavigator<SrcIterator, N> SNavigator;
537 typedef MultiArrayNavigator<DestIterator, N> DNavigator;
540 for(
int i=0; i<N; i++)
541 if(MaxDim < shape[i]) MaxDim = shape[i];
543 using namespace vigra::functor;
545 ArrayVector<double> sigmas(shape.size(), sigma);
548 if(-N*MaxDim*MaxDim < MinValue || N*MaxDim*MaxDim > MaxValue)
550 MultiArray<SrcShape::static_size, TmpType> tmpArray(shape);
552 detail::internalSeparableMultiArrayDistTmp( s, shape, src, tmpArray.traverser_begin(),
553 typename AccessorTraits<TmpType>::default_accessor(), sigmas, true );
556 typename AccessorTraits<TmpType>::default_accessor(), d, dest,
557 ifThenElse( Arg1() > Param(MaxValue), Param(MaxValue),
558 ifThenElse( Arg1() < Param(MinValue), Param(MinValue), Arg1() ) ) );
562 detail::internalSeparableMultiArrayDistTmp( s, shape, src, d, dest, sigmas,
true );
568 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
569 class DestIterator,
class DestAccessor>
572 triple<SrcIterator, SrcShape, SrcAccessor>
const & source,
573 pair<DestIterator, DestAccessor>
const & dest,
double sigma)
576 dest.first, dest.second, sigma);
585 #endif //-- VIGRA_MULTI_MORPHOLOGY_HXX