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"
60template <
class DestType,
class TmpType>
61struct 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) ) );
93template <
class DestType>
94struct 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) ) );
122struct MultiBinaryMorphologyImpl<bool, bool>
124 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
125 class DestIterator,
class DestAccessor>
127 exec( SrcIterator , SrcShape
const & , SrcAccessor ,
128 DestIterator , DestAccessor ,
double ,
bool )
130 vigra_fail(
"multiBinaryMorphology(): Internal error (this function should never be called).");
223template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
224 class DestIterator,
class DestAccessor>
227 DestIterator d, DestAccessor dest,
double radius)
229 typedef typename DestAccessor::value_type DestType;
230 typedef Int32 TmpType;
235 if(dmax > NumericTraits<DestType>::toRealPromote(NumericTraits<DestType>::max()))
237 detail::MultiBinaryMorphologyImpl<DestType, TmpType>::exec(s, shape, src, d, dest, radius,
false);
241 detail::MultiBinaryMorphologyImpl<DestType, DestType>::exec(s, shape, src, d, dest, radius,
false);
245template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
246 class DestIterator,
class DestAccessor>
249 pair<DestIterator, DestAccessor>
const & dest,
double radius)
252 dest.first, dest.second, radius );
255template <
unsigned int N,
class T1,
class S1,
262 vigra_precondition(source.shape() == dest.
shape(),
263 "multiBinaryErosion(): shape mismatch between input and output.");
265 destMultiArray(dest), radius );
347template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
348 class DestIterator,
class DestAccessor>
351 DestIterator d, DestAccessor dest,
double radius)
353 typedef typename DestAccessor::value_type DestType;
354 typedef Int32 TmpType;
359 if(dmax > NumericTraits<DestType>::toRealPromote(NumericTraits<DestType>::max()))
361 detail::MultiBinaryMorphologyImpl<DestType, TmpType>::exec(s, shape, src, d, dest, radius,
true);
365 detail::MultiBinaryMorphologyImpl<DestType, DestType>::exec(s, shape, src, d, dest, radius,
true);
369template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
370 class DestIterator,
class DestAccessor>
373 pair<DestIterator, DestAccessor>
const & dest,
double radius)
376 dest.first, dest.second, radius );
379template <
unsigned int N,
class T1,
class S1,
386 vigra_precondition(source.shape() == dest.
shape(),
387 "multiBinaryDilation(): shape mismatch between input and output.");
389 destMultiArray(dest), radius );
468template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
469 class DestIterator,
class DestAccessor>
472 DestIterator d, DestAccessor dest,
double sigma)
474 typedef typename NumericTraits<typename DestAccessor::value_type>::ValueType DestType;
475 typedef typename NumericTraits<typename DestAccessor::value_type>::Promote TmpType;
476 DestType MaxValue = NumericTraits<DestType>::max();
477 enum { N = 1 + SrcIterator::level };
483 for(
int i=0; i<N; i++)
484 if(MaxDim < shape[i]) MaxDim = shape[i];
486 using namespace vigra::functor;
491 if(N*MaxDim*MaxDim > MaxValue)
495 detail::internalSeparableMultiArrayDistTmp( s, shape, src, tmpArray.traverser_begin(),
496 typename AccessorTraits<TmpType>::default_accessor(), sigmas );
499 typename AccessorTraits<TmpType>::default_accessor(), d, dest,
500 ifThenElse( Arg1() > Param(MaxValue), Param(MaxValue), Arg1() ) );
506 detail::internalSeparableMultiArrayDistTmp( s, shape, src, d, dest, sigmas );
511template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
512 class DestIterator,
class DestAccessor>
515 pair<DestIterator, DestAccessor>
const & dest,
double sigma)
518 dest.first, dest.second, sigma);
521template <
unsigned int N,
class T1,
class S1,
528 vigra_precondition(source.shape() == dest.
shape(),
529 "multiGrayscaleErosion(): shape mismatch between input and output.");
531 destMultiArray(dest), sigma);
610template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
611 class DestIterator,
class DestAccessor>
613 DestIterator d, DestAccessor dest,
double sigma)
615 typedef typename NumericTraits<typename DestAccessor::value_type>::ValueType DestType;
616 typedef typename NumericTraits<typename DestAccessor::value_type>::Promote TmpType;
617 DestType MinValue = NumericTraits<DestType>::min();
618 DestType MaxValue = NumericTraits<DestType>::max();
619 enum { N = 1 + SrcIterator::level };
625 for(
int i=0; i<N; i++)
626 if(MaxDim < shape[i]) MaxDim = shape[i];
628 using namespace vigra::functor;
633 if(-N*MaxDim*MaxDim < MinValue || N*MaxDim*MaxDim > MaxValue)
637 detail::internalSeparableMultiArrayDistTmp( s, shape, src, tmpArray.traverser_begin(),
638 typename AccessorTraits<TmpType>::default_accessor(), sigmas,
true );
641 typename AccessorTraits<TmpType>::default_accessor(), d, dest,
642 ifThenElse( Arg1() > Param(MaxValue), Param(MaxValue),
643 ifThenElse( Arg1() < Param(MinValue), Param(MinValue), Arg1() ) ) );
647 detail::internalSeparableMultiArrayDistTmp( s, shape, src, d, dest, sigmas,
true );
652template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
653 class DestIterator,
class DestAccessor>
656 pair<DestIterator, DestAccessor>
const & dest,
double sigma)
659 dest.first, dest.second, sigma);
662template <
unsigned int N,
class T1,
class S1,
669 vigra_precondition(source.shape() == dest.
shape(),
670 "multiGrayscaleDilation(): shape mismatch between input and output.");
672 destMultiArray(dest), sigma);
Definition array_vector.hxx:514
Base class for, and view to, MultiArray.
Definition multi_array.hxx:705
const difference_type & shape() const
Definition multi_array.hxx:1650
Main MultiArray class containing the memory management.
Definition multi_array.hxx:2479
void separableMultiDistSquared(...)
Euclidean distance squared on multi-dimensional arrays.
void multiGrayscaleErosion(...)
Parabolic grayscale erosion on multi-dimensional arrays.
void multiBinaryErosion(...)
Binary erosion on multi-dimensional arrays.
void transformMultiArray(...)
Transform a multi-dimensional array with a unary function or functor.
void multiGrayscaleDilation(...)
Parabolic grayscale dilation on multi-dimensional arrays.
FFTWComplex< R >::SquaredNormType squaredNorm(const FFTWComplex< R > &a)
squared norm (= squared magnitude)
Definition fftw3.hxx:1044
detail::SelectIntegerType< 32, detail::SignedIntTypes >::type Int32
32-bit signed int
Definition sized_int.hxx:175
void multiBinaryDilation(...)
Binary dilation on multi-dimensional arrays.