26 #ifndef MLN_DATA_MEDIAN_HH
27 # define MLN_DATA_MEDIAN_HH
35 # include <mln/core/concept/image.hh>
36 # include <mln/core/window.hh>
37 # include <mln/core/alias/dpoint2d.hh>
39 # include <mln/win/shift.hh>
40 # include <mln/win/diff.hh>
41 # include <mln/win/line.hh>
43 # include <mln/canvas/browsing/snake_fwd.hh>
44 # include <mln/accu/stat/median_h.hh>
45 # include <mln/accu/transform_line.hh>
62 template <
typename I,
typename W>
64 median(const Image<I>& input, const Window<W>& win);
68 # ifndef MLN_INCLUDE_ONLY
73 template <
typename I,
typename W>
75 median_tests(
const Image<I>& input,
const Window<W>& win)
77 mln_precondition(exact(input).is_valid());
78 mln_precondition(exact(win).is_valid());
92 template <
typename I,
typename W,
typename O>
95 typedef mln_psite(I) P;
96 typedef mln_dpsite(P) D;
106 accu::stat::median_h<mln_value(I)> med;
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;
114 median_t(const I& input_, const W& win_, O& output_)
117 input(exact(input_)),
119 output(exact(output_)),
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)
141 p = input.domain().pmin() +
up;
142 mln_qiter(W) q(win, p);
143 for_all(q) if (input.has(q))
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();
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();
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();
184 template <
typename I,
typename W>
187 median(const Image<I>& input, const Window<W>& win)
189 trace::entering(
"data::impl::generic::median");
191 mlc_equal(mln_trait_image_quant(I),
192 trait::image::quant::low)::check();
193 internal::median_tests(input, win);
197 typedef mln_concrete(I) O;
200 median_t<I,W,O> f(exact(input), exact(win), output);
201 canvas::browsing::snake_fwd(f);
203 trace::exiting("
data::impl::generic::
median");
210 template <typename I,
211 typename M,
unsigned i, typename C>
214 median_line(const Image<I>& input, const win::line<M,i,C>& win)
216 trace::entering(
"data::impl::median_line");
218 mlc_equal(mln_trait_image_quant(I),
219 trait::image::quant::low)::check();
220 internal::median_tests(input, win);
222 accu::stat::median_h<mln_value(I)> a;
223 mln_concrete(I) output = accu::transform_line(a, input, win.length(), i);
225 trace::exiting("
data::impl::median_line");
237 template <
typename I,
typename W>
240 median_dispatch_wrt_win(const Image<I>& input, const Window<W>& win)
242 return impl::generic::median(input, win);
245 template <
typename I,
246 typename M,
unsigned i,
typename C>
249 median_dispatch_wrt_win(const Image<I>& input, const win::line<M,i,C>& win)
251 return impl::median_line(input, win);
255 template <
typename I,
typename W>
258 median_dispatch(const Image<I>& input, const Window<W>& win)
260 return median_dispatch_wrt_win(input, exact(win));
268 template <
typename I,
typename W>
272 trace::entering(
"data::median");
274 mlc_equal(mln_trait_image_quant(I),
275 trait::image::quant::low)::check();
277 internal::median_tests(input, win);
278 mln_concrete(I) output;
279 output = internal::median_dispatch(input, win);
281 trace::exiting(
"data::median");
285 # endif // ! MLN_INCLUDE_ONLY
292 #endif // ! MLN_DATA_MEDIAN_HH