$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
median.hh
1 // Copyright (C) 2007, 2008, 2009, 2012 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_DATA_MEDIAN_HH
28 # define MLN_DATA_MEDIAN_HH
29 
35 
36 # include <mln/core/concept/image.hh>
37 # include <mln/core/window.hh>
38 # include <mln/core/alias/dpoint2d.hh>
39 
40 # include <mln/win/shift.hh>
41 # include <mln/win/diff.hh>
42 # include <mln/win/line.hh>
43 
44 # include <mln/canvas/browsing/snake_fwd.hh>
45 # include <mln/accu/stat/median_h.hh>
46 # include <mln/accu/transform_line.hh>
47 
48 
49 namespace mln
50 {
51 
52  namespace data
53  {
54 
65  template <typename I, typename W>
66  mln_concrete(I)
67  median(const Image<I>& input, const Window<W>& win);
68 
69 
70 
71 # ifndef MLN_INCLUDE_ONLY
72 
73  namespace internal
74  {
75 
76  template <typename I, typename W>
77  void
78  median_tests(const Image<I>& input, const Window<W>& win)
79  {
80  mln_precondition(exact(input).is_valid());
81  mln_precondition(exact(win).is_valid());
82  (void) input;
83  (void) win;
84  }
85 
86  } // end of namespace data::internal
87 
88 
89  namespace impl
90  {
91 
92  // Functors.
93 
94 
95  template <typename I, typename W, typename O>
96  struct median_t
97  {
98  typedef mln_psite(I) P;
99  typedef mln_dpsite(P) D;
100 
101  // i/o
102 
103  const I& input;
104  const W& win;
105  O& output;
106 
107  // aux data
108 
109  accu::stat::median_h<mln_value(I)> med;
110  P p;
111  window<D> win_fp, win_fm, win_bp, win_bm, win_dp, win_dm;
112  mln_qiter(window<D>) q_fp, q_fm, q_bp, q_bm, q_dp, q_dm;
113 
114  // ctor
115 
116  inline
117  median_t(const I& input_, const W& win_, O& output_)
118  :
119  // i/o
120  input(exact(input_)),
121  win(exact(win_)),
122  output(exact(output_)),
123  // aux data
124  med(),
125  p(),
126  win_fp(win - win::shift(win, left)),
127  win_fm(win::shift(win, left) - win),
128  win_bp(win - win::shift(win, right)),
129  win_bm(win::shift(win, right) - win),
130  win_dp(win - win::shift(win, up)),
131  win_dm(win::shift(win, up) - win),
132  q_fp(win_fp, p), q_fm(win_fm, p),
133  q_bp(win_bp, p), q_bm(win_bm, p),
134  q_dp(win_dp, p), q_dm(win_dm, p)
135  {
136  }
137 
138  // parts
139 
140  inline
141  void init()
142  {
143  med.init();
144  p = input.domain().pmin() + up;
145  mln_qiter(W) q(win, p);
146  for_all(q) if (input.has(q))
147  med.take(input(q));
148  }
149 
150  inline
151  void down()
152  {
153  for_all(q_dm) if (input.has(q_dm))
154  med.untake(input(q_dm));
155  for_all(q_dp) if (input.has(q_dp))
156  med.take(input(q_dp));
157  output(p) = med.to_result();
158  }
159 
160  inline
161  void fwd()
162  {
163  for_all(q_fm) if (input.has(q_fm))
164  med.untake(input(q_fm));
165  for_all(q_fp) if (input.has(q_fp))
166  med.take(input(q_fp));
167  output(p) = med.to_result();
168  }
169 
170  inline
171  void bkd()
172  {
173  for_all(q_bm) if (input.has(q_bm))
174  med.untake(input(q_bm));
175  for_all(q_bp) if (input.has(q_bp))
176  med.take(input(q_bp));
177  output(p) = med.to_result();
178  }
179 
180  }; // end of median_t
181 
182 
183 
184  namespace generic
185  {
186 
187  template <typename I, typename W>
188  inline
189  mln_concrete(I)
190  median(const Image<I>& input, const Window<W>& win)
191  {
192  mln_trace("data::impl::generic::median");
193 
194  mlc_equal(mln_trait_image_quant(I),
195  trait::image::quant::low)::check();
196  internal::median_tests(input, win);
197 
198  extension::adjust(input, win);
199 
200  typedef mln_concrete(I) O;
201  O output;
202  initialize(output, input);
203  median_t<I,W,O> f(exact(input), exact(win), output);
204  canvas::browsing::snake_fwd(f);
205 
206  return output;
207  }
208 
209  } // end of namespace mln::data::impl::generic
210 
211 
212  template <typename I,
213  typename M, unsigned i, typename C>
214  inline
215  mln_concrete(I)
216  median_line(const Image<I>& input, const win::line<M,i,C>& win)
217  {
218  mln_trace("data::impl::median_line");
219 
220  mlc_equal(mln_trait_image_quant(I),
221  trait::image::quant::low)::check();
222  internal::median_tests(input, win);
223 
224  accu::stat::median_h<mln_value(I)> a;
225  mln_concrete(I) output = accu::transform_line(a, input, win.length(), i);
226 
227  return output;
228  }
229 
230 
231  } // end of namespace mln::data::impl
232 
233 
234 
235  namespace internal
236  {
237 
238  template <typename I, typename W>
239  inline
240  mln_concrete(I)
241  median_dispatch_wrt_win(const Image<I>& input, const Window<W>& win)
242  {
243  return impl::generic::median(input, win);
244  }
245 
246  template <typename I,
247  typename M, unsigned i, typename C>
248  inline
249  mln_concrete(I)
250  median_dispatch_wrt_win(const Image<I>& input, const win::line<M,i,C>& win)
251  {
252  return impl::median_line(input, win);
253  }
254 
255 
256  template <typename I, typename W>
257  inline
258  mln_concrete(I)
259  median_dispatch(const Image<I>& input, const Window<W>& win)
260  {
261  return median_dispatch_wrt_win(input, exact(win));
262  }
263 
264  } // end of namespace data::internal
265 
266 
267  // Facade.
268 
269  template <typename I, typename W>
270  mln_concrete(I)
271  median(const Image<I>& input, const Window<W>& win)
272  {
273  mln_trace("data::median");
274 
275  mlc_equal(mln_trait_image_quant(I),
276  trait::image::quant::low)::check();
277 
278  internal::median_tests(input, win);
279  mln_concrete(I) output;
280  output = internal::median_dispatch(input, win);
281 
282  return output;
283  }
284 
285 # endif // ! MLN_INCLUDE_ONLY
286 
287  } // end of namespace mln::data
288 
289 } // end of namespace mln
290 
291 
292 #endif // ! MLN_DATA_MEDIAN_HH