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

multi_morphology.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 2003-2007 by Kasim Terzic, Christian-Dennis Rahn */
4 /* and Ullrich Koethe */
5 /* */
6 /* This file is part of the VIGRA computer vision library. */
7 /* The VIGRA Website is */
8 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
9 /* Please direct questions, bug reports, and contributions to */
10 /* ullrich.koethe@iwr.uni-heidelberg.de or */
11 /* vigra@informatik.uni-hamburg.de */
12 /* */
13 /* Permission is hereby granted, free of charge, to any person */
14 /* obtaining a copy of this software and associated documentation */
15 /* files (the "Software"), to deal in the Software without */
16 /* restriction, including without limitation the rights to use, */
17 /* copy, modify, merge, publish, distribute, sublicense, and/or */
18 /* sell copies of the Software, and to permit persons to whom the */
19 /* Software is furnished to do so, subject to the following */
20 /* conditions: */
21 /* */
22 /* The above copyright notice and this permission notice shall be */
23 /* included in all copies or substantial portions of the */
24 /* Software. */
25 /* */
26 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
27 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
28 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
29 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
30 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
31 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
32 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
33 /* OTHER DEALINGS IN THE SOFTWARE. */
34 /* */
35 /************************************************************************/
36 
37 #ifndef VIGRA_MULTI_MORPHOLOGY_HXX
38 #define VIGRA_MULTI_MORPHOLOGY_HXX
39 
40 #include <vector>
41 #include <cmath>
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"
51 
52 namespace vigra
53 {
54 
55 namespace detail {
56 
57 // this class simplifies the design, but more importantly, it makes sure
58 // that the in-place code doesn't get compiled for boolean arrays
59 // (were it would never executed anyway -- see the specializations below)
60 template <class DestType, class TmpType>
61 struct MultiBinaryMorphologyImpl
62 {
63  template <class SrcIterator, class SrcShape, class SrcAccessor,
64  class DestIterator, class DestAccessor>
65  static void
66  exec( SrcIterator s, SrcShape const & shape, SrcAccessor src,
67  DestIterator d, DestAccessor dest,
68  double radius, bool dilation)
69  {
70  using namespace vigra::functor;
71 
72  // Allocate a new temporary array if the distances squared wouldn't fit
73  MultiArray<SrcShape::static_size, TmpType> tmpArray(shape);
74 
75  separableMultiDistSquared(s, shape, src,
76  tmpArray.traverser_begin(), typename AccessorTraits<TmpType>::default_accessor(), dilation );
77 
78  // threshold everything less than radius away from the edge
79  double radius2 = radius * radius;
80  DestType foreground = dilation
81  ? NumericTraits<DestType>::zero()
82  : NumericTraits<DestType>::one(),
83  background = dilation
84  ? NumericTraits<DestType>::one()
85  : NumericTraits<DestType>::zero();
86  transformMultiArray( tmpArray.traverser_begin(), shape, StandardValueAccessor<double>(),
87  d, dest,
88  ifThenElse( Arg1() > Param(radius2),
89  Param(foreground), Param(background) ) );
90  }
91 };
92 
93 template <class DestType>
94 struct MultiBinaryMorphologyImpl<DestType, DestType>
95 {
96  template <class SrcIterator, class SrcShape, class SrcAccessor,
97  class DestIterator, class DestAccessor>
98  static void
99  exec( SrcIterator s, SrcShape const & shape, SrcAccessor src,
100  DestIterator d, DestAccessor dest,
101  double radius, bool dilation)
102  {
103  using namespace vigra::functor;
104 
105  separableMultiDistSquared( s, shape, src, d, dest, dilation );
106 
107  // threshold everything less than radius away from the edge
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();
115  transformMultiArray( d, shape, dest, d, dest,
116  ifThenElse( Arg1() > Param(radius2),
117  Param(foreground), Param(background) ) );
118  }
119 };
120 
121 template <>
122 struct MultiBinaryMorphologyImpl<bool, bool>
123 {
124  template <class SrcIterator, class SrcShape, class SrcAccessor,
125  class DestIterator, class DestAccessor>
126  static void
127  exec( SrcIterator /*s*/, SrcShape const & /*shape*/, SrcAccessor /*src*/,
128  DestIterator /*d*/, DestAccessor /*dest*/, double /*radius*/, bool /*dilation*/)
129  {
130  vigra_fail("multiBinaryMorphology(): Internal error (this function should never be called).");
131  }
132 };
133 
134 } // namespace detail
135 
136 /** \addtogroup MultiArrayMorphology Morphological operators for multi-dimensional arrays.
137 
138  These functions perform morphological operations on an arbitrary
139  dimensional array that is specified by iterators (compatible to \ref MultiIteratorPage)
140  and shape objects. It can therefore be applied to a wide range of data structures
141  (\ref vigra::MultiArrayView, \ref vigra::MultiArray etc.).
142 */
143 //@{
144 
145 /********************************************************/
146 /* */
147 /* multiBinaryErosion */
148 /* */
149 /********************************************************/
150 /** \brief Binary erosion on multi-dimensional arrays.
151 
152  This function applies a flat circular erosion operator with a given radius. The
153  operation is isotropic. The input is interpreted as a binary multi-dimensional
154  array where non-zero pixels represent foreground and zero pixels represent
155  background. In the output, foreground is always represented by ones
156  (i.e. NumericTrais<typename DestAccessor::value_type>::one()).
157 
158  This function may work in-place, which means that <tt>siter == diter</tt> is allowed.
159  A temporary internal array is only allocated if working on the destination
160  array directly would cause overflow errors (that is if
161  <tt> NumericTraits<typename DestAccessor::value_type>::max() < squaredNorm(shape)</tt>,
162  i.e. the squared length of the image diagonal doesn't fit into the destination type).
163 
164  <b> Declarations:</b>
165 
166  pass arbitrary-dimensional array views:
167  \code
168  namespace vigra {
169  template <unsigned int N, class T1, class S1,
170  class T2, class S2>
171  void
172  multiBinaryErosion(MultiArrayView<N, T1, S1> const & source,
173  MultiArrayView<N, T2, S2> dest,
174  double radius);
175  }
176  \endcode
177 
178  \deprecatedAPI{multiBinaryErosion}
179  pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
180  \code
181  namespace vigra {
182  template <class SrcIterator, class SrcShape, class SrcAccessor,
183  class DestIterator, class DestAccessor>
184  void
185  multiBinaryErosion(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
186  DestIterator diter, DestAccessor dest, int radius);
187 
188  }
189  \endcode
190  use argument objects in conjunction with \ref ArgumentObjectFactories :
191  \code
192  namespace vigra {
193  template <class SrcIterator, class SrcShape, class SrcAccessor,
194  class DestIterator, class DestAccessor>
195  void
196  multiBinaryErosion(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
197  pair<DestIterator, DestAccessor> const & dest,
198  int radius);
199 
200  }
201  \endcode
202  \deprecatedEnd
203 
204  <b> Usage:</b>
205 
206  <b>\#include</b> <vigra/multi_morphology.hxx><br/>
207  Namespace: vigra
208 
209  \code
210  Shape3 shape(width, height, depth);
211  MultiArray<3, unsigned char> source(shape);
212  MultiArray<3, unsigned char> dest(shape);
213  ...
214 
215  // perform isotropic binary erosion
216  multiBinaryErosion(source, dest, 3);
217  \endcode
218 
219  \see vigra::discErosion(), vigra::multiGrayscaleErosion()
220 */
222 
223 template <class SrcIterator, class SrcShape, class SrcAccessor,
224  class DestIterator, class DestAccessor>
225 void
226 multiBinaryErosion( SrcIterator s, SrcShape const & shape, SrcAccessor src,
227  DestIterator d, DestAccessor dest, double radius)
228 {
229  typedef typename DestAccessor::value_type DestType;
230  typedef Int32 TmpType;
231 
232  double dmax = squaredNorm(shape);
233 
234  // Get the distance squared transform of the image
235  if(dmax > NumericTraits<DestType>::toRealPromote(NumericTraits<DestType>::max()))
236  {
237  detail::MultiBinaryMorphologyImpl<DestType, TmpType>::exec(s, shape, src, d, dest, radius, false);
238  }
239  else // work directly on the destination array
240  {
241  detail::MultiBinaryMorphologyImpl<DestType, DestType>::exec(s, shape, src, d, dest, radius, false);
242  }
243 }
244 
245 template <class SrcIterator, class SrcShape, class SrcAccessor,
246  class DestIterator, class DestAccessor>
247 inline void
248 multiBinaryErosion(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
249  pair<DestIterator, DestAccessor> const & dest, double radius)
250 {
251  multiBinaryErosion( source.first, source.second, source.third,
252  dest.first, dest.second, radius );
253 }
254 
255 template <unsigned int N, class T1, class S1,
256  class T2, class S2>
257 inline void
258 multiBinaryErosion(MultiArrayView<N, T1, S1> const & source,
259  MultiArrayView<N, T2, S2> dest,
260  double radius)
261 {
262  vigra_precondition(source.shape() == dest.shape(),
263  "multiBinaryErosion(): shape mismatch between input and output.");
264  multiBinaryErosion( srcMultiArrayRange(source),
265  destMultiArray(dest), radius );
266 }
267 
268 /********************************************************/
269 /* */
270 /* multiBinaryDilation */
271 /* */
272 /********************************************************/
273 
274 /** \brief Binary dilation on multi-dimensional arrays.
275 
276  This function applies a flat circular dilation operator with a given radius. The
277  operation is isotropic. The input is interpreted as a binary multi-dimensional
278  array where non-zero pixels represent foreground and zero pixels represent
279  background. In the output, foreground is always represented by ones
280  (i.e. NumericTrais<typename DestAccessor::value_type>::one()).
281 
282  This function may work in-place, which means that <tt>siter == diter</tt> is allowed.
283  A temporary internal array is only allocated if working on the destination
284  array directly would cause overflow errors (that is if
285  <tt> NumericTraits<typename DestAccessor::value_type>::max() < squaredNorm(shape)</tt>,
286  i.e. the squared length of the image diagonal doesn't fit into the destination type).
287 
288  <b> Declarations:</b>
289 
290  pass arbitrary-dimensional array views:
291  \code
292  namespace vigra {
293  template <unsigned int N, class T1, class S1,
294  class T2, class S2>
295  void
296  multiBinaryDilation(MultiArrayView<N, T1, S1> const & source,
297  MultiArrayView<N, T2, S2> dest,
298  double radius);
299  }
300  \endcode
301 
302  \deprecatedAPI{multiBinaryDilation}
303  pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
304  \code
305  namespace vigra {
306  template <class SrcIterator, class SrcShape, class SrcAccessor,
307  class DestIterator, class DestAccessor>
308  void
309  multiBinaryDilation(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
310  DestIterator diter, DestAccessor dest, int radius);
311 
312  }
313  \endcode
314  use argument objects in conjunction with \ref ArgumentObjectFactories :
315  \code
316  namespace vigra {
317  template <class SrcIterator, class SrcShape, class SrcAccessor,
318  class DestIterator, class DestAccessor>
319  void
320  multiBinaryDilation(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
321  pair<DestIterator, DestAccessor> const & dest,
322  int radius);
323 
324  }
325  \endcode
326  \deprecatedEnd
327 
328  <b> Usage:</b>
329 
330  <b>\#include</b> <vigra/multi_morphology.hxx><br/>
331  Namespace: vigra
332 
333  \code
334  Shape3 shape(width, height, depth);
335  MultiArray<3, unsigned char> source(shape);
336  MultiArray<3, unsigned char> dest(shape);
337  ...
338 
339  // perform isotropic binary erosion
340  multiBinaryDilation(source, dest, 3);
341  \endcode
342 
343  \see vigra::discDilation(), vigra::multiGrayscaleDilation()
344 */
346 
347 template <class SrcIterator, class SrcShape, class SrcAccessor,
348  class DestIterator, class DestAccessor>
349 void
350 multiBinaryDilation( SrcIterator s, SrcShape const & shape, SrcAccessor src,
351  DestIterator d, DestAccessor dest, double radius)
352 {
353  typedef typename DestAccessor::value_type DestType;
354  typedef Int32 TmpType;
355 
356  double dmax = squaredNorm(shape);
357 
358  // Get the distance squared transform of the image
359  if(dmax > NumericTraits<DestType>::toRealPromote(NumericTraits<DestType>::max()))
360  {
361  detail::MultiBinaryMorphologyImpl<DestType, TmpType>::exec(s, shape, src, d, dest, radius, true);
362  }
363  else // work directly on the destination array
364  {
365  detail::MultiBinaryMorphologyImpl<DestType, DestType>::exec(s, shape, src, d, dest, radius, true);
366  }
367 }
368 
369 template <class SrcIterator, class SrcShape, class SrcAccessor,
370  class DestIterator, class DestAccessor>
371 inline void
372 multiBinaryDilation(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
373  pair<DestIterator, DestAccessor> const & dest, double radius)
374 {
375  multiBinaryDilation( source.first, source.second, source.third,
376  dest.first, dest.second, radius );
377 }
378 
379 template <unsigned int N, class T1, class S1,
380  class T2, class S2>
381 inline void
382 multiBinaryDilation(MultiArrayView<N, T1, S1> const & source,
383  MultiArrayView<N, T2, S2> dest,
384  double radius)
385 {
386  vigra_precondition(source.shape() == dest.shape(),
387  "multiBinaryDilation(): shape mismatch between input and output.");
388  multiBinaryDilation( srcMultiArrayRange(source),
389  destMultiArray(dest), radius );
390 }
391 
392 /********************************************************/
393 /* */
394 /* multiGrayscaleErosion */
395 /* */
396 /********************************************************/
397 /** \brief Parabolic grayscale erosion on multi-dimensional arrays.
398 
399  This function applies a parabolic erosion operator with a given spread (sigma) on
400  a grayscale array. The operation is isotropic.
401  The input is a grayscale multi-dimensional array.
402 
403  This function may work in-place, which means that <tt>siter == diter</tt> is allowed.
404  A full-sized internal array is only allocated if working on the destination
405  array directly would cause overflow errors (i.e. if
406  <tt> typeid(typename DestAccessor::value_type) < N * M*M</tt>, where M is the
407  size of the largest dimension of the array.
408 
409  <b> Declarations:</b>
410 
411  pass arbitrary-dimensional array views:
412  \code
413  namespace vigra {
414  template <unsigned int N, class T1, class S1,
415  class T2, class S2>
416  void
417  multiGrayscaleErosion(MultiArrayView<N, T1, S1> const & source,
418  MultiArrayView<N, T2, S2> dest,
419  double sigma);
420  }
421  \endcode
422 
423  \deprecatedAPI{multiGrayscaleErosion}
424  pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
425  \code
426  namespace vigra {
427  template <class SrcIterator, class SrcShape, class SrcAccessor,
428  class DestIterator, class DestAccessor>
429  void
430  multiGrayscaleErosion(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
431  DestIterator diter, DestAccessor dest, double sigma);
432 
433  }
434  \endcode
435  use argument objects in conjunction with \ref ArgumentObjectFactories :
436  \code
437  namespace vigra {
438  template <class SrcIterator, class SrcShape, class SrcAccessor,
439  class DestIterator, class DestAccessor>
440  void
441  multiGrayscaleErosion(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
442  pair<DestIterator, DestAccessor> const & dest,
443  double sigma);
444 
445  }
446  \endcode
447  \deprecatedEnd
448 
449  <b> Usage:</b>
450 
451  <b>\#include</b> <vigra/multi_morphology.hxx><br/>
452  Namespace: vigra
453 
454  \code
455  Shape3 shape(width, height, depth);
456  MultiArray<3, unsigned char> source(shape);
457  MultiArray<3, unsigned char> dest(shape);
458  ...
459 
460  // perform isotropic grayscale erosion
461  multiGrayscaleErosion(source, dest, 3.0);
462  \endcode
463 
464  \see vigra::discErosion(), vigra::multiBinaryErosion()
465 */
467 
468 template <class SrcIterator, class SrcShape, class SrcAccessor,
469  class DestIterator, class DestAccessor>
470 void
471 multiGrayscaleErosion( SrcIterator s, SrcShape const & shape, SrcAccessor src,
472  DestIterator d, DestAccessor dest, double sigma)
473 {
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 };
478 
479  // temporary array to hold the current line to enable in-place operation
480  ArrayVector<TmpType> tmp( shape[0] );
481 
482  int MaxDim = 0;
483  for( int i=0; i<N; i++)
484  if(MaxDim < shape[i]) MaxDim = shape[i];
485 
486  using namespace vigra::functor;
487 
488  ArrayVector<double> sigmas(shape.size(), sigma);
489 
490  // Allocate a new temporary array if the distances squared wouldn't fit
491  if(N*MaxDim*MaxDim > MaxValue)
492  {
493  MultiArray<SrcShape::static_size, TmpType> tmpArray(shape);
494 
495  detail::internalSeparableMultiArrayDistTmp( s, shape, src, tmpArray.traverser_begin(),
496  typename AccessorTraits<TmpType>::default_accessor(), sigmas );
497 
498  transformMultiArray( tmpArray.traverser_begin(), shape,
499  typename AccessorTraits<TmpType>::default_accessor(), d, dest,
500  ifThenElse( Arg1() > Param(MaxValue), Param(MaxValue), Arg1() ) );
501  //copyMultiArray( tmpArray.traverser_begin(), shape,
502  // typename AccessorTraits<TmpType>::default_accessor(), d, dest );
503  }
504  else
505  {
506  detail::internalSeparableMultiArrayDistTmp( s, shape, src, d, dest, sigmas );
507  }
508 
509 }
510 
511 template <class SrcIterator, class SrcShape, class SrcAccessor,
512  class DestIterator, class DestAccessor>
513 inline void
514 multiGrayscaleErosion(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
515  pair<DestIterator, DestAccessor> const & dest, double sigma)
516 {
517  multiGrayscaleErosion( source.first, source.second, source.third,
518  dest.first, dest.second, sigma);
519 }
520 
521 template <unsigned int N, class T1, class S1,
522  class T2, class S2>
523 inline void
524 multiGrayscaleErosion(MultiArrayView<N, T1, S1> const & source,
525  MultiArrayView<N, T2, S2> dest,
526  double sigma)
527 {
528  vigra_precondition(source.shape() == dest.shape(),
529  "multiGrayscaleErosion(): shape mismatch between input and output.");
530  multiGrayscaleErosion( srcMultiArrayRange(source),
531  destMultiArray(dest), sigma);
532 }
533 
534 /********************************************************/
535 /* */
536 /* multiGrayscaleDilation */
537 /* */
538 /********************************************************/
539 /** \brief Parabolic grayscale dilation on multi-dimensional arrays.
540 
541  This function applies a parabolic dilation operator with a given spread (sigma) on
542  a grayscale array. The operation is isotropic.
543  The input is a grayscale multi-dimensional array.
544 
545  This function may work in-place, which means that <tt>siter == diter</tt> is allowed.
546  A full-sized internal array is only allocated if working on the destination
547  array directly would cause overflow errors (i.e. if
548  <tt> typeid(typename DestAccessor::value_type) < N * M*M</tt>, where M is the
549  size of the largest dimension of the array.
550 
551  <b> Declarations:</b>
552 
553  pass arbitrary-dimensional array views:
554  \code
555  namespace vigra {
556  template <unsigned int N, class T1, class S1,
557  class T2, class S2>
558  void
559  multiGrayscaleDilation(MultiArrayView<N, T1, S1> const & source,
560  MultiArrayView<N, T2, S2> dest,
561  double sigma);
562  }
563  \endcode
564 
565  \deprecatedAPI{multiGrayscaleDilation}
566  pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
567  \code
568  namespace vigra {
569  template <class SrcIterator, class SrcShape, class SrcAccessor,
570  class DestIterator, class DestAccessor>
571  void
572  multiGrayscaleDilation(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
573  DestIterator diter, DestAccessor dest, double sigma);
574 
575  }
576  \endcode
577  use argument objects in conjunction with \ref ArgumentObjectFactories :
578  \code
579  namespace vigra {
580  template <class SrcIterator, class SrcShape, class SrcAccessor,
581  class DestIterator, class DestAccessor>
582  void
583  multiGrayscaleDilation(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
584  pair<DestIterator, DestAccessor> const & dest,
585  double sigma);
586 
587  }
588  \endcode
589  \deprecatedEnd
590 
591  <b> Usage:</b>
592 
593  <b>\#include</b> <vigra/multi_morphology.hxx><br/>
594  Namespace: vigra
595 
596  \code
597  Shape3 shape(width, height, depth);
598  MultiArray<3, unsigned char> source(shape);
599  MultiArray<3, unsigned char> dest(shape);
600  ...
601 
602  // perform isotropic grayscale erosion
603  multiGrayscaleDilation(source, dest, 3.0);
604  \endcode
605 
606  \see vigra::discDilation(), vigra::multiBinaryDilation()
607 */
609 
610 template <class SrcIterator, class SrcShape, class SrcAccessor,
611  class DestIterator, class DestAccessor>
612 void multiGrayscaleDilation( SrcIterator s, SrcShape const & shape, SrcAccessor src,
613  DestIterator d, DestAccessor dest, double sigma)
614 {
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 };
620 
621  // temporary array to hold the current line to enable in-place operation
622  ArrayVector<TmpType> tmp( shape[0] );
623 
624  int MaxDim = 0;
625  for( int i=0; i<N; i++)
626  if(MaxDim < shape[i]) MaxDim = shape[i];
627 
628  using namespace vigra::functor;
629 
630  ArrayVector<double> sigmas(shape.size(), sigma);
631 
632  // Allocate a new temporary array if the distances squared wouldn't fit
633  if(-N*MaxDim*MaxDim < MinValue || N*MaxDim*MaxDim > MaxValue)
634  {
635  MultiArray<SrcShape::static_size, TmpType> tmpArray(shape);
636 
637  detail::internalSeparableMultiArrayDistTmp( s, shape, src, tmpArray.traverser_begin(),
638  typename AccessorTraits<TmpType>::default_accessor(), sigmas, true );
639 
640  transformMultiArray( tmpArray.traverser_begin(), shape,
641  typename AccessorTraits<TmpType>::default_accessor(), d, dest,
642  ifThenElse( Arg1() > Param(MaxValue), Param(MaxValue),
643  ifThenElse( Arg1() < Param(MinValue), Param(MinValue), Arg1() ) ) );
644  }
645  else
646  {
647  detail::internalSeparableMultiArrayDistTmp( s, shape, src, d, dest, sigmas, true );
648  }
649 
650 }
651 
652 template <class SrcIterator, class SrcShape, class SrcAccessor,
653  class DestIterator, class DestAccessor>
654 inline void
655 multiGrayscaleDilation(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
656  pair<DestIterator, DestAccessor> const & dest, double sigma)
657 {
658  multiGrayscaleDilation( source.first, source.second, source.third,
659  dest.first, dest.second, sigma);
660 }
661 
662 template <unsigned int N, class T1, class S1,
663  class T2, class S2>
664 inline void
665 multiGrayscaleDilation(MultiArrayView<N, T1, S1> const & source,
666  MultiArrayView<N, T2, S2> dest,
667  double sigma)
668 {
669  vigra_precondition(source.shape() == dest.shape(),
670  "multiGrayscaleDilation(): shape mismatch between input and output.");
671  multiGrayscaleDilation( srcMultiArrayRange(source),
672  destMultiArray(dest), sigma);
673 }
674 
675 //@}
676 
677 } //-- namespace vigra
678 
679 
680 #endif //-- VIGRA_MULTI_MORPHOLOGY_HXX
FFTWComplex< R >::SquaredNormType squaredNorm(const FFTWComplex< R > &a)
squared norm (= squared magnitude)
Definition: fftw3.hxx:1044
void multiGrayscaleDilation(...)
Parabolic grayscale dilation on multi-dimensional arrays.
detail::SelectIntegerType< 32, detail::SignedIntTypes >::type Int32
32-bit signed int
Definition: sized_int.hxx:175
void multiBinaryErosion(...)
Binary erosion on multi-dimensional arrays.
vigra::GridGraph< N, DirectedTag >::vertex_descriptor source(typename vigra::GridGraph< N, DirectedTag >::edge_descriptor const &e, vigra::GridGraph< N, DirectedTag > const &g)
Get a vertex descriptor for the start vertex of edge e in graph g (API: boost).
Definition: multi_gridgraph.hxx:2943
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
void separableMultiDistSquared(...)
Euclidean distance squared on multi-dimensional arrays.
void transformMultiArray(...)
Transform a multi-dimensional array with a unary function or functor.
void multiBinaryDilation(...)
Binary dilation on multi-dimensional arrays.
void multiGrayscaleErosion(...)
Parabolic grayscale erosion on multi-dimensional arrays.

© 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.11.1 (Fri May 19 2017)