$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
connectivity_number_3d.hh
1 // Copyright (C) 2011 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_TOPO_CONNECTIVITY_NUMBER_3D_HH
27 # define MLN_TOPO_CONNECTIVITY_NUMBER_3D_HH
28 
31 
32 # include <set>
33 
34 # include <mln/core/concept/image.hh>
35 
36 # include <mln/value/int_u8.hh>
37 # include <mln/value/int_u32.hh>
38 
39 # include <mln/core/alias/neighb3d.hh>
40 # include <mln/make/box3d.hh>
41 
42 # include <mln/core/image/image3d.hh>
43 # include <mln/core/image/vmorph/fun_image.hh>
44 # include <mln/core/image/dmorph/image_if.hh>
45 # include <mln/fun/v2b/lnot.hh>
46 # include <mln/labeling/blobs.hh>
47 
48 # include <mln/math/abs.hh>
49 
50 
51 namespace mln
52 {
53 
54  namespace topo
55  {
56 
65 
68 
69 
86  template <typename I>
88  connectivity_number_3d_c6(const Image<I>& ima, const mln_psite(I)& p,
89  bool ref_val);
90 
103  template <typename I>
105  connectivity_number_3d_c26(const Image<I>& ima, const mln_psite(I)& p,
106  bool ref_val);
107 
124  template <typename I>
126  connectivity_number_3d_c6p(const Image<I>& ima, const mln_psite(I)& p,
127  bool ref_val);
128 
141  template <typename I>
143  connectivity_number_3d_c18(const Image<I>& ima, const mln_psite(I)& p,
144  bool ref_val);
145 
146 
147 
148 # ifndef MLN_INCLUDE_ONLY
149 
150  /* FIXME: Maybe we could implement these computations in a faster
151  way using a mask (using an image_if morpher), instead of
152  creating a small 3x3x3 image ? */
153 
154  namespace internal
155  {
156 
161  template<typename I>
162  inline
163  mln_concrete(I)
164  local_configuration(const Image<I>& ima_, const mln_psite(I)& p,
165  bool ref_val)
166  {
167  const I& ima = exact(ima_);
168 
169  box3d b = make::box3d(-1,-1,-1, 1,1,1);
170  mln_concrete(I) ima_local(b, 0);
171  data::fill(ima_local, false);
172  point3d center(0, 0, 0);
173  mln_niter(neighb3d) n_ima(c26(), p);
174  mln_niter(neighb3d) n_local(c26(), center);
175  for_all_2(n_ima, n_local)
176  if (ima.has(n_ima) && ima(n_ima) == ref_val)
177  ima_local(n_local) = true;
178  return ima_local;
179  }
180 
181 
185  bool
186  f_within_c18(const point3d& p)
187  {
188  return !(math::abs(p.sli()) == 1
189  && math::abs(p.row()) == 1
190  && math::abs(p.col()) == 1);
191  }
192 
194  struct within_c18 : Function_v2b<within_c18>
195  {
196  typedef bool result;
197  bool operator()(const point3d& p) const { return f_within_c18(p); }
198  };
199  }
200 
201 
202  template<typename I>
203  inline
205  connectivity_number_3d_c6(const Image<I>& ima, const mln_psite(I)& p,
206  bool ref_val)
207  {
208  /* FIXME: Not compatible with proxy/morphers on values. */
209  mlc_equal(mln_value(I), bool)::check();
210 
211  mln_concrete(I) ima_local =
212  internal::local_configuration(ima, p, ref_val);
213 
214  // Create a copy of mln::c6()'s own neighborhood to avoid
215  // thread-unsafe accesses to this neighborhood.
216  neighb3d nbh = c6();
217  conn_number_t unused_nl;
218  // Restrict the image to the 18-c neighborhood of P.
219  image_if<image3d<conn_number_t>, internal::within_c18> lab =
220  labeling::blobs(ima_local | internal::within_c18(),
221  nbh, unused_nl);
222  std::set<conn_number_t> s;
223  point3d center(0, 0, 0);
224  mln_niter(neighb3d) n(nbh, center);
225  for_all(n)
226  if (lab(n) != 0)
227  s.insert(lab(n));
228  return s.size();
229  }
230 
231  template<typename I>
232  inline
233  conn_number_t
234  connectivity_number_3d_c26(const Image<I>& ima, const mln_psite(I)& p,
235  bool ref_val)
236  {
237  /* FIXME: Not compatible with proxy/morphers on values. */
238  mlc_equal(mln_value(I), bool)::check();
239 
240  mln_concrete(I) ima_local =
241  internal::local_configuration(ima, p, ref_val);
242 
243  // Create a copy of mln::c26()'s own neighborhood to avoid
244  // thread-unsafe accesses to this neighborhood.
245  neighb3d nbh = c26();
246  conn_number_t number;
247  labeling::blobs(ima_local, nbh, number);
248  return number;
249  }
250 
251  template<typename I>
252  inline
253  conn_number_t
254  connectivity_number_3d_c6p(const Image<I>& ima, const mln_psite(I)& p,
255  bool ref_val)
256  {
257  /* FIXME: Not compatible with proxy/morphers on values. */
258  mlc_equal(mln_value(I), bool)::check();
259 
260  mln_concrete(I) ima_local =
261  internal::local_configuration(ima, p, ref_val);
262 
263  // Create a copy of mln::c6()'s own neighborhood to avoid
264  // thread-unsafe accesses to this neighborhood.
265  neighb3d nbh = c6();
266  conn_number_t unused_nl;
267  image3d<conn_number_t> lab = labeling::blobs(ima_local, nbh, unused_nl);
268  std::set<conn_number_t> s;
269  point3d center(0, 0, 0);
270  mln_niter_(neighb3d) n(nbh, center);
271  for_all(n)
272  if (lab(n) != 0)
273  s.insert(lab(n));
274  return s.size();
275  }
276 
277  template<typename I>
278  inline
279  conn_number_t
280  connectivity_number_3d_c18(const Image<I>& ima, const mln_psite(I)& p,
281  bool ref_val)
282  {
283  /* FIXME: Not compatible with proxy/morphers on values. */
284  mlc_equal(mln_value(I), bool)::check();
285 
286  mln_concrete(I) ima_local =
287  internal::local_configuration(ima, p, ref_val);
288 
289  // Create a copy of mln::c18()'s own neighborhood to avoid
290  // thread-unsafe accesses to this neighborhood.
291  neighb3d nbh = c18();
292  conn_number_t unused_nl;
293  image3d<conn_number_t> lab = labeling::blobs(ima_local, nbh, unused_nl);
294  std::set<conn_number_t> s;
295  point3d center(0, 0, 0);
296  mln_niter_(neighb3d) n(nbh, center);
297  for_all(n)
298  if (lab(n) != 0)
299  s.insert(lab(n));
300  return s.size();
301  }
302 
303 # endif // MLN_INCLUDE_ONLY
304 
305  } // end of namespace mln::topo
306 
307 } // end of namespace mln
308 
309 #endif // ! MLN_TOPO_CONNECTIVITY_NUMBER_3D_HH