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_FAST_MEDIAN_HH
00027 # define MLN_DATA_FAST_MEDIAN_HH
00028
00036 # include <mln/core/concept/image.hh>
00037 # include <mln/core/alias/window2d.hh>
00038 # include <mln/accu/stat/median_h.hh>
00039
00040 # include <mln/win/shift.hh>
00041 # include <mln/win/diff.hh>
00042
00043 # include <mln/geom/min_col.hh>
00044 # include <mln/geom/min_row.hh>
00045 # include <mln/geom/max_col.hh>
00046 # include <mln/geom/max_row.hh>
00047
00048
00049 namespace mln
00050 {
00051
00052 namespace data
00053 {
00054
00064 template <typename I, typename W, typename O>
00065 void fast_median(const Image<I>& input, const Window<W>& win,
00066 Image<O>& output);
00067
00068
00069 # ifndef MLN_INCLUDE_ONLY
00070
00071
00072 namespace impl
00073 {
00074
00075 template <typename I, typename W, typename O>
00076 inline
00077 void fast_median(const I& input,
00078 const W& win,
00079 O& output)
00080 {
00081 mln_precondition(input.is_valid());
00082 mln_precondition(output.is_valid());
00083
00084 def::coord
00085 min_row = geom::min_row(input), max_row = geom::max_row(input),
00086 min_col = geom::min_col(input), max_col = geom::max_col(input);
00087
00088 window2d
00089 win_fwd_plus = win - win::shift(win, left),
00090 win_fwd_minus = win::shift(win, left) - win,
00091 win_bkd_plus = win - win::shift(win, right),
00092 win_bkd_minus = win::shift(win, right) - win,
00093 win_bot = win - win::shift(win, up),
00094 win_top = win::shift(win, up) - win;
00095
00096 accu::stat::median_h<mln_value(I)> med;
00097
00098
00099
00100 point2d p = input.domain().pmin() + up;
00101
00102 mln_qixter(const I, window2d)
00103 q_fp(input, win_fwd_plus, p), q_fm(input, win_fwd_minus, p),
00104 q_bp(input, win_bkd_plus, p), q_bm(input, win_bkd_minus, p),
00105 q_top(input, win_top, p), q_bot(input, win_bot, p);
00106
00107 med.init();
00108 {
00109 mln_qixter(const I, W) q(input, win, p);
00110 for_all(q)
00111 med.take(q.val());
00112 }
00113
00114 def::coord& row = p.row();
00115 def::coord& col = p.col();
00116 bool fwd = true;
00117
00118 mln_assertion(p.col() == min_col);
00119 mln_assertion(p.row() == min_row - 1);
00120
00121 for (row = min_row; row <= max_row; ++row)
00122 {
00123
00124
00125 for_all(q_top)
00126 med.untake(q_top.val());
00127
00128 for_all(q_bot)
00129 med.take(q_bot.val());
00130
00131 output(p) = med;
00132
00133 if (fwd)
00134
00135 while (col < max_col)
00136 {
00137 ++col;
00138 for_all(q_fm)
00139 med.untake(q_fm.val());
00140 for_all(q_fp)
00141 med.take(q_fp.val());
00142 output(p) = med;
00143 }
00144 else
00145
00146 while (col > min_col)
00147 {
00148 --col;
00149 for_all(q_bm)
00150 med.untake(q_bm.val());
00151 for_all(q_bp)
00152 med.take(q_bp.val());
00153 output(p) = med;
00154 }
00155
00156 fwd = ! fwd;
00157 }
00158 }
00159
00160 }
00161
00162
00163
00164
00165 template <typename I, typename W, typename O>
00166 inline
00167 void fast_median(const Image<I>& input, const Window<W>& win,
00168 Image<O>& output)
00169 {
00170 impl::fast_median(exact(input), exact(win), exact(output));
00171 }
00172
00173 # endif // ! MLN_INCLUDE_ONLY
00174
00175 }
00176
00177 }
00178
00179
00180 #endif // ! MLN_DATA_FAST_MEDIAN_HH