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_CANVAS_LABELING_BLOBS_HH
00027 # define MLN_CANVAS_LABELING_BLOBS_HH
00028
00033
00034 # include <mln/core/concept/image.hh>
00035 # include <mln/core/concept/neighborhood.hh>
00036 # include <mln/data/fill.hh>
00037 # include <mln/core/site_set/p_queue_fast.hh>
00038
00039 # include <mln/util/pix.hh>
00040
00041 namespace mln
00042 {
00043
00044 namespace canvas
00045 {
00046
00047 namespace labeling
00048 {
00049
00066 template <typename I, typename N, typename L, typename F>
00067 mln_ch_value(I, L)
00068 blobs(const Image<I>& input_, const Neighborhood<N>& nbh_,
00069 L& nlabels, F& functor);
00070
00071
00072
00073 # ifndef MLN_INCLUDE_ONLY
00074
00075
00076
00077
00078 namespace impl
00079 {
00080
00081
00082
00083 namespace generic
00084 {
00085
00086 template <typename I, typename N, typename L, typename F>
00087 mln_ch_value(I, L)
00088 blobs(const I& input, const N& nbh, L& nlabels, F& functor)
00089 {
00090 typedef mln_psite(I) P;
00091
00092 P cur;
00093 mln_niter(N) n(nbh, cur);
00094 p_queue_fast<P> qu;
00095 const L zero = literal::zero;
00096
00097
00098 nlabels = literal::zero;
00099 typedef mln_ch_value(I, L) out_t;
00100 out_t output;
00101 initialize(output, input);
00102 data::fill(output, zero);
00103 functor.init();
00104
00105
00106 mln_piter(I) p(input.domain());
00107 for_all(p)
00108 if (input(p) && output(p) == zero)
00109 {
00110
00111 if (nlabels == mln_max(L))
00112 {
00113 trace::warning("labeling aborted! Too many labels \
00114 for this label type: nlabels > max(label_type).");
00115
00116 return output;
00117 }
00118 ++nlabels;
00119 functor.new_label(nlabels);
00120 mln_invariant(qu.is_empty());
00121 qu.push(p);
00122 output(p) = nlabels;
00123 functor.process_p(util::pix<out_t>(output, p));
00124 do
00125 {
00126 cur = qu.front();
00127 qu.pop();
00128 for_all(n) if (input.has(n))
00129 if (input(n) && output(n) == zero)
00130 {
00131 mln_invariant(! qu.compute_has(n));
00132 qu.push(n);
00133 output(n) = nlabels;
00134 functor.process_n(util::pix<out_t>(output, n));
00135 }
00136 }
00137 while (! qu.is_empty());
00138 }
00139
00140 functor.finalize();
00141 return output;
00142 }
00143
00144 }
00145
00146 }
00147
00148
00149
00150
00151
00152 template <typename I, typename N, typename L, typename F>
00153 inline
00154 mln_ch_value(I, L)
00155 blobs(const Image<I>& input_, const Neighborhood<N>& nbh_,
00156 L& nlabels, F& functor)
00157 {
00158 trace::entering("labeling::blobs");
00159 mlc_equal(mln_trait_image_kind(I),
00160 mln::trait::image::kind::binary)::check();
00161 const I& input = exact(input_);
00162 const N& nbh = exact(nbh_);
00163 mln_precondition(input.is_valid());
00164
00165
00166 mln_ch_value(I, L)
00167 output = impl::generic::blobs(input, nbh, nlabels, functor);
00168
00169 trace::exiting("labeling::blobs");
00170 return output;
00171 }
00172
00173
00174 # endif // ! MLN_INCLUDE_ONLY
00175
00176 }
00177
00178 }
00179
00180 }
00181
00182
00183 #endif // ! MLN_CANVAS_LABELING_BLOBS_HH