vigra - vigra/multi_morphology.hxx Source File

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

multi_morphology.hxx |

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 */
221 doxygen_overloaded_function(template <...> void multiBinaryErosion)
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 */
345 doxygen_overloaded_function(template <...> void multiBinaryDilation)
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 */
466 doxygen_overloaded_function(template <...> void multiGrayscaleErosion)
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 */
608 doxygen_overloaded_function(template <...> void multiGrayscaleDilation)
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
vigra::squaredNorm
FFTWComplex< R >::SquaredNormType squaredNorm(const FFTWComplex< R > &a)
squared norm (= squared magnitude)
Definition: fftw3.hxx:1044
vigra::multiGrayscaleDilation
void multiGrayscaleDilation(...)
Parabolic grayscale dilation on multi-dimensional arrays.
vigra::Int32
detail::SelectIntegerType< 32, detail::SignedIntTypes >::type Int32
32-bit signed int
Definition: sized_int.hxx:175
vigra::multiBinaryErosion
void multiBinaryErosion(...)
Binary erosion on multi-dimensional arrays.
vigra::boost_graph::source
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
vigra::doxygen_overloaded_function
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
vigra::separableMultiDistSquared
void separableMultiDistSquared(...)
Euclidean distance squared on multi-dimensional arrays.
vigra::transformMultiArray
void transformMultiArray(...)
Transform a multi-dimensional array with a unary function or functor.
vigra::multiBinaryDilation
void multiBinaryDilation(...)
Binary dilation on multi-dimensional arrays.
vigra::multiGrayscaleErosion
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.0 (Fri May 19 2017)