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_BLOBS_AND_COMPUTE_HH
00027 # define MLN_LABELING_BLOBS_AND_COMPUTE_HH
00028
00032
00033
00034 # include <mln/core/concept/image.hh>
00035 # include <mln/core/concept/neighborhood.hh>
00036
00037 # include <mln/labeling/blobs.hh>
00038 # include <mln/labeling/compute.hh>
00039
00040
00041 namespace mln
00042 {
00043
00044 namespace labeling
00045 {
00046
00055 template <typename I, typename N, typename L, typename A>
00056 util::couple<mln_ch_value(I, L), util::array<mln_result(A)> >
00057 blobs_and_compute(const Image<I>& input, const Neighborhood<N>& nbh,
00058 L& nlabels, const Accumulator<A>& accu);
00059
00060
00061
00062 # ifndef MLN_INCLUDE_ONLY
00063
00064
00065 namespace internal
00066 {
00067
00070 template <typename L, typename A>
00071 struct compute_functor
00072 {
00073 typedef mln_result(A) accu_result;
00074 typedef mln_argument(A) accu_argument;
00075 typedef util::array<accu_result> result;
00076
00077 void init()
00078 {
00079
00080 accus_.reserve(static_cast<unsigned>(mln_max(mln_value(L))) / 2);
00081 accus_.append(A());
00082 }
00083
00084 void new_label(const mln_value(L)& l)
00085 {
00086 current_lbl_ = l;
00087 accus_.append(A());
00088 }
00089
00090 void process_p(const util::pix<L>& pix)
00091 {
00092 process_(accu_argument(), pix);
00093 }
00094
00095 void process_n(const util::pix<L>& pix)
00096 {
00097 process_(accu_argument(), pix);
00098 }
00099
00100 void finalize()
00101 {
00102 convert::from_to(accus_, result_);
00103 }
00104
00105
00106 private:
00107 void process_(const mln_psite(L)&, const util::pix<L>& pix)
00108 {
00109 accus_[current_lbl_].take(pix.p());
00110 }
00111
00112 void process_(const mln_value(L)&, const util::pix<L>& pix)
00113 {
00114 accus_[current_lbl_].take(pix.v());
00115 }
00116
00117 void process_(const util::pix<L>&, const util::pix<L>& pix)
00118 {
00119 accus_[current_lbl_].take(pix);
00120 }
00121
00122 public:
00123 util::array<mln_result(A)> result_;
00124 util::array<A> accus_;
00125 mln_value(L) current_lbl_;
00126 };
00127
00128 }
00129
00130
00131
00132
00133
00134
00135 template <typename I, typename N, typename L, typename A>
00136 util::couple<mln_ch_value(I,L), util::array<mln_result(A)> >
00137 blobs_and_compute(const Image<I>& input, const Neighborhood<N>& nbh,
00138 L& nlabels, const Accumulator<A>& accu)
00139 {
00140 trace::entering("labeling::blobs_and_compute");
00141
00142 (void) accu;
00143 mlc_equal(mln_trait_image_kind(I),
00144 mln::trait::image::kind::binary)::check();
00145 mln_precondition(exact(input).is_valid());
00146
00147 typedef mln_ch_value(I,L) out_t;
00148 typedef internal::compute_functor<out_t,A> func_t;
00149 func_t functor;
00150 out_t
00151 output = canvas::labeling::blobs(input, nbh, nlabels, functor);
00152
00153 util::couple<out_t, typename func_t::result>
00154 result = make::couple(output, functor.result_);
00155
00156 trace::exiting("labeling::blobs_and_compute");
00157 return result;
00158 }
00159
00160
00161 # endif // ! MLN_INCLUDE_ONLY
00162
00163
00164 }
00165
00166 }
00167
00168
00169 #endif // ! MLN_LABELING_BLOBS_AND_COMPUTE_HH