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