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