$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
canvas/labeling/blobs.hh
1 // Copyright (C) 2009, 2010, 2012, 2013 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_CANVAS_LABELING_BLOBS_HH
28 # define MLN_CANVAS_LABELING_BLOBS_HH
29 
34 
35 # include <mln/core/concept/image.hh>
36 # include <mln/core/concept/neighborhood.hh>
37 # include <mln/data/fill.hh>
38 # include <mln/core/site_set/p_queue_fast.hh>
39 
40 # include <mln/extension/fill.hh>
41 
42 # include <mln/util/pix.hh>
43 
44 namespace mln
45 {
46 
47  namespace canvas
48  {
49 
50  namespace labeling
51  {
52 
71  template <typename I, typename N, typename L, typename F>
72  mln_ch_value(I, L)
73  blobs(const Image<I>& input, const Neighborhood<N>& nbh,
74  L& nlabels, F& functor);
75 
76 
77 
78 # ifndef MLN_INCLUDE_ONLY
79 
80 
81  // Implementations.
82 
83  namespace impl
84  {
85 
86  // Generic implementation.
87 
88  namespace generic
89  {
90 
91  template <typename I, typename N, typename L, typename F>
92  mln_ch_value(I, L)
93  blobs(const Image<I>& input_, const N& nbh, L& nlabels, F& functor)
94  {
95  const I& input = exact(input_);
96 
97  typedef mln_psite(I) P;
98 
99  P cur;
100  mln_niter(N) n(nbh, cur);
101  p_queue_fast<P> qu;
102  const L zero = literal::zero;
103 
104  // Initialization.
105  nlabels = literal::zero;
106  typedef mln_ch_value(I, L) out_t;
107  out_t output;
108  initialize(output, input);
109  data::fill(output, zero);
110 
111  extension::fill(input, false);
112 
113  functor.init(); // <-- functor.init()
114 
115  // Loop.
116  mln_piter(I) p(input.domain());
117  for_all(p)
118  if (input(p) && output(p) == zero) // Object point, not labeled yet.
119  {
120  // Label this point component.
121  if (nlabels == mln_max(L))
122  {
123  mln_trace_warning("labeling aborted! Too many labels \
124 for this label type: nlabels > max(label_type).");
125 
126  return output;
127  }
128  ++nlabels;
129  functor.new_label(nlabels); // <-- functor.new_label()
130  mln_invariant(qu.is_empty());
131  qu.push(p);
132  output(p) = nlabels;
133  functor.process_p(p); // <-- functor.process_p()
134  // output(p) == nlabels
135  do
136  {
137  cur = qu.front();
138  qu.pop();
139  for_all(n) if (input.has(n))
140  if (input(n) && output(n) == zero)
141  {
142  mln_invariant(! qu.compute_has(n));
143  qu.push(n);
144  output(n) = nlabels;
145  functor.process_n(n); // <-- functor.process_n()
146  // output(n) == nlabels
147  }
148  }
149  while (! qu.is_empty());
150  }
151 
152  functor.finalize(); // <-- functor.finalize()
153 
154  return output;
155  }
156 
157  } // end of namespace mln::labeling::impl::generic
158 
159 
160 
161  } // end of namespace mln::canvas::labeling::impl
162 
163 
164  // Facade.
165 
166  template <typename I, typename N, typename L, typename F>
167  inline
168  mln_ch_value(I, L)
169  blobs(const Image<I>& input_, const Neighborhood<N>& nbh_,
170  L& nlabels, F& functor)
171  {
172  mln_trace("labeling::blobs");
173  mlc_equal(mln_trait_image_kind(I),
174  mln::trait::image::kind::binary)::check();
175  const I& input = exact(input_);
176  const N& nbh = exact(nbh_);
177  mln_precondition(input.is_valid());
178 
179  // The only implementation is the generic one.
180  mln_ch_value(I, L)
181  output = impl::generic::blobs(input, nbh, nlabels, functor);
182 
183  return output;
184  }
185 
186 
187 # endif // ! MLN_INCLUDE_ONLY
188 
189  } // end of namespace mln::canvas::labeling
190 
191  } // end of namespace mln::canvas
192 
193 } // end of namespace mln
194 
195 
196 #endif // ! MLN_CANVAS_LABELING_BLOBS_HH