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

localminmax.hxx VIGRA

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,
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,
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 */
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  */
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  */
526  {
527  neigh = n;
528  return *this;
529  }
530 
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  */
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  */
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  */
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  */
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 */
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 */
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 */
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 
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
vigra::TinyVector< int, 3 > Diff3D
3-dimensional difference vector
Definition: voxelneighborhood.hxx:55
LocalMinmaxOptions & markWith(double m)
Mark extrema in the destination image with the given value.
Definition: localminmax.hxx:541
void extendedLocalMinima(...)
Find local minimal regions (plateaus) in an array.
unsigned int labelImage(...)
Find the connected components of a segmented image.
LocalMinmaxOptions()
Construct default options object.
Definition: localminmax.hxx:505
unsigned int labelVolume(...)
Find the connected components of a segmented volume.
AtImageBorder AtVolumeBorder
Encode whether a voxel is near the volume border.
Definition: voxelneighborhood.hxx:72
Neighborhood3DTwentySix::NeighborCode3D NeighborCode3DTwentySix
Definition: voxelneighborhood.hxx:1646
void localMaxima3D(...)
Find local maxima in a 3D multi array.
void localMinima(...)
Find local minima in an image or multi-dimensional array.
void extendedLocalMinima3D(...)
Find local minimal regions in a volume.
void localMinima3D(...)
Find local minima in a 3D multi array.
AtImageBorder
Encode whether a point is near the image border.
Definition: pixelneighborhood.hxx:68
AtImageBorder isAtImageBorder(int x, int y, int width, int height)
Find out whether a point is at the image border.
Definition: pixelneighborhood.hxx:111
AtVolumeBorder isAtVolumeBorder(int x, int y, int z, int width, int height, int depth)
Find out whether a voxel is at the volume border.
Definition: voxelneighborhood.hxx:82
void localMaxima(...)
Find local maxima in an image or multi-dimensional array.
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
Neighborhood3DSix::NeighborCode3D NeighborCode3DSix
Definition: voxelneighborhood.hxx:490
void extendedLocalMaxima(...)
Find local maximal regions in an array.
LocalMinmaxOptions & allowPlateaus(bool f=true)
Allow extremal plateaus.
Definition: localminmax.hxx:578
FourNeighborhood::NeighborCode FourNeighborCode
Definition: pixelneighborhood.hxx:379
LocalMinmaxOptions & neighborhood(unsigned int n)
Use the given neighborhood.
Definition: localminmax.hxx:525
LocalMinmaxOptions & threshold(double t)
Threshold the extrema.
Definition: localminmax.hxx:554
 
Definition: pixelneighborhood.hxx:70
Options object for localMinima() and localMaxima().
Definition: localminmax.hxx:493
EightNeighborhood::NeighborCode EightNeighborCode
Definition: pixelneighborhood.hxx:687
NeighborhoodType
Choose the neighborhood system in a dimension-independent way.
Definition: multi_fwd.hxx:186
void extendedLocalMaxima3D(...)
Find local maximal regions in 3D multi array.
LocalMinmaxOptions & allowAtBorder(bool f=true)
Detect extrema at the image border.
Definition: localminmax.hxx:565

© 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)