27 #ifndef MLN_LABELING_VALUE_AND_COMPUTE_HH
28 # define MLN_LABELING_VALUE_AND_COMPUTE_HH
34 # include <mln/core/concept/image.hh>
35 # include <mln/core/concept/neighborhood.hh>
36 # include <mln/canvas/labeling/video.hh>
37 # include <mln/data/fill.hh>
38 # include <mln/util/array.hh>
39 # include <mln/util/couple.hh>
61 template <
typename I,
typename N,
typename L,
typename A>
62 util::couple<mln_ch_value(I,L),
63 util::couple<util::array<mln_result(A)>,
66 const Neighborhood<N>& nbh, L& nlabels,
67 const Accumulator<A>& accu);
70 # ifndef MLN_INCLUDE_ONLY
78 template <
typename I,
typename N,
typename L,
typename A>
80 value_and_compute_tests(
const Image<I>& input,
82 const Neighborhood<N>& nbh, L& ,
83 const Accumulator<A>& )
85 mln_precondition(
exact(input).is_valid());
86 mln_precondition(
exact(nbh).is_valid());
101 template <
typename I,
typename L,
typename A>
102 struct value_and_compute_functor
104 typedef mln_psite(I) P;
106 util::array<mln_result(A)> result_;
107 util::array<A> accus_;
110 const mln_value(I)& val;
112 typedef mln_result(A) accu_result;
113 typedef mln_argument(A) accu_argument;
114 typedef util::couple<util::array<accu_result>,
115 util::array<A> > result;
120 typedef mln_domain(I) S;
125 bool handles(
const P&
p)
const {
return input(p) == val; }
126 bool equiv(
const P& n,
const P&)
const {
return input(n) == val; }
127 bool labels(
const P&)
const {
return true; }
128 void do_no_union(
const P&,
const P&) {}
129 void init_attr(
const P&) {}
130 void merge_attr(
const P&,
const P&) {}
131 void set_new_label(
const P&
p,
const L& l)
134 process__(accu_argument(), p, l);
136 void set_label(
const P& p,
const L& l) { process__(accu_argument(), p, l); };
143 void init_() { accus_.append(A()); }
144 bool handles_(
unsigned p)
const {
return input.element(p) == val; }
145 bool equiv_(
unsigned n,
unsigned)
const {
return input.element(n) == val; }
146 bool labels_(
unsigned)
const {
return true; }
147 void do_no_union_(
unsigned,
unsigned) {}
148 void init_attr_(
unsigned) {}
149 void merge_attr_(
unsigned,
unsigned) {}
150 void set_new_label_(
unsigned p,
const L& l)
153 process__(accu_argument(), p, l);
155 void set_label_(
unsigned p,
const L& l) { process__(accu_argument(), p, l); };
162 value_and_compute_functor(
const Image<I>& input_,
const mln_value(I)& val)
163 : input(
exact(input_)),
171 void process__(
const unsigned&,
unsigned p,
const L& l)
177 void process__(
const mln_psite(I)&,
unsigned p,
const L& l)
179 accus_[l].take(input.point_at_offset(p));
184 void process__(
const mln_psite(I)&,
const mln_site(I)& p,
const L& l)
190 void process__(
const mln_value(I)&,
const mln_site(I)&,
const L& l)
195 template <
typename V>
197 void process__(
const V&,
const mln_site(I)&,
const L& )
199 mlc_abort(V)::check();
212 template <
typename I,
typename N,
typename L,
typename A>
213 util::couple<mln_ch_value(I,L),
214 util::couple<util::array<mln_result(A)>,
217 const Neighborhood<N>& nbh, L& nlabels,
218 const Accumulator<A>& accu)
220 mln_trace(
"labeling::value_and_compute");
222 internal::value_and_compute_tests(input, val, nbh, nlabels, accu);
224 typedef mln_ch_value(I,L) out_t;
225 typedef impl::value_and_compute_functor<I, L, A> func_t;
226 func_t f(input, val);
227 out_t output = canvas::
labeling::
video(input, nbh, nlabels, f);
229 util::couple<out_t, typename func_t::result>
230 result = make::couple(output,
231 make::couple(f.result_, f.accus_));
237 # endif // ! MLN_INCLUDE_ONLY
244 #endif // ! MLN_LABELING_VALUE_AND_COMPUTE_HH