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_MINIMA_HH
00027 # define MLN_LABELING_REGIONAL_MINIMA_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_minima(const Image<I>& input, const Neighborhood<N>& nbh,
00058 L& nlabels);
00059
00060
00061 # ifndef MLN_INCLUDE_ONLY
00062
00063 namespace impl
00064 {
00065
00066
00067
00068 template <typename I>
00069 struct regional_minima_functor
00070 {
00071 typedef mln_psite(I) P;
00072
00073
00074
00075 const I& input;
00076
00077
00078
00079 void init() { data::fill(attr, true); }
00080 bool handles(const P&) const { return true; }
00081 bool labels(const P& p) const { return attr(p); }
00082 bool equiv(const P& n, const P& p) const { return input(n) ==
00083 input(p); }
00084 void do_no_union(const P& n, const P& p)
00085 {
00086
00087
00088 (void)n;
00089
00090 mln_invariant(input(n) < input(p));
00091 attr(p) = false;
00092 }
00093
00094 void init_attr(const P&) {}
00095 void merge_attr(const P& r, const P& p) { attr(p) = attr(p) &&
00096 attr(r); }
00097
00098
00099
00100 void init_() { data::fill(attr, true); }
00101 bool handles_(unsigned) const { return true; }
00102 bool labels_(unsigned p) const { return attr.element(p); }
00103 bool equiv_(unsigned n, unsigned p) const { return input.element(n) ==
00104 input.element(p); }
00105 void do_no_union_(unsigned n, unsigned p)
00106 {
00107
00108
00109 (void)n;
00110
00111 mln_invariant(input.element(n) < input.element(p));
00112 attr.element(p) = false;
00113 }
00114
00115 void init_attr_(unsigned) {}
00116 void merge_attr_(unsigned r, unsigned p) { attr.element(p) = attr.element(p) &&
00117 attr.element(r); }
00118
00119
00120
00121 mln_ch_value(I, bool) attr;
00122
00123 regional_minima_functor(const I& input)
00124 : input(input)
00125 {
00126 initialize(attr, input);
00127 }
00128 };
00129
00130
00131 }
00132
00133
00134
00135
00136
00137 template <typename I, typename N, typename L>
00138 mln_ch_value(I, L)
00139 regional_minima(const Image<I>& input_, const Neighborhood<N>& nbh_,
00140 L& nlabels)
00141 {
00142 trace::entering("labeling::regional_minima");
00143
00144 const I& input = exact(input_);
00145 const N& nbh = exact(nbh_);
00146 mln_precondition(input.is_valid());
00147
00148
00149
00150
00151 typedef impl::regional_minima_functor<I> F;
00152 F f(exact(input));
00153 mln_ch_value(I, L) output = canvas::labeling_sorted(input, nbh, nlabels,
00154 f, false);
00155
00156 trace::exiting("labeling::regional_minima");
00157 return output;
00158 }
00159
00160 # endif // ! MLN_INCLUDE_ONLY
00161
00162 }
00163
00164 }
00165
00166
00167 #endif // ! MLN_LABELING_REGIONAL_MINIMA_HH