$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
enlarge.hh
1 // Copyright (C) 2009, 2011 EPITA Research and Development Laboratory
2 // (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_WORLD_BINARY_2D_ENLARGE_HH
28 # define MLN_WORLD_BINARY_2D_ENLARGE_HH
29 
35 
36 
37 # include <iostream>
38 
39 # include <mln/core/image/image2d.hh>
40 # include <mln/core/routine/initialize.hh>
41 
42 # include <mln/value/int_u8.hh>
43 # include <mln/fun/p2v/ternary.hh>
44 # include <mln/fun/v2b/threshold_ge.hh>
45 
46 # include <mln/data/transform.hh>
47 
48 # include <mln/pw/image.hh>
49 # include <mln/pw/cst.hh>
50 # include <mln/pw/value.hh>
51 # include <mln/opt/at.hh>
52 
53 # include <mln/geom/min_row.hh>
54 # include <mln/geom/min_col.hh>
55 
56 # include <mln/core/routine/duplicate.hh>
57 
58 #include <mln/debug/println.hh>
59 
60 namespace mln
61 {
62 
63  namespace world
64  {
65 
66  namespace binary_2d
67  {
68 
75  //
76  template <typename I>
77  mln_concrete(I)
78  enlarge(const Image<I>& input, unsigned n);
79 
80 
81 # ifndef MLN_INCLUDE_ONLY
82 
83 
84  // Internal routines.
85 
86  namespace internal
87  {
88 
89  inline
90  float
91  val(bool b)
92  {
93  return b ? 1 : 0;
94  }
95 
96  inline
97  int
98  do_threshold(float value)
99  {
100  return static_cast<int>(255.f * value);
101  }
102 
103  } // end of namespace mln::world::binary_2d
104 
105 
106 
107 
108  // Implementation.
109 
110  namespace impl
111  {
112 
114  inline
116  enlargex2(const image2d<bool>& input)
117  {
118  using value::int_u8;
119 
120  mln_precondition(input.is_valid());
121 
122  def::coord
123  mrow = geom::min_row(input),
124  mcol = geom::min_col(input);
125 
126  image2d<int_u8> output(make::box2d(mrow, mcol,
127  mrow + 2 * input.nrows() - 1,
128  mcol + 2 * input.ncols() - 1));
129  float value;
130 
131  // row 0
132  opt::at(output, mrow, mcol) = internal::do_threshold(opt::at(input, mrow, mcol));
133 
134  for (unsigned col = 2; col < output.ncols(); col += 2)
135  {
136  value = internal::val(opt::at(input, mrow, mcol + col / 2));
137  value += internal::val(opt::at(input, mrow, mcol + col / 2 - 1));
138  opt::at(output, mrow, mcol + col) = internal::do_threshold(value / 2);
139  }
140 
141  for (unsigned col = 1; col < output.ncols(); col += 2)
142  opt::at(output, mrow, mcol + col)
143  = internal::do_threshold(opt::at(input, mrow, mcol + col / 2));
144 
145  // col 0
146 
147  for (unsigned row = 2; row < output.nrows(); row += 2)
148  {
149  value = internal::val(opt::at(input, mrow + row / 2, mcol));
150  value += internal::val(opt::at(input, mrow + row / 2 - 1, mcol));
151  opt::at(output, mrow + row, mcol) = internal::do_threshold(value / 2);
152  }
153 
154  for (unsigned row = 1; row < output.nrows(); row += 2)
155  opt::at(output, mrow + row, mcol)
156  = internal::do_threshold(opt::at(input, mrow + row / 2, mcol));
157 
158  // others
159 
160  for (unsigned row = 2; row < output.nrows(); row += 2)
161  {
162  for (unsigned col = 2; col < output.ncols(); col += 2)
163  {
164  value = internal::val(opt::at(input, mrow + row / 2, mcol + col / 2));
165  value += internal::val(opt::at(input, mrow + row / 2 - 1, mcol + col / 2));
166  value += internal::val(opt::at(input, mrow + row / 2, mcol + col / 2 - 1));
167  value += internal::val(opt::at(input, mrow + row / 2 - 1, mcol + col / 2 - 1));
168  opt::at(output, mrow + row, mcol + col)
169  = internal::do_threshold(value / 4);
170  }
171  for (unsigned col = 1; col < output.ncols(); col += 2)
172  {
173  value = internal::val(opt::at(input, mrow + row / 2, mcol + col / 2));
174  value += internal::val(opt::at(input, mrow + row / 2 - 1, mcol + col / 2));
175  opt::at(output, mrow + row, mcol + col) = internal::do_threshold(value / 2);
176  }
177  }
178 
179  for (unsigned row = 1; row < output.nrows(); row += 2)
180  {
181  for (unsigned col = 2; col < output.ncols(); col += 2)
182  {
183  value = internal::val(opt::at(input, mrow + row / 2, mcol + col / 2));
184  value += internal::val(opt::at(input, mrow + row / 2, mcol + col / 2 - 1));
185  opt::at(output, mrow + row, mcol + col) = internal::do_threshold(value / 2);
186  }
187  for (unsigned col = 1; col < output.ncols(); col += 2)
188  opt::at(output, mrow + row, mcol + col)
189  = internal::do_threshold(opt::at(input, mrow + row / 2, mcol + col / 2));
190  }
191 
192  return output;
193  }
194 
195 
196 
197  inline
199  enlargex2(const image2d<value::int_u8>& input)
200  {
201  using value::int_u8;
202 
203  unsigned
204  mrow = geom::min_row(input),
205  mcol = geom::min_col(input);
206 
207  image2d<int_u8> output(make::box2d(mrow, mcol,
208  mrow + 2 * input.nrows() - 1,
209  mcol + 2 * input.ncols() - 1));
210  unsigned value;
211 
212  // row 0
213  opt::at(output, mrow, mcol) = (opt::at(input, mrow, mcol));
214 
215  for (unsigned col = 2; col < output.ncols(); col += 2)
216  {
217  value = (opt::at(input, mrow, mcol + col / 2));
218  value += (opt::at(input, mrow, mcol + col / 2 - 1));
219  opt::at(output, mrow, mcol + col) = (value / 2);
220  }
221 
222  for (unsigned col = 1; col < output.ncols(); col += 2)
223  opt::at(output, mrow, mcol + col) = (opt::at(input, mrow, mcol + col / 2));
224 
225  // col 0
226 
227  for (unsigned row = 2; row < output.nrows(); row += 2)
228  {
229  value = (opt::at(input, mrow + row / 2, mcol));
230  value += (opt::at(input, mrow + row / 2 - 1, mcol));
231  opt::at(output, mrow + row, mcol) = (value / 2);
232  }
233 
234  for (unsigned row = 1; row < output.nrows(); row += 2)
235  opt::at(output, mrow + row, mcol) = (opt::at(input, mrow + row / 2, mcol));
236 
237  // others
238 
239  for (unsigned row = 2; row < output.nrows(); row += 2)
240  {
241  for (unsigned col = 2; col < output.ncols(); col += 2)
242  {
243  value = (opt::at(input, mrow + row / 2, mcol + col / 2));
244  value += (opt::at(input, mrow + row / 2 - 1, mcol + col / 2));
245  value += (opt::at(input, mrow + row / 2, mcol + col / 2 - 1));
246  value += (opt::at(input, mrow + row / 2 - 1, mcol + col / 2 - 1));
247  opt::at(output, mrow + row, mcol + col) = ((unsigned(value)+2) / 4);
248  }
249  for (unsigned col = 1; col < output.ncols(); col += 2)
250  {
251  value = (opt::at(input, mrow + row / 2, mcol + col / 2));
252  value += (opt::at(input, mrow + row / 2 - 1, mcol + col / 2));
253  opt::at(output, mrow + row, mcol + col) = (value / 2);
254  }
255  }
256 
257  for (unsigned row = 1; row < output.nrows(); row += 2)
258  {
259  for (unsigned col = 2; col < output.ncols(); col += 2)
260  {
261  value = (opt::at(input, mrow + row / 2, mcol + col / 2));
262  value += (opt::at(input, mrow + row / 2, mcol + col / 2 - 1));
263  opt::at(output, mrow + row, mcol + col) = (value / 2);
264  }
265  for (unsigned col = 1; col < output.ncols(); col += 2)
266  opt::at(output, mrow + row, mcol + col)
267  = (opt::at(input, mrow + row / 2, mcol + col / 2));
268  }
269 
270  return output;
271  }
272 
273 
274  template <typename I>
275  inline
276  mln_ch_value(I,value::int_u8)
277  do_enlarge_gl(const I& input, unsigned n)
278  {
279  using value::int_u8;
280 
281  mln_ch_value(I,int_u8) output = enlargex2(input);
282 
283  while (--n)
284  output = enlargex2(output);
285 
286  return output;
287  }
288 
289 
290  template <typename I>
291  inline
292  mln_concrete(I)
293  do_enlarge_bool(const I& input, unsigned n)
294  {
295  mln_ch_value(I,value::int_u8) tmp = do_enlarge_gl(input, n);
296  debug::println(tmp);
297  I output
299  return output;
300  }
301 
302 
303  } // end of namespace mln::world::binary_2d::impl
304 
305 
306 
307 
308  // Dispatch
309 
310  namespace internal
311  {
312 
313  template<typename I>
314  inline
315  mln_concrete(I)
316  enlarge_dispatch(const I& input, const bool&, unsigned n)
317  {
318  return impl::do_enlarge_bool(input, n);
319  }
320 
321  template<typename I>
322  inline
323  mln_concrete(I)
324  enlarge_dispatch(const I& input, const value::int_u8&, unsigned n)
325  {
326  return impl::do_enlarge_gl(input, n);
327  }
328 
329  template<typename I>
330  inline
331  mln_concrete(I)
332  enlarge_dispatch(const I& input, const mln_value(I)&, unsigned n)
333  {
334  (void) input;
335  (void) n;
336 
337  mlc_abort(I)::check();
338  return mln_concrete(I)();
339  }
340 
341  template<typename I>
342  inline
343  mln_concrete(I)
344  enlarge_dispatch(const Image<I>& input, unsigned n)
345  {
346  return enlarge_dispatch(exact(input), mln_value(I)(), n);
347  }
348 
349  } // end of namespace mln::world::binary_2d::internal
350 
351 
352 
353  // Facade
354 
355  template <typename I>
356  inline
357  mln_concrete(I)
358  enlarge(const Image<I>& input, unsigned n)
359  {
360  mln_trace("mln::world::binary_2d::enlarge");
361 
362  mln_precondition(exact(input).is_valid());
363  typedef mln_site(I) S;
364  mlc_bool(S::dim == 2)::check();
365 
366  mln_concrete(I) output;
367  if (n == 0)
368  output = duplicate(input);
369  else
370  output = internal::enlarge_dispatch(input, n);
371 
372  return output;
373  }
374 
375 
376 # endif // ! MLN_INCLUDE_ONLY
377 
378  } // end of namespace mln::world::binary_2d
379 
380  } // end of namespace mln::world
381 
382 } // mln
383 
384 #endif // ! MLN_WORLD_BINARY_2D_ENLARGE_HH