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_MAKE_RAG_AND_LABELED_WSL_HH
00027 # define MLN_MAKE_RAG_AND_LABELED_WSL_HH
00028
00037
00038 # include <map>
00039
00040 # include <mln/core/concept/image.hh>
00041 # include <mln/core/concept/neighborhood.hh>
00042 # include <mln/core/image/image2d.hh>
00043 # include <mln/core/alias/box2d.hh>
00044 # include <mln/extension/adjust_fill.hh>
00045 # include <mln/util/graph.hh>
00046 # include <mln/util/couple.hh>
00047
00048
00049 namespace mln
00050 {
00051
00052 namespace make
00053 {
00054
00064
00091 template <typename I, typename N>
00092 util::couple<util::graph,mln_concrete(I)>
00093 rag_and_labeled_wsl(const Image<I>& wshd_,
00094 const Neighborhood<N>& nbh_,
00095 const mln_value(I)& nbasins);
00096
00097
00098
00099 # ifndef MLN_INCLUDE_ONLY
00100
00101
00102 namespace internal
00103 {
00104
00105 template <typename I, typename N>
00106 inline
00107 void
00108 rag_and_labeled_wsl_tests(const Image<I>& wshd,
00109 const Neighborhood<N>& nbh,
00110 const mln_value(I)&)
00111 {
00112 mln_precondition(exact(wshd).is_valid());
00113 mln_precondition(exact(nbh).is_valid());
00114 (void) wshd;
00115 (void) nbh;
00116 }
00117
00118 }
00119
00120
00121 namespace impl
00122 {
00123
00124 namespace generic
00125 {
00126
00127 template <typename I, typename N>
00128 inline
00129 util::couple<util::graph,mln_concrete(I)>
00130 rag_and_labeled_wsl(const Image<I>& wshd_,
00131 const Neighborhood<N>& nbh_,
00132 const mln_value(I)& nbasins)
00133 {
00134 trace::entering("make::impl::generic::rag_and_labeled_wsl");
00135
00136 internal::rag_and_labeled_wsl_tests(wshd_, nbh_, nbasins);
00137 const I& wshd = exact(wshd_);
00138 const N& nbh = exact(nbh_);
00139 typedef mln_value(I) L;
00140
00141 extension::adjust_fill(wshd, nbh, 0u);
00142
00143 mln_concrete(I) output(wshd.domain());
00144
00145
00146
00147 data::fill(output, mln_max(mln_value(I)).prev());
00148
00149 std::map<util::couple<L,L>, mln_value(I)> c2la;
00150 util::array<util::couple<L,L> > la2c;
00151 mln_value(I) nlabels = literal::zero;
00152
00153 L l1, l2;
00154 mln_piter(I) p(wshd.domain());
00155 mln_niter(N) n(nbh, p);
00156 for_all(p)
00157 {
00158 if (wshd(p) != 0u)
00159 continue;
00160
00161 l1 = l2 = 0;
00162 for_all(n)
00163 if (wshd.has(n) && wshd(n) != 0u)
00164 {
00165 if (l1 == 0u)
00166 l1 = wshd(n);
00167 else
00168 if (wshd(n) != l1)
00169 {
00170 mln_invariant(l2 == 0u);
00171 l2 = wshd(n);
00172 break;
00173 }
00174 }
00175 if (l2 == 0u || l1 == 0u)
00176 continue;
00177 if (l2 < l1)
00178 std::swap(l1, l2);
00179
00180
00181 util::couple<L,L> c = make::couple(l2,l1);
00182 if (c2la.find(c) == c2la.end())
00183 {
00184 c2la[c] = nlabels++;
00185 la2c.append(c);
00186 }
00187 output(p) = c2la[c];
00188
00189 }
00190
00191
00192 util::graph g;
00193 g.add_vertices(nbasins.next());
00194 for (unsigned i = 0; i < la2c.nelements(); ++i)
00195 g.add_edge(la2c[i].first(), la2c[i].second());
00196
00197 trace::exiting("make::impl::generic::rag_and_labeled_wsl");
00198 return make::couple(g, output);
00199 }
00200
00201 }
00202
00203 }
00204
00205
00206
00207 namespace internal
00208 {
00209
00210 template <typename I, typename N>
00211 inline
00212 util::couple<util::graph,mln_concrete(I)>
00213 rag_and_labeled_wsl_dispatch(const Image<I>& wshd,
00214 const Neighborhood<N>& nbh,
00215 const mln_value(I)& nbasins)
00216 {
00217 return make::impl::generic::rag_and_labeled_wsl(wshd, nbh, nbasins);
00218 }
00219
00220 }
00221
00222
00223
00224
00225
00226 template <typename I, typename N>
00227 inline
00228 util::couple<util::graph,mln_concrete(I)>
00229 rag_and_labeled_wsl(const Image<I>& wshd,
00230 const Neighborhood<N>& nbh,
00231 const mln_value(I)& nbasins)
00232 {
00233 trace::entering("make::rag_and_labeled_wsl");
00234
00235 internal::rag_and_labeled_wsl_tests(wshd, nbh, nbasins);
00236
00237 util::couple<util::graph,mln_concrete(I)>
00238 result = internal::rag_and_labeled_wsl_dispatch(wshd, nbh, nbasins);
00239
00240 trace::exiting("make::rag_and_labeled_wsl");
00241 return result;
00242 }
00243
00244
00245 # endif // ! MLN_INCLUDE_ONLY
00246
00247
00248 }
00249
00250 }
00251
00252
00253 #endif // ! MLN_MAKE_RAG_AND_LABELED_WSL_HH