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
00027 #ifndef MLN_LABELING_REGIONAL_MINIMA_HH
00028 # define MLN_LABELING_REGIONAL_MINIMA_HH
00029
00033
00034 # include <mln/core/concept/image.hh>
00035 # include <mln/core/concept/neighborhood.hh>
00036 # include <mln/canvas/labeling/sorted.hh>
00037 # include <mln/data/fill.hh>
00038 # include <mln/data/sort_psites.hh>
00039
00040
00041 namespace mln
00042 {
00043
00044 namespace labeling
00045 {
00046
00056 template <typename I, typename N, typename L>
00057 mln_ch_value(I, L)
00058 regional_minima(const Image<I>& input, const Neighborhood<N>& nbh,
00059 L& nlabels);
00060
00061
00062 # ifndef MLN_INCLUDE_ONLY
00063
00064 namespace impl
00065 {
00066
00067
00068
00069 template <typename I>
00070 struct regional_minima_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)
00086 {
00087
00088
00089 (void)n;
00090
00091 mln_invariant(input(n) < input(p));
00092 attr(p) = false;
00093 }
00094
00095 void init_attr(const P&) {}
00096 void merge_attr(const P& r, const P& p) { attr(p) = attr(p) &&
00097 attr(r); }
00098
00099
00100
00101 void init_() { data::fill(attr, true); }
00102 bool handles_(unsigned) const { return true; }
00103 bool labels_(unsigned p) const { return attr.element(p); }
00104 bool equiv_(unsigned n, unsigned p) const { return input.element(n) ==
00105 input.element(p); }
00106 void do_no_union_(unsigned n, unsigned p)
00107 {
00108
00109
00110 (void)n;
00111
00112 mln_invariant(input.element(n) < input.element(p));
00113 attr.element(p) = false;
00114 }
00115
00116 void init_attr_(unsigned) {}
00117 void merge_attr_(unsigned r, unsigned p) { attr.element(p) = attr.element(p) &&
00118 attr.element(r); }
00119
00120
00121
00122 mln_ch_value(I, bool) attr;
00123
00124 regional_minima_functor(const I& input)
00125 : input(input)
00126 {
00127 initialize(attr, input);
00128 }
00129 };
00130
00131
00132 }
00133
00134
00135
00136
00137
00138 template <typename I, typename N, typename L>
00139 mln_ch_value(I, L)
00140 regional_minima(const Image<I>& input_, const Neighborhood<N>& nbh_,
00141 L& nlabels)
00142 {
00143 trace::entering("labeling::regional_minima");
00144
00145 const I& input = exact(input_);
00146 const N& nbh = exact(nbh_);
00147 mln_precondition(input.is_valid());
00148
00149
00150
00151
00152 typedef impl::regional_minima_functor<I> F;
00153 F f(exact(input));
00154 mln_ch_value(I, L)
00155 output = canvas::labeling::sorted(input, nbh, nlabels, f, false);
00156
00157 trace::exiting("labeling::regional_minima");
00158 return output;
00159 }
00160
00161 # endif // ! MLN_INCLUDE_ONLY
00162
00163 }
00164
00165 }
00166
00167
00168 #endif // ! MLN_LABELING_REGIONAL_MINIMA_HH