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_VALUE_AND_COMPUTE_HH
00027 # define MLN_LABELING_VALUE_AND_COMPUTE_HH
00028
00032
00033 # include <mln/core/concept/image.hh>
00034 # include <mln/core/concept/neighborhood.hh>
00035 # include <mln/canvas/labeling/video.hh>
00036 # include <mln/data/fill.hh>
00037
00038
00039
00040 namespace mln
00041 {
00042
00043 namespace labeling
00044 {
00045
00054
00055 template <typename I, typename N, typename L, typename A>
00056 util::couple<mln_ch_value(I,L),
00057 util::couple<util::array<mln_result(A)>,
00058 util::array<A> > >
00059 value_and_compute(const Image<I>& input, const mln_value(I)& val,
00060 const Neighborhood<N>& nbh, L& nlabels,
00061 const Accumulator<A>& accu);
00062
00063
00064 # ifndef MLN_INCLUDE_ONLY
00065
00066
00067
00068
00069 namespace internal
00070 {
00071
00072 template <typename I, typename N, typename L, typename A>
00073 void
00074 value_and_compute_tests(const Image<I>& input, const mln_value(I)& val,
00075 const Neighborhood<N>& nbh, L& nlabels,
00076 const Accumulator<A>& accu)
00077 {
00078 mln_precondition(exact(input).is_valid());
00079 mln_precondition(exact(nbh).is_valid());
00080
00081 (void) accu;
00082 (void) input;
00083 (void) val;
00084 (void) nbh;
00085 (void) nlabels;
00086 }
00087
00088 }
00089
00090
00091
00092 namespace impl
00093 {
00094
00095
00096
00097 template <typename I, typename L, typename A>
00098 struct value_and_compute_functor
00099 {
00100 typedef mln_psite(I) P;
00101
00102 util::array<mln_result(A)> result_;
00103 util::array<A> accus_;
00104
00105 const I& input;
00106 const mln_value(I)& val;
00107
00108 typedef mln_result(A) accu_result;
00109 typedef mln_argument(A) accu_argument;
00110 typedef util::couple<util::array<accu_result>,
00111 util::array<A> > result;
00112
00113
00114
00115
00116 typedef mln_domain(I) S;
00117
00118
00119
00120 void init() {}
00121 bool handles(const P& p) const { return input(p) == val; }
00122 bool equiv(const P& n, const P&) const { return input(n) == val; }
00123 bool labels(const P&) const { return true; }
00124 void do_no_union(const P&, const P&) {}
00125 void init_attr(const P&) {}
00126 void merge_attr(const P&, const P&) {}
00127 void set_new_label(const P& p, const L& l)
00128 {
00129 accus_.append(A());
00130 process__(accu_argument(), p, l);
00131 }
00132 void set_label(const P& p, const L& l) { process__(accu_argument(), p, l); };
00133 void finalize() { convert::from_to(accus_, result_); }
00134
00135
00136
00137
00138
00139 void init_() { accus_.append(A()); }
00140 bool handles_(unsigned p) const { return input.element(p) == val; }
00141 bool equiv_(unsigned n, unsigned) const { return input.element(n) == val; }
00142 bool labels_(unsigned) const { return true; }
00143 void do_no_union_(unsigned, unsigned) {}
00144 void init_attr_(unsigned) {}
00145 void merge_attr_(unsigned, unsigned) {}
00146 void set_new_label_(unsigned p, const L& l)
00147 {
00148 accus_.append(A());
00149 process__(accu_argument(), p, l);
00150 };
00151 void set_label_(unsigned p, const L& l) { process__(accu_argument(), p, l); };
00152 void finalize_() { convert::from_to(accus_, result_); }
00153
00154
00155
00156
00157
00158 value_and_compute_functor(const Image<I>& input_, const mln_value(I)& val)
00159 : input(exact(input_)),
00160 val(val)
00161 {
00162 }
00163
00164
00165 private:
00166 inline
00167 void process__(const unsigned&, unsigned p, const L& l)
00168 {
00169 accus_[l].take(p);
00170 }
00171
00172 inline
00173 void process__(const mln_psite(I)&, unsigned p, const L& l)
00174 {
00175 accus_[l].take(input.point_at_index(p));
00176 }
00177
00178
00179 inline
00180 void process__(const mln_psite(I)&, const mln_site(I)& p, const L& l)
00181 {
00182 accus_[l].take(p);
00183 }
00184
00185 inline
00186 void process__(const mln_value(I)&, const mln_site(I)&, const L& l)
00187 {
00188 accus_[l].take(l);
00189 }
00190
00191 template <typename V>
00192 inline
00193 void process__(const V&, const mln_site(I)&, const L& l)
00194 {
00195 mlc_abort(V)::check();
00196 }
00197
00198
00199 };
00200
00201 }
00202
00203
00204
00205
00206
00207
00208 template <typename I, typename N, typename L, typename A>
00209 util::couple<mln_ch_value(I,L),
00210 util::couple<util::array<mln_result(A)>,
00211 util::array<A> > >
00212 value_and_compute(const Image<I>& input, const mln_value(I)& val,
00213 const Neighborhood<N>& nbh, L& nlabels,
00214 const Accumulator<A>& accu)
00215 {
00216 trace::entering("labeling::value_and_compute");
00217
00218 internal::value_and_compute_tests(input, val, nbh, nlabels, accu);
00219
00220 typedef mln_ch_value(I,L) out_t;
00221 typedef impl::value_and_compute_functor<I, L, A> func_t;
00222 func_t f(input, val);
00223 out_t output = canvas::labeling::video(input, nbh, nlabels, f);
00224
00225 util::couple<out_t, typename func_t::result>
00226 result = make::couple(output,
00227 make::couple(f.result_, f.accus_));
00228
00229
00230 trace::exiting("labeling::value_and_compute");
00231 return result;
00232 }
00233
00234 # endif // ! MLN_INCLUDE_ONLY
00235
00236 }
00237
00238 }
00239
00240
00241 #endif // ! MLN_LABELING_VALUE_AND_COMPUTE_HH