00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_DATA_MEDIAN_HH
00027 # define MLN_DATA_MEDIAN_HH
00028
00034
00035 # include <mln/core/concept/image.hh>
00036 # include <mln/core/window.hh>
00037 # include <mln/core/alias/dpoint2d.hh>
00038
00039 # include <mln/win/shift.hh>
00040 # include <mln/win/diff.hh>
00041 # include <mln/win/line.hh>
00042
00043 # include <mln/canvas/browsing/snake_fwd.hh>
00044 # include <mln/accu/stat/median_h.hh>
00045 # include <mln/accu/transform_line.hh>
00046
00047
00048 namespace mln
00049 {
00050
00051 namespace data
00052 {
00053
00062 template <typename I, typename W>
00063 mln_concrete(I)
00064 median(const Image<I>& input, const Window<W>& win);
00065
00066
00067
00068 # ifndef MLN_INCLUDE_ONLY
00069
00070 namespace internal
00071 {
00072
00073 template <typename I, typename W>
00074 void
00075 median_tests(const Image<I>& input, const Window<W>& win)
00076 {
00077 mln_precondition(exact(input).is_valid());
00078 mln_precondition(exact(win).is_valid());
00079 (void) input;
00080 (void) win;
00081 }
00082
00083 }
00084
00085
00086 namespace impl
00087 {
00088
00089
00090
00091
00092 template <typename I, typename W, typename O>
00093 struct median_t
00094 {
00095 typedef mln_psite(I) P;
00096 typedef mln_dpsite(P) D;
00097
00098
00099
00100 const I& input;
00101 const W& win;
00102 O& output;
00103
00104
00105
00106 accu::stat::median_h<mln_value(I)> med;
00107 P p;
00108 window<D> win_fp, win_fm, win_bp, win_bm, win_dp, win_dm;
00109 mln_qiter(window<D>) q_fp, q_fm, q_bp, q_bm, q_dp, q_dm;
00110
00111
00112
00113 inline
00114 median_t(const I& input_, const W& win_, O& output_)
00115 :
00116
00117 input(exact(input_)),
00118 win(exact(win_)),
00119 output(exact(output_)),
00120
00121 med(),
00122 p(),
00123 win_fp(win - win::shift(win, left)),
00124 win_fm(win::shift(win, left) - win),
00125 win_bp(win - win::shift(win, right)),
00126 win_bm(win::shift(win, right) - win),
00127 win_dp(win - win::shift(win, up)),
00128 win_dm(win::shift(win, up) - win),
00129 q_fp(win_fp, p), q_fm(win_fm, p),
00130 q_bp(win_bp, p), q_bm(win_bm, p),
00131 q_dp(win_dp, p), q_dm(win_dm, p)
00132 {
00133 }
00134
00135
00136
00137 inline
00138 void init()
00139 {
00140 med.init();
00141 p = input.domain().pmin() + up;
00142 mln_qiter(W) q(win, p);
00143 for_all(q) if (input.has(q))
00144 med.take(input(q));
00145 }
00146
00147 inline
00148 void down()
00149 {
00150 for_all(q_dm) if (input.has(q_dm))
00151 med.untake(input(q_dm));
00152 for_all(q_dp) if (input.has(q_dp))
00153 med.take(input(q_dp));
00154 output(p) = med.to_result();
00155 }
00156
00157 inline
00158 void fwd()
00159 {
00160 for_all(q_fm) if (input.has(q_fm))
00161 med.untake(input(q_fm));
00162 for_all(q_fp) if (input.has(q_fp))
00163 med.take(input(q_fp));
00164 output(p) = med.to_result();
00165 }
00166
00167 inline
00168 void bkd()
00169 {
00170 for_all(q_bm) if (input.has(q_bm))
00171 med.untake(input(q_bm));
00172 for_all(q_bp) if (input.has(q_bp))
00173 med.take(input(q_bp));
00174 output(p) = med.to_result();
00175 }
00176
00177 };
00178
00179
00180
00181 namespace generic
00182 {
00183
00184 template <typename I, typename W>
00185 inline
00186 mln_concrete(I)
00187 median(const Image<I>& input, const Window<W>& win)
00188 {
00189 trace::entering("data::impl::generic::median");
00190
00191 mlc_equal(mln_trait_image_quant(I),
00192 trait::image::quant::low)::check();
00193 internal::median_tests(input, win);
00194
00195 extension::adjust(input, win);
00196
00197 typedef mln_concrete(I) O;
00198 O output;
00199 initialize(output, input);
00200 median_t<I,W,O> f(exact(input), exact(win), output);
00201 canvas::browsing::snake_fwd(f);
00202
00203 trace::exiting("data::impl::generic::median");
00204 return output;
00205 }
00206
00207 }
00208
00209
00210 template <typename I,
00211 typename M, unsigned i, typename C>
00212 inline
00213 mln_concrete(I)
00214 median_line(const Image<I>& input, const win::line<M,i,C>& win)
00215 {
00216 trace::entering("data::impl::median_line");
00217
00218 mlc_equal(mln_trait_image_quant(I),
00219 trait::image::quant::low)::check();
00220 internal::median_tests(input, win);
00221
00222 accu::stat::median_h<mln_value(I)> a;
00223 mln_concrete(I) output = accu::transform_line(a, input, win.length(), i);
00224
00225 trace::exiting("data::impl::median_line");
00226 return output;
00227 }
00228
00229
00230 }
00231
00232
00233
00234 namespace internal
00235 {
00236
00237 template <typename I, typename W>
00238 inline
00239 mln_concrete(I)
00240 median_dispatch_wrt_win(const Image<I>& input, const Window<W>& win)
00241 {
00242 return impl::generic::median(input, win);
00243 }
00244
00245 template <typename I,
00246 typename M, unsigned i, typename C>
00247 inline
00248 mln_concrete(I)
00249 median_dispatch_wrt_win(const Image<I>& input, const win::line<M,i,C>& win)
00250 {
00251 return impl::median_line(input, win);
00252 }
00253
00254
00255 template <typename I, typename W>
00256 inline
00257 mln_concrete(I)
00258 median_dispatch(const Image<I>& input, const Window<W>& win)
00259 {
00260 return median_dispatch_wrt_win(input, exact(win));
00261 }
00262
00263 }
00264
00265
00266
00267
00268 template <typename I, typename W>
00269 mln_concrete(I)
00270 median(const Image<I>& input, const Window<W>& win)
00271 {
00272 trace::entering("data::median");
00273
00274 mlc_equal(mln_trait_image_quant(I),
00275 trait::image::quant::low)::check();
00276
00277 internal::median_tests(input, win);
00278 mln_concrete(I) output;
00279 output = internal::median_dispatch(input, win);
00280
00281 trace::exiting("data::median");
00282 return output;
00283 }
00284
00285 # endif // ! MLN_INCLUDE_ONLY
00286
00287 }
00288
00289 }
00290
00291
00292 #endif // ! MLN_DATA_MEDIAN_HH