00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_LABELING_REGIONAL_MAXIMA_HH
00027 # define MLN_LABELING_REGIONAL_MAXIMA_HH
00028
00032
00033 # include <mln/core/concept/image.hh>
00034 # include <mln/core/concept/neighborhood.hh>
00035 # include <mln/canvas/labeling.hh>
00036 # include <mln/data/fill.hh>
00037 # include <mln/data/sort_psites.hh>
00038
00039
00040 namespace mln
00041 {
00042
00043 namespace labeling
00044 {
00045
00055 template <typename I, typename N, typename L>
00056 mln_ch_value(I, L)
00057 regional_maxima(const Image<I>& input, const Neighborhood<N>& nbh,
00058 L& nlabels);
00059
00060
00061
00062 # ifndef MLN_INCLUDE_ONLY
00063
00064 namespace impl
00065 {
00066
00067
00068
00069 template <typename I>
00070 struct regional_maxima_functor
00071 {
00072 typedef mln_psite(I) P;
00073
00074
00075
00076 const I& input;
00077
00078
00079
00080 void init() { data::fill(attr, true); }
00081 bool handles(const P&) const { return true; }
00082 bool labels(const P& p) const { return attr(p); }
00083 bool equiv(const P& n, const P& p) const { return input(n) ==
00084 input(p); }
00085 void do_no_union(const P& n, const P& p) { mln_invariant(input(n) >
00086 input(p));
00087 attr(p) = false; (void)n; }
00088 void init_attr(const P&) {}
00089 void merge_attr(const P& r, const P& p) { attr(p) = attr(p) &&
00090 attr(r); }
00091
00092
00093
00094 void init_() { data::fill(attr, true); }
00095 bool handles_(unsigned) const { return true; }
00096 bool labels_(unsigned p) const { return attr.element(p); }
00097 bool equiv_(unsigned n, unsigned p) const { return input.element(n) ==
00098 input.element(p); }
00099 void do_no_union_(unsigned n, unsigned p) { mln_invariant(input.element(n) >
00100 input.element(p));
00101 attr.element(p) = false;
00102 (void) n;
00103 }
00104 void init_attr_(unsigned) {}
00105 void merge_attr_(unsigned r, unsigned p) { attr.element(p) = attr.element(p) &&
00106 attr.element(r); }
00107
00108
00109
00110 mln_ch_value(I, bool) attr;
00111
00112 regional_maxima_functor(const I& input)
00113 : input(input)
00114 {
00115 initialize(attr, input);
00116 }
00117 };
00118
00119
00120 }
00121
00122
00123
00124
00125
00126
00127 template <typename I, typename N, typename L>
00128 mln_ch_value(I, L)
00129 regional_maxima(const Image<I>& input_, const Neighborhood<N>& nbh_,
00130 L& nlabels)
00131 {
00132 trace::entering("labeling::regional_maxima");
00133
00134 const I& input = exact(input_);
00135 const N& nbh = exact(nbh_);
00136 mln_precondition(input.is_valid());
00137
00138 typedef impl::regional_maxima_functor<I> F;
00139 F f(exact(input));
00140 mln_ch_value(I, L) output = canvas::labeling_sorted(input, nbh, nlabels,
00141 f, true);
00142
00143 trace::exiting("labeling::regional_maxima");
00144 return output;
00145 }
00146
00147 # endif // ! MLN_INCLUDE_ONLY
00148
00149 }
00150
00151 }
00152
00153
00154 #endif // ! MLN_LABELING_REGIONAL_MAXIMA_HH