$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
compute_parent.hh
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_MORPHO_TREE_COMPUTE_PARENT_HH
27 # define MLN_MORPHO_TREE_COMPUTE_PARENT_HH
28 
39 
40 # include <mln/core/concept/image.hh>
41 # include <mln/core/concept/neighborhood.hh>
42 # include <mln/data/fill.hh>
43 
44 
45 
46 namespace mln
47 {
48 
49  namespace morpho
50  {
51 
52  namespace tree
53  {
54 
127  template <typename I, typename N, typename S>
128  mln_ch_value(I, mln_psite(I))
129  compute_parent(const Image<I>& f, const Neighborhood<N>& nbh,
130  const Site_Set<S>& s);
131 
132 
133 
134 # ifndef MLN_INCLUDE_ONLY
135 
136 
137  // Tests.
138 
139 
140  namespace internal
141  {
142 
143  template <typename I, typename N, typename S>
144  void
145  compute_parent_tests(const Image<I>& f_,
146  const Neighborhood<N>& nbh_,
147  const Site_Set<S>& s_)
148  {
149  const I& f = exact(f_);
150  const N& nbh = exact(nbh_);
151  const S& s = exact(s_);
152 
153  mln_precondition(f.is_valid());
154  mln_precondition(nbh.is_valid());
155  mln_precondition(s == f.domain());
156 
157  (void) f;
158  (void) nbh;
159  (void) s;
160  }
161 
162 
163  // Z-Find-Root.
164 
165  template <typename T>
166  inline
167  mln_psite(T)
168  zfind_root(T& zpar, const mln_psite(T)& x)
169  {
170  mlc_equal(mln_value(T), mln_psite(T))::check();
171  if (zpar(x) == x)
172  return x;
173  else
174  return zpar(x) = zfind_root(zpar, zpar(x));
175  }
176 
177  } // end of namespace mln::morpho::tree::internal
178 
179 
180 
181  // Implementations.
182 
183 
184  namespace impl
185  {
186 
187  namespace generic
188  {
189 
190  template <typename I, typename N, typename S>
191  inline
192  mln_ch_value(I, mln_psite(I))
193  compute_parent(const Image<I>& f_,
194  const Neighborhood<N>& nbh_,
195  const Site_Set<S>& s_)
196  {
197  mln_trace("morpho::tree::impl::generic::compute_parent");
198 
199  typedef mln_psite(I) P;
200 
201  const I& f = exact(f_);
202  const N& nbh = exact(nbh_);
203  const S& s = exact(s_);
204 
205  // Tests.
206  internal::compute_parent_tests(f, nbh, s);
207 
208  // Auxiliary data.
209  mln_ch_value(I, bool) deja_vu;
210  mln_ch_value(I, P) parent;
211  mln_ch_value(I, P) zpar;
212 
213  initialize(deja_vu, f);
214  initialize(parent, f);
215  initialize(zpar, f);
216 
217  // Initialization.
218  data::fill(deja_vu, false);
219 
220  // Body.
221  mln_bkd_piter(S) p(s); // Backward.
222  mln_niter(N) n(nbh, p);
223  for_all(p)
224  {
225  // Make-Set.
226  parent(p) = p;
227  zpar(p) = p;
228 
229  for_all(n)
230  if (f.domain().has(n) && deja_vu(n))
231  {
232  // Do-Union.
233  P r = internal::zfind_root(zpar, n);
234  if (r != p)
235  {
236  parent(r) = p;
237  zpar(r) = p;
238  }
239  }
240  deja_vu(p) = true;
241  }
242 
243  // Canonization.
244  {
245  mln_fwd_piter(S) p(s); // Forward.
246  for_all(p)
247  {
248  P q = parent(p);
249  if (f(parent(q)) == f(q))
250  parent(p) = parent(q);
251  }
252  }
253 
254  return parent;
255  }
256 
257  } // end of namespace mln::morpho::tree::impl::generic
258 
259  } // end of namespace mln::morpho::tree::impl
260 
261 
262  // Dispatch.
263 
264  namespace internal
265  {
266 
267  template <typename I, typename N, typename S>
268  inline
269  mln_ch_value(I, mln_psite(I))
270  compute_parent_dispatch(const Image<I>& f,
271  const Neighborhood<N>& nbh,
272  const Site_Set<S>& s)
273  {
274  return impl::generic::compute_parent(f, nbh, s);
275  }
276 
277  } // end of namespace mln::morpho::tree::internal
278 
279 
280  // Facade.
281 
282  template <typename I, typename N, typename S>
283  inline
284  mln_ch_value(I, mln_psite(I))
285  compute_parent(const Image<I>& f, const Neighborhood<N>& nbh,
286  const Site_Set<S>& s)
287  {
288  mln_trace("morpho::tree::compute_parent");
289 
290  internal::compute_parent_tests(f, nbh, s);
291 
292  mln_ch_value(I, mln_psite(I)) output;
293  output = internal::compute_parent_dispatch(f, nbh, s);
294 
295  return output;
296  }
297 
298 # endif // ! MLN_INCLUDE_ONLY
299 
300  } // end of namespace mln::morpho::tree
301 
302  } // end of namespace mln::morpho
303 
304 } // end of namespace mln
305 
306 
307 #endif // ! MLN_MORPHO_TREE_COMPUTE_PARENT_HH