vigra - vigra/localminmax.hxx Source File

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

localminmax.hxx |

1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2010 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35
36 #ifndef VIGRA_LOCALMINMAX_HXX
37 #define VIGRA_LOCALMINMAX_HXX
38
39 #include <vector>
40 #include <functional>
41 #include "utilities.hxx"
42 #include "stdimage.hxx"
43 #include "initimage.hxx"
44 #include "labelimage.hxx"
45 #include "labelvolume.hxx"
46 #include "pixelneighborhood.hxx"
47 #include "voxelneighborhood.hxx"
48 #include "multi_shape.hxx"
49
50 namespace vigra
51 {
52
53 /** \addtogroup LocalMinMax Local Minima and Maxima
54
55 Detect local minima and maxima in a gray level image,
56 including extremal plateaus larger than 1 pixel
57 */
58 //@{
59
60 namespace detail {
61
62 template <class SrcIterator, class SrcAccessor,
63 class Neighborhood,
64 class Compare>
65 inline bool
66 isLocalExtremum(SrcIterator is, SrcAccessor sa, Neighborhood,
67 typename SrcAccessor::value_type threshold,
68 Compare compare, AtImageBorder atBorder)
69 {
70 typename SrcAccessor::value_type v = sa(is);
71
72 if(!compare(v, threshold))
73 return false;
74
75 int directionCount = Neighborhood::nearBorderDirectionCount(atBorder);
76 RestrictedNeighborhoodCirculator<SrcIterator, Neighborhood> sc(is, atBorder);
77 for(int i = 0; i < directionCount; ++i, ++sc)
78 {
79 if(!compare(v, sa(sc)))
80 return false;
81 }
82 return true;
83 }
84
85 template <class SrcIterator, class SrcAccessor,
86 class DestIterator, class DestAccessor,
87 class DestValue, class Neighborhood,
88 class Compare>
89 void
90 localMinMax(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
91 DestIterator dul, DestAccessor da,
92 DestValue marker, Neighborhood neighborhood,
93 typename SrcAccessor::value_type threshold,
94 Compare compare,
95 bool allowExtremaAtBorder = false)
96 {
97 int w = slr.x - sul.x;
98 int h = slr.y - sul.y;
99
100 int x, y;
101
102 if(allowExtremaAtBorder)
103 {
104 SrcIterator is = sul;
105 DestIterator id = dul;
106
107 for(x=0; x<w; ++x, ++is.x, ++id.x)
108 {
109 if(isLocalExtremum(is, sa, neighborhood, threshold, compare,
110 isAtImageBorder(x, 0, w, h)))
111 da.set(marker, id);
112 }
113
114 is = sul + Diff2D(0,1);
115 id = dul + Diff2D(0,1);
116
117 for(y=1; y<h-1; ++y, ++is.y, ++id.y)
118 {
119 if(isLocalExtremum(is, sa, neighborhood, threshold, compare,
120 isAtImageBorder(0, y, w, h)))
121 da.set(marker, id);
122 }
123
124 is = sul + Diff2D(w-1,1);
125 id = dul + Diff2D(w-1,1);
126
127 for(y=1; y<h-1; ++y, ++is.y, ++id.y)
128 {
129 if(isLocalExtremum(is, sa, neighborhood, threshold, compare,
130 isAtImageBorder(w-1, y, w, h)))
131 da.set(marker, id);
132 }
133
134 is = sul + Diff2D(0,h-1);
135 id = dul + Diff2D(0,h-1);
136
137 for(x=0; x<w; ++x, ++is.x, ++id.x)
138 {
139 if(isLocalExtremum(is, sa, neighborhood, threshold, compare,
140 isAtImageBorder(x, h-1, w, h)))
141 da.set(marker, id);
142 }
143 }
144
145 w -= 2;
146 h -= 2;
147 sul += Diff2D(1,1);
148 dul += Diff2D(1,1);
149
150 for(y=0; y<h; ++y, ++sul.y, ++dul.y)
151 {
152 SrcIterator sx = sul;
153 DestIterator dx = dul;
154
155 for(x=0; x<w; ++x, ++sx.x, ++dx.x)
156 {
157 typename SrcAccessor::value_type v = sa(sx);
158
159 if(!compare(v, threshold))
160 continue;
161
162 int i;
163 NeighborhoodCirculator<SrcIterator, Neighborhood> sc(sx);
164 for(i = 0; i < Neighborhood::DirectionCount; ++i, ++sc)
165 {
166 if(!compare(v, sa(sc)))
167 break;
168 }
169
170 if(i == Neighborhood::DirectionCount)
171 da.set(marker, dx);
172 }
173 }
174 }
175
176 template<class SrcIterator, class SrcShape, class SrcAccessor,
177 class DestIterator, class DestAccessor, class DestValue,
178 class Neighborhood, class Compare>
179 void
180 localMinMax3D(SrcIterator sul, SrcShape shp, SrcAccessor sa,
181 DestIterator dul, DestAccessor da,
182 DestValue marker,
183 Neighborhood neighborhood,
184 typename SrcAccessor::value_type threshold,
185 Compare compare,
186 bool allowExtremaAtBorder = false)
187 {
188 int w = shp[0];
189 int h = shp[1];
190 int d = shp[2];
191
192 int x, y, z;
193
194 if (allowExtremaAtBorder)
195 {
196 throw std::runtime_error("Not implemented (use localMinima() or localMaxima() instead).");
197 }
198
199 w -= 2;
200 h -= 2;
201 d -= 2;
202 sul.dim0() += 1;
203 sul.dim1() += 1;
204 sul.dim2() += 1;
205 dul += Diff3D(1, 1, 1);
206
207 SrcIterator zs = sul;
208 DestIterator zd = dul;
209
210 for (z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
211 {
212 SrcIterator ys(zs);
213 DestIterator yd(zd);
214
215 for (y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
216 {
217 SrcIterator xs(ys);
218 DestIterator xd(yd);
219
220 for (x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
221 {
222
223 typename SrcAccessor::value_type v = sa(xs);
224 if (!compare(v, threshold))
225 continue;
226
227 int i;
228 NeighborhoodCirculator<SrcIterator, Neighborhood> sc(xs);
229 for (i = 0; i < Neighborhood::DirectionCount; ++i, ++sc)
230 {
231 if(!compare(v, sa(sc)))
232 break;
233 }
234
235 if(i == Neighborhood::DirectionCount)
236 da.set(marker, xd);
237 }
238 }
239 }
240 }
241
242 template <class SrcIterator, class SrcAccessor,
243 class DestIterator, class DestAccessor, class DestValue,
244 class Neighborhood, class Compare, class Equal>
245 void
246 extendedLocalMinMax(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
247 DestIterator dul, DestAccessor da, DestValue marker,
248 Neighborhood /*neighborhood*/,
249 Compare compare, Equal equal,
250 typename SrcAccessor::value_type threshold,
251 bool allowExtremaAtBorder = false)
252 {
253 typedef typename SrcAccessor::value_type SrcType;
254
255 int w = slr.x - sul.x;
256 int h = slr.y - sul.y;
257
258 int i,x,y;
259
260 BasicImage<int> labels(w,h);
261
262 int number_of_regions =
263 labelImage(sul, slr, sa, labels.upperLeft(), labels.accessor(),
264 (Neighborhood::DirectionCount == 8), equal);
265
266 // assume that a region is a extremum until the opposite is proved
267 std::vector<unsigned char> isExtremum(number_of_regions+1, (unsigned char)1);
268
269 BasicImage<int>::traverser ly = labels.upperLeft();
270
271 for(y=0; y<h; ++y, ++sul.y, ++ly.y)
272 {
273 SrcIterator sx = sul;
274 BasicImage<int>::traverser lx(ly);
275
276 for(x=0; x<w; ++x, ++sx.x, ++lx.x)
277 {
278 int lab = *lx;
279 SrcType v = sa(sx);
280
281 if(isExtremum[lab] == 0)
282 continue;
283
284 if(!compare(v, threshold))
285 {
286 // mark all regions that don't exceed the threshold as non-extremum
287 isExtremum[lab] = 0;
288 continue;
289 }
290
291 AtImageBorder atBorder = isAtImageBorder(x, y, w, h);
292 if(atBorder == NotAtBorder)
293 {
294 NeighborhoodCirculator<SrcIterator, Neighborhood> sc(sx);
295 NeighborhoodCirculator<BasicImage<int>::traverser, Neighborhood> lc(lx);
296 for(i=0; i<Neighborhood::DirectionCount; ++i, ++sc, ++lc)
297 {
298 if(lab != *lc && compare(sa(sc),v))
299 {
300 isExtremum[lab] = 0;
301 break;
302 }
303 }
304 }
305 else
306 {
307 if(allowExtremaAtBorder)
308 {
309 RestrictedNeighborhoodCirculator<SrcIterator, Neighborhood>
310 sc(sx, atBorder), scend(sc);
311 do
312 {
313 if(lab != *(lx+sc.diff()) && compare(sa(sc),v))
314 {
315 isExtremum[lab] = 0;
316 break;
317 }
318 }
319 while(++sc != scend);
320 }
321 else
322 {
323 isExtremum[lab] = 0;
324 }
325 }
326 }
327 }
328
329 ly = labels.upperLeft();
330 for(y=0; y<h; ++y, ++dul.y, ++ly.y)
331 {
332 DestIterator xd = dul;
333 BasicImage<int>::Iterator lx(ly);
334
335 for(x=0; x<w; ++x, ++xd.x, ++lx.x)
336 {
337 if(isExtremum[*lx])
338 da.set(marker, xd);
339 }
340 }
341 }
342
343 template<class SrcIterator, class SrcShape, class SrcAccessor,
344 class DestIterator, class DestAccessor, class DestValue,
345 class Neighborhood, class Compare, class Equal>
346 void
347 extendedLocalMinMax3D(SrcIterator sul, SrcShape shp, SrcAccessor sa,
348 DestIterator dul, DestAccessor da,
349 DestValue marker,
350 Neighborhood neighbourhood,
351 Compare compare,
352 Equal equal,
353 typename SrcAccessor::value_type threshold,
354 bool allowExtremaAtBorder = false)
355 {
356 typedef typename SrcAccessor::value_type SrcType;
357
358 int w = shp[0];
359 int h = shp[1];
360 int d = shp[2];
361
362 int i, x, y, z;
363
364 MultiArray<3, int> labels(shp);
365
366 int number_of_regions =
367 labelVolume(sul, shp, sa, labels.traverser_begin(),
368 typename AccessorTraits<int>::default_accessor(),
369 neighbourhood);
370
371 MultiArray<3, int>::traverser zl(labels.traverser_begin());
372
373 SrcIterator zs = sul;
374 DestIterator zd = dul;
375
376 // assume that a region is a extremum until the opposite is proved
377 std::vector<unsigned char> isExtremum(number_of_regions + 1, (unsigned char)1);
378
379 for (z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2(), ++zl.dim2())
380 {
381 SrcIterator ys(zs);
382 DestIterator yd(zd);
383 MultiArray<3, int>::traverser yl(zl);
384
385 for (y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1(), ++yl.dim1())
386 {
387 SrcIterator xs(ys);
388 DestIterator xd(yd);
389 MultiArray<3, int>::traverser xl(yl);
390
391 for (x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0(), ++xl.dim0())
392 {
393
394 int lab = *xl;
395 SrcType v = sa(xs);
396
397 if (isExtremum[lab] == 0)
398 continue;
399
400 if (!compare(v, threshold))
401 {
402 // mark all regions that don't exceed the threshold as non-extremum
403 isExtremum[lab] = 0;
404 continue;
405 }
406
407 AtVolumeBorder atBorder = isAtVolumeBorder(x, y, z, w, h, d);
408 if (atBorder == NotAtBorder)
409 {
410 NeighborhoodCirculator<SrcIterator, Neighborhood> sc(xs);
411 NeighborhoodCirculator<MultiArray<3, int>::traverser, Neighborhood> lc(xl);
412 for (i = 0; i < Neighborhood::DirectionCount; ++i, ++sc, ++lc)
413 {
414 if (lab != *lc && compare(sa(sc), v))
415 {
416
417 isExtremum[lab] = 0;
418 break;
419 }
420 }
421 }
422 else
423 {
424 if (allowExtremaAtBorder)
425 {
426 RestrictedNeighborhoodCirculator<SrcIterator, Neighborhood>
427 sc(xs, atBorder), scend(sc);
428 do
429 {
430 if (lab != *(xl + sc.diff()) && compare(sa(sc), v))
431 {
432 isExtremum[lab] = 0;
433 break;
434 }
435 }
436 while (++sc != scend);
437 }
438 else
439 {
440 isExtremum[lab] = 0;
441 }
442 }
443 }
444 }
445 }
446
447 zl = labels.traverser_begin();
448 zs = sul;
449 zd = dul;
450
451 for (z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2(), ++zl.dim2())
452 {
453 SrcIterator ys(zs);
454 DestIterator yd(zd);
455 MultiArray<3, int>::traverser yl(zl);
456
457 for (y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1(), ++yl.dim1())
458 {
459 SrcIterator xs(ys);
460 DestIterator xd(yd);
461 MultiArray<3, int>::traverser xl(yl);
462
463 for (x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0(), ++xl.dim0())
464 {
465 if(isExtremum[*xl])
466 da.set(marker, xd);
467 }
468 }
469 }
470 }
471
472 } // namespace detail
473
474
475 /** \brief Options object for localMinima() and localMaxima().
476
477 <b> Usage:</b>
478
479 <b>\#include</b> <vigra/localminmax.hxx><br>
480 Namespace: vigra
481
482 \code
483 MultiArray<2, unsigned char> src(w,h), minima(w,h);
484 ... // fill src
485
486 // use 4-neighborhood, allow minima at the image border,
487 // and discard those where the gray value is not below 5
488 localMinima(src, minima,
489 LocalMinmaxOptions().neighborhood(4).allowAtBorder().threshold(5));
490
491 \endcode
492 */
493 class LocalMinmaxOptions
494 {
495 public:
496 double marker, thresh;
497 int neigh;
498 bool use_threshold, allow_at_border, allow_plateaus;
499
500 /**\brief Construct default options object.
501 *
502 Defaults are: marker value '1', no threshold, indirect neighborhood,
503 don't allow extrema at border and extremal plateaus.
504 */
505 LocalMinmaxOptions()
506 : marker(1.0),
507 thresh(0.0),
508 neigh(1),
509 use_threshold(false),
510 allow_at_border(false),
511 allow_plateaus(false)
512 {}
513
514 /**\brief Use the given neighborhood.
515
516 The value '0' indicates direct neighborhood (i.e. 4-neighborhood
517 in 2D, 6-neighborhood in 3D, 2*N neighborhood in N-D), the value '1'
518 indicates indirect neighborhood (i.e. 8-neighborhood in 2D,
519 26-neighborhood in 3D, 3<sup>N</sup>-1 neighborhood in N-D). The appropriate
520 number of neighbors for the desired dimension and the constants
521 <tt>DirectNeighborhood</tt> and <tt>IndirectNeighborhood</tt> can be used as well.
522
523 Default: 1 (indirect neighborhood)
524 */
525 LocalMinmaxOptions & neighborhood(unsigned int n)
526 {
527 neigh = n;
528 return *this;
529 }
530
531 LocalMinmaxOptions & neighborhood(NeighborhoodType n)
532 {
533 neigh = n;
534 return *this;
535 }
536
537 /**\brief Mark extrema in the destination image with the given value.
538
539 Default: 1
540 */
541 LocalMinmaxOptions & markWith(double m)
542 {
543 marker = m;
544 return *this;
545 }
546
547 /**\brief Threshold the extrema.
548
549 Discard minima whose gray value is not below the threshold.
550 and maxima whose gray level is not above the threshold.
551
552 Default: don't threshold (i.e. return all extrema)
553 */
554 LocalMinmaxOptions & threshold(double t)
555 {
556 use_threshold = true;
557 thresh = t;
558 return *this;
559 }
560
561 /**\brief Detect extrema at the image border.
562
563 Default: false
564 */
565 LocalMinmaxOptions & allowAtBorder(bool f = true)
566 {
567 allow_at_border = f;
568 return *this;
569 }
570
571 /**\brief Allow extremal plateaus.
572
573 That is regions of constant gray value whose neighbors are all
574 higher (minima) or lower than the value of the region.
575
576 Default: false
577 */
578 LocalMinmaxOptions & allowPlateaus(bool f = true)
579 {
580 allow_plateaus = f;
581 return *this;
582 }
583 };
584
585
586 /********************************************************/
587 /* */
588 /* localMinima */
589 /* */
590 /********************************************************/
591
592 /** \brief Find local minima in an image or multi-dimensional array.
593
594 By default, minima are defined as points which are not
595 at the array border and whose value is lower than the value
596 of all indirect neighbors (i.e. 8-neighbors in 2D,
597 26-neighbors in 3D, 3<sup>N</sup>-1 neighbors in N-D).
598 The detected points will be marked
599 with the default value 1 in the destination array.
600
601 The defaults can be overridden in various ways by providing
602 \ref LocalMinmaxOptions : you can switch to the direct neighborhood
603 (i.e. 4-neighborhood in 2D, 6-neighborhood in 3D, 2*N neighborhood
604 in N-D), allow minima at the border, discard minima where the function
605 value is not below a given threshold, allow extended minima
606 (i.e. minima that form minimal plateaus rather than isolated pixels --
607 note that this option is only supported for 2D images),
608 and change the marker in the destination image. See usage examples below
609 for details.
610
611 There are also variants of the localMinima() function where parameters
612 are passed explicitly rather than via an option object. These versions
613 of the function are deprecated, but will be kept for compatibility.
614
615 <b> Declarations:</b>
616
617 use arbitrary-dimensional arrays:
618 \code
619 namespace vigra {
620 template <unsigned int N, class T1, class C1, class T2, class C2>
621 void
622 localMinima(MultiArrayView<N, T1, C1> src,
623 MultiArrayView<N, T2, C2> dest,
624 LocalMinmaxOptions const & options = LocalMinmaxOptions());
625 }
626 \endcode
627
628 \deprecatedAPI{localMinima}
629 pass \ref ImageIterators and \ref DataAccessors :
630 \code
631 namespace vigra {
632 template <class SrcIterator, class SrcAccessor,
633 class DestIterator, class DestAccessor>
634 void
635 localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
636 DestIterator dul, DestAccessor da,
637 LocalMinmaxOptions const & options = LocalMinmaxOptions());
638 }
639 \endcode
640 use argument objects in conjunction with \ref ArgumentObjectFactories :
641 \code
642 namespace vigra {
643 template <class SrcIterator, class SrcAccessor,
644 class DestIterator, class DestAccessor>
645 void
646 localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
647 pair<DestIterator, DestAccessor> dest,
648 LocalMinmaxOptions const & options = LocalMinmaxOptions());
649 }
650 \endcode
651 \deprecatedEnd
652
653 <b> Usage:</b>
654
655 <b>\#include</b> <vigra/localminmax.hxx><br>
656 <b>\#include</b> <vigra/multi_localminmax.hxx><br>
657 Namespace: vigra
658
659 \code
660 // 3D examples (other dimensions work likewise)
661 Shape3 shape(w,h,d);
662 MultiArray<3, unsigned char> src(shape), minima(shape);
663 ... // fill src
664
665 // use default parameterisation
666 localMinima(src, minima);
667
668 // reset destination image
669 minima = 0;
670
671 // use direct neighborhood (i.e. 6-neighborhood since we are in 3D)
672 // and allow minima at the image border
673 localMinima(src, minima,
674 LocalMinmaxOptions().neighborhood(0).allowAtBorder());
675 \endcode
676
677 \deprecatedUsage{localMinima}
678 \code
679 // 2D examples using BasicImage
680 BImage src(w,h), minima(w,h);
681 ... // fill src
682
683 // use default parameterisation
684 localMinima(srcImageRange(src), destImage(minima));
685
686 // reset destination image
687 minima = 0;
688
689 // use 4-neighborhood and allow minima at the image border
690 localMinima(srcImageRange(src), destImage(minima),
691 LocalMinmaxOptions().neighborhood(4).allowAtBorder());
692
693 // reset destination image
694 minima = 0;
695
696 // allow extended minima (minimal plateaus) and use value '255' as a marker
697 localMinima(srcImageRange(src), destImage(minima),
698 LocalMinmaxOptions().allowPlateaus().markWith(255));
699 \endcode
700 <b> Required Interface:</b>
701 \code
702 SrcIterator src_upperleft, src_lowerright;
703 DestIterator dest_upperleft;
704
705 SrcAccessor src_accessor;
706 DestAccessor dest_accessor;
707
708 SrcAccessor::value_type u = src_accessor(src_upperleft);
709
710 u < u
711 \endcode
712 \deprecatedEnd
713 */
714 doxygen_overloaded_function(template <...> void localMinima)
715
716 template <class SrcIterator, class SrcAccessor,
717 class DestIterator, class DestAccessor>
718 inline void
719 localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
720 DestIterator dul, DestAccessor da,
721 LocalMinmaxOptions const & options = LocalMinmaxOptions())
722 {
723 typedef typename SrcAccessor::value_type SrcType;
724 typedef typename DestAccessor::value_type DestType;
725
726 SrcType threshold = options.use_threshold
727 ? std::min(NumericTraits<SrcType>::max(), (SrcType)options.thresh)
728 : NumericTraits<SrcType>::max();
729 DestType marker = (DestType)options.marker;
730
731 if(options.allow_plateaus)
732 {
733 if(options.neigh == 0 || options.neigh == 4)
734 {
735 detail::extendedLocalMinMax(sul, slr, sa, dul, da, marker, FourNeighborCode(),
736 std::less<SrcType>(), std::equal_to<SrcType>(),
737 threshold, options.allow_at_border);
738 }
739 else if(options.neigh == 1 || options.neigh == 8)
740 {
741 detail::extendedLocalMinMax(sul, slr, sa, dul, da, marker, EightNeighborCode(),
742 std::less<SrcType>(), std::equal_to<SrcType>(),
743 threshold, options.allow_at_border);
744 }
745 else
746 vigra_precondition(false, "localMinima(): neighborhood must be 4 or 8.");
747
748 }
749 else
750 {
751 if(options.neigh == 0 || options.neigh == 4)
752 {
753 detail::localMinMax(sul, slr, sa, dul, da, marker, FourNeighborCode(),
754 threshold, std::less<SrcType>(), options.allow_at_border);
755 }
756 else if(options.neigh == 1 || options.neigh == 8)
757 {
758 detail::localMinMax(sul, slr, sa, dul, da, marker, EightNeighborCode(),
759 threshold, std::less<SrcType>(), options.allow_at_border);
760 }
761 else
762 vigra_precondition(false, "localMinima(): neighborhood must be 4 or 8.");
763 }
764 }
765
766 template <class SrcIterator, class SrcAccessor,
767 class DestIterator, class DestAccessor,
768 class DestValue>
769 inline void
770 localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
771 DestIterator dul, DestAccessor da,
772 DestValue marker, FourNeighborCode neighborhood)
773 {
774 detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood,
775 NumericTraits<typename SrcAccessor::value_type>::max(),
776 std::less<typename SrcAccessor::value_type>());
777 }
778
779 template <class SrcIterator, class SrcAccessor,
780 class DestIterator, class DestAccessor,
781 class DestValue>
782 inline void
783 localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
784 DestIterator dul, DestAccessor da,
785 DestValue marker, EightNeighborCode neighborhood)
786 {
787 detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood,
788 NumericTraits<typename SrcAccessor::value_type>::max(),
789 std::less<typename SrcAccessor::value_type>());
790 }
791
792 template <class SrcIterator, class SrcAccessor,
793 class DestIterator, class DestAccessor, class DestValue>
794 inline void
795 localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
796 DestIterator dul, DestAccessor da,
797 DestValue marker)
798 {
799 localMinima(sul, slr, sa, dul, da, marker, EightNeighborCode());
800 }
801
802 template <class SrcIterator, class SrcAccessor,
803 class DestIterator, class DestAccessor,
804 class DestValue>
805 inline void
806 localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
807 pair<DestIterator, DestAccessor> dest,
808 DestValue marker, FourNeighborCode neighborhood)
809 {
810 localMinima(src.first, src.second, src.third,
811 dest.first, dest.second, marker, neighborhood);
812 }
813
814 template <class SrcIterator, class SrcAccessor,
815 class DestIterator, class DestAccessor,
816 class DestValue>
817 inline void
818 localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
819 pair<DestIterator, DestAccessor> dest,
820 DestValue marker, EightNeighborCode neighborhood)
821 {
822 localMinima(src.first, src.second, src.third,
823 dest.first, dest.second, marker, neighborhood);
824 }
825
826 template <class SrcIterator, class SrcAccessor,
827 class DestIterator, class DestAccessor, class DestValue>
828 inline void
829 localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
830 pair<DestIterator, DestAccessor> dest,
831 DestValue marker)
832 {
833 localMinima(src.first, src.second, src.third,
834 dest.first, dest.second, marker, EightNeighborCode());
835 }
836
837 template <class SrcIterator, class SrcAccessor,
838 class DestIterator, class DestAccessor>
839 inline void
840 localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
841 pair<DestIterator, DestAccessor> dest,
842 LocalMinmaxOptions const & options = LocalMinmaxOptions())
843 {
844 localMinima(src.first, src.second, src.third,
845 dest.first, dest.second, options);
846 }
847
848 /**************************************************************************/
849
850 /********************************************************/
851 /* */
852 /* localMinima3D */
853 /* */
854 /********************************************************/
855
856 /** \brief Find local minima in a 3D multi array.
857
858 Deprecated, use localMinima() instead.
859
860 */
861 doxygen_overloaded_function(template <...> void localMinima3D)
862
863 template<class SrcIterator, class SrcAccessor, class SrcShape,
864 class DestIterator, class DestAccessor, class DestValue>
865 inline void
866 localMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
867 DestIterator dul, DestAccessor da,
868 DestValue marker,
869 NeighborCode3DTwentySix neighborhood)
870 {
871 detail::localMinMax3D(sul, slr, sa, dul, da, marker, neighborhood,
872 NumericTraits<typename SrcAccessor::value_type>::max(),
873 std::less<typename SrcAccessor::value_type>());
874 }
875
876 template<class SrcIterator, class SrcAccessor, class SrcShape,
877 class DestIterator, class DestAccessor, class DestValue>
878 inline void
879 localMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
880 DestIterator dul, DestAccessor da,
881 DestValue marker,
882 NeighborCode3DSix neighborhood)
883 {
884 detail::localMinMax3D(sul, slr, sa, dul, da, marker, neighborhood,
885 NumericTraits<typename SrcAccessor::value_type>::max(),
886 std::less<typename SrcAccessor::value_type>());
887 }
888
889 template<class SrcIterator, class SrcShape, class SrcAccessor,
890 class DestIterator, class DestAccessor, class DestValue>
891 inline void
892 localMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
893 DestIterator dul, DestAccessor da,
894 DestValue marker)
895 {
896 localMinima3D(sul, slr, sa, dul, da, marker, NeighborCode3DSix());
897 }
898
899 template<class SrcIterator, class SrcShape, class SrcAccessor,
900 class DestIterator, class DestAccessor, class DestValue>
901 inline void
902 localMinima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
903 pair<DestIterator, DestAccessor> dest,
904 DestValue marker,
905 NeighborCode3DSix neighborhood)
906 {
907 localMinima3D(src.first, src.second, src.third, dest.first, dest.second,
908 marker, neighborhood);
909 }
910
911 template<class SrcIterator, class SrcShape, class SrcAccessor,
912 class DestIterator, class DestAccessor, class DestValue>
913 inline void
914 localMinima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
915 pair<DestIterator, DestAccessor> dest,
916 DestValue marker,
917 NeighborCode3DTwentySix neighborhood)
918 {
919 localMinima3D(src.first, src.second, src.third, dest.first, dest.second,
920 marker, neighborhood);
921 }
922
923 template<class T1, class S1,
924 class T2, class S2,
925 class DestValue,
926 class Neighborhood>
927 inline void
928 localMinima3D(MultiArrayView<3, T1, S1> const & src,
929 MultiArrayView<3, T2, S2> dest,
930 DestValue marker,
931 Neighborhood neighborhood)
932 {
933 localMinima3D(srcMultiArrayRange(src), destMultiArray(dest),
934 marker, neighborhood);
935 }
936
937 template<class T1, class S1,
938 class T2, class S2,
939 class DestValue>
940 inline void
941 localMinima3D(MultiArrayView<2, T1, S1> const & src,
942 MultiArrayView<2, T2, S2> dest,
943 DestValue marker)
944 {
945 localMinima3D(srcMultiArrayRange(src), destMultiArray(dest),
946 marker, NeighborCode3DSix());
947 }
948
949 /**************************************************************************/
950
951 /********************************************************/
952 /* */
953 /* localMaxima */
954 /* */
955 /********************************************************/
956
957 /** \brief Find local maxima in an image or multi-dimensional array.
958
959 By default, maxima are defined as points which are not
960 at the array border and whose value is higher than the value
961 of all indirect neighbors (i.e. 8-neighbors in 2D,
962 26-neighbors in 3D, 3<sup>N</sup>-1 neighbors in N-D).
963 The detected points will be marked
964 with the default value 1 in the destination array.
965
966 The defaults can be overridden in various ways by providing
967 \ref LocalMinmaxOptions : you can switch to the direct neighborhood
968 (i.e. 4-neighborhood in 2D, 6-neighborhood in 3D, 2*N neighborhood
969 in N-D), allow maxima at the border, discard maxima where the function
970 value is not above a given threshold, allow extended maxima
971 (i.e. maxima that form maximal plateaus rather than isolated pixels --
972 note that this option is only supported for 2D images),
973 and change the marker in the destination image. See usage examples below
974 for details.
975
976 There are also variants of the localMaxima() function where parameters
977 are passed explicitly rather than via an option object. These versions
978 of the function are deprecated, but will be kept for compatibility.
979
980 <b> Declarations:</b>
981
982 use arbitrary-dimensional arrays:
983 \code
984 namespace vigra {
985 template <unsigned int N, class T1, class C1, class T2, class C2>
986 void
987 localMaxima(MultiArrayView<N, T1, C1> src,
988 MultiArrayView<N, T2, C2> dest,
989 LocalMinmaxOptions const & options = LocalMinmaxOptions());
990 }
991 \endcode
992
993 \deprecatedAPI{localMaxima}
994 pass \ref ImageIterators and \ref DataAccessors :
995 \code
996 namespace vigra {
997 template <class SrcIterator, class SrcAccessor,
998 class DestIterator, class DestAccessor>
999 void
1000 localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1001 DestIterator dul, DestAccessor da,
1002 LocalMinmaxOptions const & options = LocalMinmaxOptions());
1003 }
1004 \endcode
1005 use argument objects in conjunction with \ref ArgumentObjectFactories :
1006 \code
1007 namespace vigra {
1008 template <class SrcIterator, class SrcAccessor,
1009 class DestIterator, class DestAccessor>
1010 void
1011 localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1012 pair<DestIterator, DestAccessor> dest,
1013 LocalMinmaxOptions const & options = LocalMinmaxOptions());
1014 }
1015 \endcode
1016 \deprecatedEnd
1017
1018 <b> Usage:</b>
1019
1020 <b>\#include</b> <vigra/localminmax.hxx><br>
1021 <b>\#include</b> <vigra/multi_localminmax.hxx><br>
1022 Namespace: vigra
1023
1024 \code
1025 // 3D examples (other dimensions work likewise)
1026 Shape3 shape(w,h,d);
1027 MultiArray<3, unsigned char> src(shape), maxima(shape);
1028 ... // fill src
1029
1030 // use default parameterisation
1031 localMaxima(src, maxima);
1032
1033 // reset destination image
1034 maxima = 0;
1035
1036 // use direct neighborhood (i.e. 6-neighborhood sine we are in 3D)
1037 // and allow maxima at the image border
1038 localMaxima(src, maxima,
1039 LocalMinmaxOptions().neighborhood(0).allowAtBorder());
1040 \endcode
1041
1042 \deprecatedUsage{localMaxima}
1043 \code
1044 // 2D examples using BasicImage
1045 BImage src(w,h), maxima(w,h);
1046 ... // fill src
1047
1048 // use default parameterisation
1049 localMaxima(srcImageRange(src), destImage(maxima));
1050
1051 // reset destination image
1052 maxima = 0;
1053
1054 // use 4-neighborhood and allow maxima at the image border
1055 localMaxima(srcImageRange(src), destImage(maxima),
1056 LocalMinmaxOptions().neighborhood(4).allowAtBorder());
1057
1058 // reset destination image
1059 maxima = 0;
1060
1061 // allow extended maxima (maximal plateaus) and use value '255' as a marker
1062 localMaxima(srcImageRange(src), destImage(maxima),
1063 LocalMinmaxOptions().allowPlateaus().markWith(255));
1064 \endcode
1065 <b> Required Interface:</b>
1066 \code
1067 SrcIterator src_upperleft, src_lowerright;
1068 DestIterator dest_upperleft;
1069
1070 SrcAccessor src_accessor;
1071 DestAccessor dest_accessor;
1072
1073 SrcAccessor::value_type u = src_accessor(src_upperleft);
1074
1075 u < u
1076 \endcode
1077 \deprecatedEnd
1078 */
1079 doxygen_overloaded_function(template <...> void localMaxima)
1080
1081 template <class SrcIterator, class SrcAccessor,
1082 class DestIterator, class DestAccessor>
1083 inline void
1084 localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1085 DestIterator dul, DestAccessor da,
1086 LocalMinmaxOptions const & options = LocalMinmaxOptions())
1087 {
1088 typedef typename SrcAccessor::value_type SrcType;
1089 typedef typename DestAccessor::value_type DestType;
1090
1091 SrcType threshold = options.use_threshold
1092 ? std::max(NumericTraits<SrcType>::min(), (SrcType)options.thresh)
1093 : NumericTraits<SrcType>::min();
1094 DestType marker = (DestType)options.marker;
1095
1096 if(options.allow_plateaus)
1097 {
1098 if(options.neigh == 0 || options.neigh == 4)
1099 {
1100 detail::extendedLocalMinMax(sul, slr, sa, dul, da, marker, FourNeighborCode(),
1101 std::greater<SrcType>(), std::equal_to<SrcType>(),
1102 threshold, options.allow_at_border);
1103 }
1104 else if(options.neigh == 1 || options.neigh == 8)
1105 {
1106 detail::extendedLocalMinMax(sul, slr, sa, dul, da, marker, EightNeighborCode(),
1107 std::greater<SrcType>(), std::equal_to<SrcType>(),
1108 threshold, options.allow_at_border);
1109 }
1110 else
1111 vigra_precondition(false, "localMaxima(): neighborhood must be 4 or 8.");
1112 }
1113 else
1114 {
1115 if(options.neigh == 0 || options.neigh == 4)
1116 {
1117 detail::localMinMax(sul, slr, sa, dul, da, marker, FourNeighborCode(),
1118 threshold, std::greater<SrcType>(), options.allow_at_border);
1119 }
1120 else if(options.neigh == 1 || options.neigh == 8)
1121 {
1122 detail::localMinMax(sul, slr, sa, dul, da, marker, EightNeighborCode(),
1123 threshold, std::greater<SrcType>(), options.allow_at_border);
1124 }
1125 else
1126 vigra_precondition(false, "localMaxima(): neighborhood must be 4 or 8.");
1127 }
1128 }
1129
1130 template <class SrcIterator, class SrcAccessor,
1131 class DestIterator, class DestAccessor,
1132 class DestValue>
1133 inline void
1134 localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1135 DestIterator dul, DestAccessor da,
1136 DestValue marker, FourNeighborCode neighborhood)
1137 {
1138 detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood,
1139 NumericTraits<typename SrcAccessor::value_type>::min(),
1140 std::greater<typename SrcAccessor::value_type>());
1141 }
1142
1143 template <class SrcIterator, class SrcAccessor,
1144 class DestIterator, class DestAccessor,
1145 class DestValue>
1146 inline void
1147 localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1148 DestIterator dul, DestAccessor da,
1149 DestValue marker, EightNeighborCode neighborhood)
1150 {
1151 detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood,
1152 NumericTraits<typename SrcAccessor::value_type>::min(),
1153 std::greater<typename SrcAccessor::value_type>());
1154 }
1155
1156 template <class SrcIterator, class SrcAccessor,
1157 class DestIterator, class DestAccessor, class DestValue>
1158 inline void
1159 localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1160 DestIterator dul, DestAccessor da,
1161 DestValue marker)
1162 {
1163 localMaxima(sul, slr, sa, dul, da, marker, EightNeighborCode());
1164 }
1165
1166 template <class SrcIterator, class SrcAccessor,
1167 class DestIterator, class DestAccessor,
1168 class DestValue>
1169 inline void
1170 localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1171 pair<DestIterator, DestAccessor> dest,
1172 DestValue marker, FourNeighborCode neighborhood)
1173 {
1174 localMaxima(src.first, src.second, src.third,
1175 dest.first, dest.second, marker, neighborhood);
1176 }
1177
1178 template <class SrcIterator, class SrcAccessor,
1179 class DestIterator, class DestAccessor,
1180 class DestValue>
1181 inline void
1182 localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1183 pair<DestIterator, DestAccessor> dest,
1184 DestValue marker, EightNeighborCode neighborhood)
1185 {
1186 localMaxima(src.first, src.second, src.third,
1187 dest.first, dest.second, marker, neighborhood);
1188 }
1189
1190 template <class SrcIterator, class SrcAccessor,
1191 class DestIterator, class DestAccessor, class DestValue>
1192 inline void
1193 localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1194 pair<DestIterator, DestAccessor> dest,
1195 DestValue marker)
1196 {
1197 localMaxima(src.first, src.second, src.third,
1198 dest.first, dest.second, marker, EightNeighborCode());
1199 }
1200
1201 template <class SrcIterator, class SrcAccessor,
1202 class DestIterator, class DestAccessor>
1203 inline void
1204 localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1205 pair<DestIterator, DestAccessor> dest,
1206 LocalMinmaxOptions const & options = LocalMinmaxOptions())
1207 {
1208 localMaxima(src.first, src.second, src.third,
1209 dest.first, dest.second, options);
1210 }
1211
1212 /**************************************************************************/
1213
1214 /********************************************************/
1215 /* */
1216 /* localMaxima3D */
1217 /* */
1218 /********************************************************/
1219
1220 /** \brief Find local maxima in a 3D multi array.
1221
1222 Deprecated, use \ref localMaxima() instead.
1223 */
1224 doxygen_overloaded_function(template <...> void localMaxima3D)
1225
1226 template<class SrcIterator, class SrcShape, class SrcAccessor,
1227 class DestIterator, class DestAccessor, class DestValue>
1228 inline void
1229 localMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
1230 DestIterator dul, DestAccessor da,
1231 DestValue marker,
1232 NeighborCode3DSix neighborhood)
1233 {
1234 detail::localMinMax3D(sul, slr, sa, dul, da, marker, neighborhood,
1235 NumericTraits<typename SrcAccessor::value_type>::min(),
1236 std::greater<typename SrcAccessor::value_type>());
1237 }
1238
1239 template<class SrcIterator, class SrcShape, class SrcAccessor,
1240 class DestIterator, class DestAccessor, class DestValue>
1241 inline void
1242 localMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
1243 DestIterator dul, DestAccessor da,
1244 DestValue marker,
1245 NeighborCode3DTwentySix neighborhood)
1246 {
1247 detail::localMinMax3D(sul, slr, sa, dul, da, marker, neighborhood,
1248 NumericTraits<typename SrcAccessor::value_type>::min(),
1249 std::greater<typename SrcAccessor::value_type>());
1250 }
1251
1252 template<class SrcIterator, class SrcShape, class SrcAccessor,
1253 class DestIterator, class DestAccessor, class DestValue>
1254 inline void
1255 localMaxima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
1256 pair<DestIterator, DestAccessor> dest,
1257 DestValue marker,
1258 NeighborCode3DTwentySix neighborhood)
1259 {
1260 localMaxima3D(src.first, src.second, src.third, dest.first, dest.second,
1261 marker, neighborhood);
1262 }
1263
1264 template<class SrcIterator, class SrcShape, class SrcAccessor,
1265 class DestIterator, class DestAccessor, class DestValue>
1266 inline void
1267 localMaxima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
1268 pair<DestIterator, DestAccessor> dest,
1269 DestValue marker)
1270 {
1271 localMaxima3D(src.first, src.second, src.third, dest.first, dest.second,
1272 marker, NeighborCode3DSix());
1273 }
1274
1275 template<class SrcIterator, class SrcShape, class SrcAccessor,
1276 class DestIterator, class DestAccessor, class DestValue>
1277 inline void
1278 localMaxima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
1279 pair<DestIterator, DestAccessor> dest,
1280 DestValue marker,
1281 NeighborCode3DSix neighborhood)
1282 {
1283 localMaxima3D(src.first, src.second, src.third, dest.first, dest.second,
1284 marker, neighborhood);
1285 }
1286
1287 template<class T1, class S1,
1288 class T2, class S2,
1289 class DestValue,
1290 class Neighborhood>
1291 inline void
1292 localMaxima3D(MultiArrayView<3, T1, S1> const & src,
1293 MultiArrayView<3, T2, S2> dest,
1294 DestValue marker,
1295 Neighborhood neighborhood)
1296 {
1297 localMaxima3D(srcMultiArrayRange(src), destMultiArray(dest),
1298 marker, neighborhood);
1299 }
1300
1301 template<class T1, class S1,
1302 class T2, class S2,
1303 class DestValue>
1304 inline void
1305 localMaxima3D(MultiArrayView<3, T1, S1> const & src,
1306 MultiArrayView<3, T2, S2> dest,
1307 DestValue marker)
1308 {
1309 localMaxima3D(srcMultiArrayRange(src), destMultiArray(dest),
1310 marker, NeighborCode3DSix());
1311 }
1312
1313
1314 /**************************************************************************/
1315
1316 /********************************************************/
1317 /* */
1318 /* extendedLocalMinima */
1319 /* */
1320 /********************************************************/
1321
1322 /** \brief Find local minimal regions (plateaus) in an array.
1323
1324 This function is only needed when you want to pass a non-standard equality
1325 predicate via <tt>EqualityFunctor</tt>. Otherwise (i.e. when equality
1326 is defined by the '==' operator of the source value type <tt>T1</tt>),
1327 you can simply call \ref localMinima() with the option
1328 <tt>LocalMinmaxOptions::allowPlateaus()</tt>.
1329
1330 This function finds regions of uniform pixel values
1331 whose neighboring regions all have larger values, i.e. it finds minimal
1332 plateaus of arbitrary size (including size 1). The <tt>EqualityFunctor</tt>
1333 determines when pixels are considered equal, so that one can allow
1334 for plateaus that are not quite constant (this is often necessary
1335 with float pixel values). Otherwise, the functionality is identical to
1336 \ref localMinima().
1337
1338 <b> Declarations:</b>
1339
1340 use arbitrary-dimensional arrays:
1341 \code
1342 namespace vigra {
1343 template <unsigned int N, class T1, class S1,
1344 class T2, class S2,
1345 class EqualityFunctor>
1346 unsigned int
1347 extendedLocalMinima(MultiArrayView<N, T1, S1> const & src,
1348 MultiArrayView<N, T2, S2> dest,
1349 EqualityFunctor const & equal,
1350 LocalMinmaxOptions options = LocalMinmaxOptions());
1351 \endcode
1352
1353 \deprecatedAPI{extendedLocalMinima}
1354 pass \ref ImageIterators and \ref DataAccessors :
1355 \code
1356 namespace vigra {
1357 template <class SrcIterator, class SrcAccessor,
1358 class DestIterator, class DestAccessor,
1359 class DestValue = DestAccessor::value_type,
1360 class Neighborhood = EightNeighborCode,
1361 class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> >
1362 void
1363 extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1364 DestIterator dul, DestAccessor da,
1365 DestValue marker = NumericTraits<DestValue>::one(),
1366 Neighborhood neighborhood = EightNeighborCode(),
1367 EqualityFunctor equal = EqualityFunctor());
1368
1369 template<class SrcIterator, class SrcShape, class SrcAccessor,
1370 class DestIterator, class DestAccessor,
1371 class Neighborhood = NeighborCode3DSix,
1372 class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> >
1373 void
1374 extendedLocalMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
1375 DestIterator dul, DestAccessor da,
1376 typename DestAccessor::value_type marker,
1377 Neighborhood neighborhood = Neighborhood(),
1378 EqualityFunctor equal = EqualityFunctor());
1379 }
1380 \endcode
1381 use argument objects in conjunction with \ref ArgumentObjectFactories :
1382 \code
1383 namespace vigra {
1384 template <class SrcIterator, class SrcAccessor,
1385 class DestIterator, class DestAccessor,
1386 class DestValue = DestAccessor::value_type,
1387 class Neighborhood = EightNeighborCode,
1388 class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> >
1389 void
1390 extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1391 pair<DestIterator, DestAccessor> dest,
1392 DestValue marker = NumericTraits<DestValue>::one(),
1393 Neighborhood neighborhood = EightNeighborCode(),
1394 EqualityFunctor equal = EqualityFunctor());
1395
1396 template<class SrcIterator, class SrcAccessor, class SrcShape,
1397 class DestIterator, class DestAccessor,
1398 class Neighborhood>
1399 void
1400 extendedLocalMinima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
1401 pair<DestIterator, DestAccessor> dest,
1402 typename DestAccessor::value_type marker,
1403 Neighborhood neighborhood);
1404 }
1405 \endcode
1406 \deprecatedEnd
1407
1408 <b> Usage:</b>
1409
1410 <b>\#include</b> <vigra/localminmax.hxx><br>
1411 Namespace: vigra
1412
1413 \code
1414 // define an equality functor
1415 template <class T>
1416 struct EqualWithToleranceFunctor
1417 {
1418 EqualWithToleranceFunctor(T tolerance)
1419 : t(tolerance)
1420 {}
1421
1422 bool operator()(T l, T r) const
1423 {
1424 return abs(l-r) <= t;
1425 }
1426
1427 T t;
1428 };
1429
1430 MultiArray<2, unsigned char> src(w,h), minima(w,h);
1431
1432 // allow plateaus
1433 localMinima(src, minima, LocalMinmaxOptions().allowPlateaus());
1434
1435 // reset result image
1436 minima.init(0);
1437 // allow plateaus with tolerance (grayvalues may differ by one)
1438 extendedLocalMinima(src, minima, EqualWithToleranceFunctor<unsigned char>(1));
1439 \endcode
1440
1441 \deprecatedUsage{extendedLocalMinima}
1442 \code
1443 // optional: define an equality functor
1444 template <class T>
1445 struct EqualWithToleranceFunctor
1446 {
1447 EqualWithToleranceFunctor(T tolerance)
1448 : t(tolerance)
1449 {}
1450
1451 bool operator()(T l, T r) const
1452 {
1453 return abs(l-r) <= t;
1454 }
1455
1456 T t;
1457 };
1458
1459 BImage src(w,h), minima(w,h);
1460
1461 // init destiniation image
1462 minima.init(0);
1463
1464 extendedLocalMinima(srcImageRange(src), destImage(minima));
1465
1466 // allow plateaus with tolerance
1467 minima.init(0);
1468 extendedLocalMinima(srcImageRange(src), destImage(minima), 1.0,
1469 FourNeighborCode(),
1470 EqualWithToleranceFunctor<unsigned char>(1));
1471 \endcode
1472 <b> Required Interface:</b>
1473 \code
1474 SrcImageIterator src_upperleft, src_lowerright;
1475 DestImageIterator dest_upperleft;
1476
1477 SrcAccessor src_accessor;
1478 DestAccessor dest_accessor;
1479
1480 SrcAccessor::value_type u = src_accessor(src_upperleft);
1481
1482 EqualityFunctor equal;
1483 u == u
1484 equal(u, u);
1485 u < u
1486
1487 DestValue marker;
1488 dest_accessor.set(marker, dest_upperleft);
1489 \endcode
1490 \deprecatedEnd
1491 */
1492 doxygen_overloaded_function(template <...> void extendedLocalMinima)
1493
1494 template <class SrcIterator, class SrcAccessor,
1495 class DestIterator, class DestAccessor,
1496 class Neighborhood, class EqualityFunctor>
1497 inline void
1498 extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1499 DestIterator dul, DestAccessor da,
1500 typename DestAccessor::value_type marker,
1501 Neighborhood neighborhood, EqualityFunctor equal)
1502 {
1503 typedef typename SrcAccessor::value_type SrcType;
1504
1505 detail::extendedLocalMinMax(sul, slr, sa, dul, da,
1506 marker, neighborhood,
1507 std::less<SrcType>(), equal,
1508 NumericTraits<typename SrcAccessor::value_type>::max());
1509 }
1510
1511 template <class SrcIterator, class SrcAccessor,
1512 class DestIterator, class DestAccessor,
1513 class Neighborhood>
1514 inline void
1515 extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1516 DestIterator dul, DestAccessor da,
1517 typename DestAccessor::value_type marker,
1518 Neighborhood neighborhood)
1519 {
1520 typedef typename SrcAccessor::value_type SrcType;
1521
1522 extendedLocalMinima(sul, slr, sa, dul, da,
1523 marker, neighborhood, std::equal_to<SrcType>());
1524 }
1525
1526 template <class SrcIterator, class SrcAccessor,
1527 class DestIterator, class DestAccessor>
1528 inline void
1529 extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1530 DestIterator dul, DestAccessor da,
1531 typename DestAccessor::value_type marker)
1532 {
1533 extendedLocalMinima(sul, slr, sa, dul, da,
1534 marker, EightNeighborCode());
1535 }
1536
1537 template <class SrcIterator, class SrcAccessor,
1538 class DestIterator, class DestAccessor>
1539 inline void
1540 extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1541 DestIterator dul, DestAccessor da)
1542 {
1543 extendedLocalMinima(sul, slr, sa, dul, da,
1544 NumericTraits<typename DestAccessor::value_type>::one());
1545 }
1546
1547 template <class SrcIterator, class SrcAccessor,
1548 class DestIterator, class DestAccessor,
1549 class Neighborhood, class EqualityFunctor>
1550 inline void
1551 extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1552 pair<DestIterator, DestAccessor> dest,
1553 typename DestAccessor::value_type marker, Neighborhood neighborhood,
1554 EqualityFunctor equal)
1555 {
1556 extendedLocalMinima(src.first, src.second, src.third,
1557 dest.first, dest.second, marker, neighborhood, equal);
1558 }
1559
1560 template <class SrcIterator, class SrcAccessor,
1561 class DestIterator, class DestAccessor,
1562 class Neighborhood>
1563 inline void
1564 extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1565 pair<DestIterator, DestAccessor> dest,
1566 typename DestAccessor::value_type marker, Neighborhood neighborhood)
1567 {
1568 extendedLocalMinima(src.first, src.second, src.third,
1569 dest.first, dest.second, marker, neighborhood);
1570 }
1571
1572 template <class SrcIterator, class SrcAccessor,
1573 class DestIterator, class DestAccessor>
1574 inline void
1575 extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1576 pair<DestIterator, DestAccessor> dest,
1577 typename DestAccessor::value_type marker)
1578 {
1579 extendedLocalMinima(src.first, src.second, src.third,
1580 dest.first, dest.second, marker, EightNeighborCode());
1581 }
1582
1583 template <class SrcIterator, class SrcAccessor,
1584 class DestIterator, class DestAccessor>
1585 inline void
1586 extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1587 pair<DestIterator, DestAccessor> dest)
1588 {
1589 extendedLocalMinima(src.first, src.second, src.third,
1590 dest.first, dest.second);
1591 }
1592
1593 /**************************************************************************/
1594
1595 /********************************************************/
1596 /* */
1597 /* extendedLocalMinima3D */
1598 /* */
1599 /********************************************************/
1600
1601 /** \brief Find local minimal regions in a volume.
1602
1603 See \ref extendedLocalMinima().
1604
1605 */
1606 doxygen_overloaded_function(template <...> void extendedLocalMinima3D)
1607
1608 template<class SrcIterator, class SrcShape, class SrcAccessor,
1609 class DestIterator, class DestAccessor, class Neighborhood,
1610 class EqualityFunctor>
1611 inline void
1612 extendedLocalMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
1613 DestIterator dul, DestAccessor da,
1614 typename DestAccessor::value_type marker,
1615 Neighborhood neighborhood,
1616 EqualityFunctor equal)
1617 {
1618 typedef typename SrcAccessor::value_type SrcType;
1619
1620 detail::extendedLocalMinMax3D(sul, slr, sa, dul, da, marker, neighborhood,
1621 std::less<SrcType>(), equal,
1622 NumericTraits<typename SrcAccessor::value_type>::max());
1623 }
1624
1625 template<class SrcIterator, class SrcShape, class SrcAccessor,
1626 class DestIterator, class DestAccessor, class Neighborhood>
1627 inline void
1628 extendedLocalMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
1629 DestIterator dul, DestAccessor da,
1630 typename DestAccessor::value_type marker,
1631 Neighborhood neighborhood)
1632 {
1633 typedef typename SrcAccessor::value_type SrcType;
1634
1635 extendedLocalMinima3D(sul, slr, sa, dul, da, marker, neighborhood,
1636 std::equal_to<SrcType>());
1637 }
1638
1639 template<class SrcIterator, class SrcShape, class SrcAccessor,
1640 class DestIterator, class DestAccessor>
1641 inline void
1642 extendedLocalMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
1643 DestIterator dul, DestAccessor da)
1644 {
1645 extendedLocalMinima3D(sul, slr, sa, dul, da,
1646 NumericTraits<typename DestAccessor::value_type>::one(),
1647 NeighborCode3DSix());
1648 }
1649
1650 template<class SrcIterator, class SrcAccessor, class SrcShape,
1651 class DestIterator, class DestAccessor, class Neighborhood>
1652 inline void
1653 extendedLocalMinima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
1654 pair<DestIterator, DestAccessor> dest,
1655 typename DestAccessor::value_type marker,
1656 Neighborhood neighborhood)
1657 {
1658 extendedLocalMinima3D(src.first, src.second, src.third,
1659 dest.first, dest.second,
1660 marker, neighborhood);
1661 }
1662
1663 /**************************************************************************/
1664
1665 /********************************************************/
1666 /* */
1667 /* extendedLocalMaxima */
1668 /* */
1669 /********************************************************/
1670
1671 /** \brief Find local maximal regions in an array.
1672
1673 This function is only needed when you want to pass a non-standard equality
1674 predicate via <tt>EqualityFunctor</tt>. Otherwise (i.e. when equality
1675 is defined by the '==' operator of the source value type <tt>T1</tt>),
1676 you can simply call \ref localMaxima() with the option
1677 <tt>LocalMinmaxOptions::allowPlateaus()</tt>.
1678
1679 This function finds regions of uniform pixel values
1680 whose neighboring regions all have smaller values, i.e. it finds maximal
1681 plateaus of arbitrary size (including size 1). The <tt>EqualityFunctor</tt>
1682 determines when pixels are considered equal, so that one can allow
1683 for plateaus that are not quite constant (this is often necessary
1684 with float pixel values). Otherwise, the functionality is identical to
1685 \ref localMaxima().
1686
1687 <b> Declarations:</b>
1688
1689 use arbitrary-dimensional arrays:
1690 \code
1691 namespace vigra {
1692 template <unsigned int N, class T1, class S1,
1693 class T2, class S2>
1694 unsigned int // return number of maxima
1695 extendedLocalMaxima(MultiArrayView<N, T1, S1> const & src,
1696 MultiArrayView<N, T2, S2> dest,
1697 LocalMinmaxOptions options = LocalMinmaxOptions());
1698 \endcode
1699
1700 \deprecatedAPI{extendedLocalMaxima}
1701 pass \ref ImageIterators and \ref DataAccessors :
1702 \code
1703 namespace vigra {
1704 template <class SrcIterator, class SrcAccessor,
1705 class DestIterator, class DestAccessor,
1706 class DestValue = DestAccessor::value_type,
1707 class Neighborhood = EightNeighborCode,
1708 class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> >
1709 void
1710 extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1711 DestIterator dul, DestAccessor da,
1712 DestValue marker = NumericTraits<DestValue>::one(),
1713 Neighborhood neighborhood = EightNeighborCode(),
1714 EqualityFunctor equal = EqualityFunctor())
1715
1716 template<class SrcIterator, class SrcShape, class SrcAccessor,
1717 class DestIterator, class DestAccessor,
1718 class Neighborhood = NeighborCode3DSix,
1719 class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> >
1720 void
1721 extendedLocalMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
1722 DestIterator dul, DestAccessor da,
1723 typename DestAccessor::value_type marker,
1724 Neighborhood neighborhood = Neighborhood(),
1725 EqualityFunctor equal = EqualityFunctor());
1726 }
1727 \endcode
1728 use argument objects in conjunction with \ref ArgumentObjectFactories :
1729 \code
1730 namespace vigra {
1731 template <class SrcIterator, class SrcAccessor,
1732 class DestIterator, class DestAccessor,
1733 class DestValue = DestAccessor::value_type,
1734 class Neighborhood = EightNeighborCode,
1735 class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> >
1736 void
1737 extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1738 pair<DestIterator, DestAccessor> dest,
1739 DestValue marker = NumericTraits<DestValue>::one(),
1740 Neighborhood neighborhood = EightNeighborCode(),
1741 EqualityFunctor equal = EqualityFunctor())
1742
1743 template<class SrcIterator, class SrcAccessor, class SrcShape,
1744 class DestIterator, class DestAccessor,
1745 class Neighborhood>
1746 void
1747 extendedLocalMaxima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
1748 pair<DestIterator, DestAccessor> dest,
1749 typename DestAccessor::value_type marker,
1750 Neighborhood neighborhood);
1751 }
1752 \endcode
1753 \deprecatedEnd
1754
1755 <b> Usage:</b>
1756
1757 <b>\#include</b> <vigra/localminmax.hxx><br>
1758 Namespace: vigra
1759
1760 \code
1761 // define an equality functor
1762 template <class T>
1763 struct EqualWithToleranceFunctor
1764 {
1765 EqualWithToleranceFunctor(T tolerance)
1766 : t(tolerance)
1767 {}
1768
1769 bool operator()(T l, T r) const
1770 {
1771 return abs(l-r) <= t;
1772 }
1773
1774 T t;
1775 };
1776
1777 MultiArray<2, unsigned char> src(w,h), maxima(w,h);
1778
1779 // allow plateaus
1780 localMaxima(src, maxima, LocalMinmaxOptions().allowPlateaus());
1781
1782 // reset result image
1783 maxima.init(0);
1784 // allow plateaus with tolerance (grayvalues may differ by one)
1785 extendedLocalMaxima(src, maxima, EqualWithToleranceFunctor<unsigned char>(1));
1786 \endcode
1787
1788 \deprecatedUsage{extendedLocalMaxima}
1789 \code
1790
1791 // optional: define an equality functor
1792 template <class T>
1793 struct EqualWithToleranceFunctor
1794 {
1795 EqualWithToleranceFunctor(T tolerance)
1796 : t(tolerance)
1797 {}
1798
1799 bool operator()(T l, T r) const
1800 {
1801 return abs(l-r) <= t;
1802 }
1803
1804 T t;
1805 };
1806
1807 BImage src(w,h), maxima(w,h);
1808
1809 // init destiniation image
1810 maxima.init(0);
1811
1812 extendedLocalMaxima(srcImageRange(src), destImage(maxima));
1813
1814 // allow plateaus with tolerance
1815 maxima.init(0);
1816 extendedLocalMaxima(srcImageRange(src), destImage(maxima), 1.0,
1817 FourNeighborCode(),
1818 EqualWithToleranceFunctor<unsigned char>(1));
1819 \endcode
1820 <b> Required Interface:</b>
1821 \code
1822 SrcImageIterator src_upperleft, src_lowerright;
1823 DestImageIterator dest_upperleft;
1824
1825 SrcAccessor src_accessor;
1826 DestAccessor dest_accessor;
1827
1828 SrcAccessor::value_type u = src_accessor(src_upperleft);
1829
1830 EqualityFunctor equal;
1831 u == u
1832 equal(u, u);
1833 u < u
1834
1835 DestValue marker;
1836 dest_accessor.set(marker, dest_upperleft);
1837 \endcode
1838 \deprecatedEnd
1839 */
1840 doxygen_overloaded_function(template <...> void extendedLocalMaxima)
1841
1842 template <class SrcIterator, class SrcAccessor,
1843 class DestIterator, class DestAccessor,
1844 class Neighborhood, class EqualityFunctor>
1845 inline void
1846 extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1847 DestIterator dul, DestAccessor da,
1848 typename DestAccessor::value_type marker,
1849 Neighborhood neighborhood, EqualityFunctor equal)
1850 {
1851 typedef typename SrcAccessor::value_type SrcType;
1852
1853 detail::extendedLocalMinMax(sul, slr, sa, dul, da,
1854 marker, neighborhood,
1855 std::greater<SrcType>(), equal,
1856 NumericTraits<typename SrcAccessor::value_type>::min());
1857 }
1858
1859 template <class SrcIterator, class SrcAccessor,
1860 class DestIterator, class DestAccessor,
1861 class Neighborhood>
1862 inline void
1863 extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1864 DestIterator dul, DestAccessor da,
1865 typename DestAccessor::value_type marker,
1866 Neighborhood neighborhood)
1867 {
1868 typedef typename SrcAccessor::value_type SrcType;
1869
1870 extendedLocalMaxima(sul, slr, sa, dul, da,
1871 marker, neighborhood, std::equal_to<SrcType>());
1872 }
1873
1874 template <class SrcIterator, class SrcAccessor,
1875 class DestIterator, class DestAccessor>
1876 inline void
1877 extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1878 DestIterator dul, DestAccessor da,
1879 typename DestAccessor::value_type marker)
1880 {
1881 extendedLocalMaxima(sul, slr, sa, dul, da,
1882 marker, EightNeighborCode());
1883 }
1884
1885 template <class SrcIterator, class SrcAccessor,
1886 class DestIterator, class DestAccessor>
1887 inline void
1888 extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
1889 DestIterator dul, DestAccessor da)
1890 {
1891 extendedLocalMaxima(sul, slr, sa, dul, da,
1892 NumericTraits<typename DestAccessor::value_type>::one());
1893 }
1894
1895 template <class SrcIterator, class SrcAccessor,
1896 class DestIterator, class DestAccessor,
1897 class Neighborhood, class EqualityFunctor>
1898 inline void
1899 extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1900 pair<DestIterator, DestAccessor> dest,
1901 typename DestAccessor::value_type marker, Neighborhood neighborhood,
1902 EqualityFunctor equal)
1903 {
1904 extendedLocalMaxima(src.first, src.second, src.third,
1905 dest.first, dest.second, marker, neighborhood, equal);
1906 }
1907
1908 template <class SrcIterator, class SrcAccessor,
1909 class DestIterator, class DestAccessor,
1910 class Neighborhood>
1911 inline void
1912 extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1913 pair<DestIterator, DestAccessor> dest,
1914 typename DestAccessor::value_type marker, Neighborhood neighborhood)
1915 {
1916 extendedLocalMaxima(src.first, src.second, src.third,
1917 dest.first, dest.second, marker, neighborhood);
1918 }
1919
1920 template <class SrcIterator, class SrcAccessor,
1921 class DestIterator, class DestAccessor>
1922 inline void
1923 extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1924 pair<DestIterator, DestAccessor> dest,
1925 typename DestAccessor::value_type marker)
1926 {
1927 extendedLocalMaxima(src.first, src.second, src.third,
1928 dest.first, dest.second, marker, EightNeighborCode());
1929 }
1930
1931 template <class SrcIterator, class SrcAccessor,
1932 class DestIterator, class DestAccessor>
1933 inline void
1934 extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
1935 pair<DestIterator, DestAccessor> dest)
1936 {
1937 extendedLocalMaxima(src.first, src.second, src.third,
1938 dest.first, dest.second);
1939 }
1940
1941 /********************************************************/
1942 /* */
1943 /* extendedLocalMaxima3D */
1944 /* */
1945 /********************************************************/
1946
1947 /** \brief Find local maximal regions in 3D multi array.
1948
1949 See \ref extendedLocalMaxima().
1950 */
1951
1952 doxygen_overloaded_function(template <...> void extendedLocalMaxima3D)
1953
1954 template<class SrcIterator, class SrcShape, class SrcAccessor,
1955 class DestIterator, class DestAccessor, class Neighborhood,
1956 class EqualityFunctor>
1957 inline void
1958 extendedLocalMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
1959 DestIterator dul, DestAccessor da,
1960 typename DestAccessor::value_type marker,
1961 Neighborhood neighborhood,
1962 EqualityFunctor equal)
1963 {
1964 typedef typename SrcAccessor::value_type SrcType;
1965
1966 detail::extendedLocalMinMax3D(sul, slr, sa, dul, da, marker, neighborhood,
1967 std::greater<SrcType>(), equal,
1968 NumericTraits<typename SrcAccessor::value_type>::min());
1969 }
1970
1971 template<class SrcIterator, class SrcShape, class SrcAccessor,
1972 class DestIterator, class DestAccessor, class Neighborhood>
1973 inline void
1974 extendedLocalMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
1975 DestIterator dul, DestAccessor da,
1976 typename DestAccessor::value_type marker,
1977 Neighborhood neighborhood)
1978 {
1979 typedef typename SrcAccessor::value_type SrcType;
1980
1981 extendedLocalMaxima3D(sul, slr, sa, dul, da,
1982 marker, neighborhood,
1983 std::equal_to<SrcType>());
1984 }
1985
1986 template<class SrcIterator, class SrcShape, class SrcAccessor,
1987 class DestIterator, class DestAccessor>
1988 inline void
1989 extendedLocalMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
1990 DestIterator dul, DestAccessor da)
1991 {
1992 extendedLocalMaxima3D(sul, slr, sa, dul, da,
1993 NumericTraits<typename DestAccessor::value_type>::one(),
1994 NeighborCode3DSix());
1995 }
1996
1997 template<class SrcIterator, class SrcShape, class SrcAccessor,
1998 class DestIterator, class DestAccessor, class Neighborhood>
1999 inline void
2000 extendedLocalMaxima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
2001 pair<DestIterator, DestAccessor> dest,
2002 typename DestAccessor::value_type marker,
2003 Neighborhood neighborhood)
2004 {
2005 extendedLocalMaxima3D(src.first, src.second, src.third,
2006 dest.first, dest.second,
2007 marker, neighborhood);
2008 }
2009
2010 //@}
2011
2012 } // namespace vigra
2013
2014 #endif // VIGRA_LOCALMINMAX_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.10.0 (Mon Nov 18 2013)