$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
sauvola_ms_functor.hh
1 // Copyright (C) 2009, 2010, 2011, 2012, 2013 EPITA Research and
2 // Development 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 SCRIBO_BINARIZATION_INTERNAL_SAUVOLA_MS_FUNCTOR_HH
28 # define SCRIBO_BINARIZATION_INTERNAL_SAUVOLA_MS_FUNCTOR_HH
29 
33 
34 # include <mln/core/image/image2d.hh>
35 # include <mln/core/alias/neighb2d.hh>
36 # include <mln/extension/fill.hh>
37 # include <mln/value/int_u8.hh>
38 # include <mln/data/fill.hh>
39 
40 # include <scribo/binarization/internal/sauvola_formula.hh>
41 
42 # ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
43 # include <scribo/binarization/internal/local_threshold_debug.hh>
44 # endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
45 
46 #include <mln/value/int_u8.hh>
47 
48 namespace scribo
49 {
50 
51  namespace binarization
52  {
53 
54  namespace internal
55  {
56 
57  extern double k2;
58  extern double k3;
59  extern double k4;
60 
61 
62  using namespace mln;
63 
64 
65  template <typename I>
67  {
68  const I& input;
69 
70  const image2d<value::int_u8>& e_2;
71  unsigned i;
72  unsigned q;
73 
74  mln_fwd_pixter(const I) pxl;
75  double res;
76  image2d<unsigned> parent;
77  image2d<unsigned> card;
78  image2d<bool> msk;
80 
81 # ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
82  image2d<bool> full_msk;
83 # endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
84 
85  unsigned n_nbhs;
87 
88  double K_;
89  double R_;
90  int i_;
91 
92  sauvola_formula formula_;
93 
94  sauvola_ms_functor(const I& input, double R,
95  const image2d<value::int_u8>&e_2,
96  unsigned i, unsigned q);
97 
98  void init();
99  void exec(double mean, double stddev);
100  void end_of_row(int row);
101  void finalize();
102 
103  };
104 
105 
106 # ifndef MLN_INCLUDE_ONLY
107 
108 
109 # ifndef MLN_WO_GLOBAL_VARS
110 
111  double k2 = SCRIBO_DEFAULT_SAUVOLA_K;
112  double k3 = SCRIBO_DEFAULT_SAUVOLA_K;
113  double k4 = SCRIBO_DEFAULT_SAUVOLA_K;
114 
115 # endif // ! MLN_WO_GLOBAL_VARS
116 
117 
118  inline
119  unsigned my_find_root(image2d<unsigned>& parent, unsigned x)
120  {
121  if (parent.element(x) == x)
122  return x;
123  return parent.element(x) = my_find_root(parent,
124  parent.element(x));
125  }
126 
127 
128  template <typename I>
129  sauvola_ms_functor<I>::sauvola_ms_functor(const I& input,
130  double R,
131  const image2d<value::int_u8>&e_2,
132  unsigned i, unsigned q)
133  : input(input),
134  e_2(e_2),
135  i(i),
136  q(q),
137  pxl(input),
138  R_(R),
139  i_(i)
140  {
141  mln_precondition(exact(input).is_valid());
142  mln_precondition(R > 0.);
143  mln_precondition(e_2.is_valid());
144  mln_precondition(q > 0);
145  mln_precondition(i > 1);
146 
147  res = 0;
148  pxl.start();
149 
150  initialize(t_sub, input);
151  initialize(parent, input);
152  initialize(msk, input);
153 
154 # ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
155  initialize(full_msk, input);
156  mln::extension::fill(full_msk, false);
157  initialize(debug_mean, input);
158  initialize(debug_stddev, input);
159 # endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
160 
161  mln::extension::fill(msk, false);
162 
163  initialize(card, input);
164  data::fill(card, 1);
165 
166  dp = negative_offsets_wrt(input, c8());
167  n_nbhs = dp.nelements();
168 
169  if (i == 2)
170  K_ = binarization::internal::k2;
171  else if (i == 3)
172  K_ = binarization::internal::k3;
173  else
174  K_ = binarization::internal::k4;
175  }
176 
177 
178  template <typename I>
179  void
180  sauvola_ms_functor<I>::init()
181  {
182  }
183 
184 
185  template <typename I>
186  void
187  sauvola_ms_functor<I>::exec(double mean, double stddev)
188  {
189  mln_precondition(pxl.is_valid());
190 
191  unsigned p = pxl.offset();
192 
193  value::int_u8 t_p;
194  mln::convert::from_to(formula_(mean, stddev, K_, R_), t_p);
195 
196  msk.element(p) = input.element(p) < t_p;
197 
198 # ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
199  full_msk.element(p) = msk.element(p);
200 # endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
201 
202  t_sub.element(p) = t_p;
203  if (! msk.element(p))
204  {
205  pxl.next();
206  return;
207  }
208  parent.element(p) = p;
209  for (unsigned i = 0; i < n_nbhs; ++i)
210  {
211  unsigned n = p + dp[i];
212  if (! msk.element(n))
213  continue;
214  unsigned r = my_find_root(parent, n);
215  if (r != p)
216  {
217  parent.element(r) = p;
218  card.element(p) += card.element(r);
219  }
220  }
221 
222  pxl.next(); // next pixel
223  }
224 
225 
226  template <typename I>
227  void
228  sauvola_ms_functor<I>::end_of_row(int row)
229  {
230  (void) row;
231  }
232 
233  template <typename I>
234  void sauvola_ms_functor<I>::finalize()
235  {
236  mln_assertion(! pxl.is_valid());
237  }
238 
239 #endif // ! MLN_INCLUDE_ONLY
240 
241  } // end of namespace scribo::binarization::internal
242 
243  } // end of namespace scribo::binarization
244 
245 } // end of namespace scribo
246 
247 #endif // SCRIBO_BINARIZATION_INTERNAL_SAUVOLA_MS_FUNCTOR_HH