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_WAS_MEDIAN_HH
00027 # define MLN_DATA_WAS_MEDIAN_HH
00028
00034 # include <mln/win/shift.hh>
00035 # include <mln/core/alias/window2d.hh>
00036
00037 # include <mln/geom/min_col.hh>
00038 # include <mln/geom/max_col.hh>
00039 # include <mln/geom/max_row.hh>
00040 # include <mln/geom/min_row.hh>
00041
00042 # include <mln/win/diff.hh>
00043 # include <mln/win/shift.hh>
00044
00045 # include <mln/data/median.hh>
00046 # include <mln/win/hline2d.hh>
00047
00048 # include <mln/opt/at.hh>
00049
00050 namespace mln
00051 {
00052
00053 namespace data
00054 {
00055
00056 namespace impl
00057 {
00058
00059
00060
00061
00062 template <typename I, typename W, typename O>
00063 void median_as_procedure(const I& input,
00064 const W& win,
00065 O& output)
00066 {
00067 mln_precondition(input.is_valid());
00068 mln_precondition(output.is_valid());
00069
00070 int
00071 min_row = geom::min_row(input), max_row = geom::max_row(input),
00072 min_col = geom::min_col(input), max_col = geom::max_col(input);
00073
00074 window2d
00075 win_fwd_plus = win - win::shift(win, left),
00076 win_fwd_minus = win::shift(win, left) - win,
00077 win_bkd_plus = win - win::shift(win, right),
00078 win_bkd_minus = win::shift(win, right) - win,
00079 win_bot = win - win::shift(win, up),
00080 win_top = win::shift(win, up) - win;
00081
00082 point2d p;
00083 mln_qiter(W)
00084 q_fp(win_fwd_plus, p), q_fm(win_fwd_minus, p),
00085 q_bp(win_bkd_plus, p), q_bm(win_bkd_minus, p),
00086 q_top(win_top, p), q_bot(win_bot, p);
00087
00088 accu::stat::median_h<mln_vset(I)> med(input.values());
00089
00090
00091
00092 p = input.bbox().pmin() + up;
00093 med.init();
00094 {
00095 mln_qiter(W) q(win, p);
00096 for_all(q) if (input.has(q))
00097 med.take(input(q));
00098 }
00099
00100 int& row = p.row();
00101 int& col = p.col();
00102 bool fwd = true;
00103
00104 mln_assertion(p.col() == min_col);
00105 mln_assertion(p.row() == min_row - 1);
00106
00107 for (row = min_row; row <= max_row; ++row)
00108 {
00109
00110 for_all(q_top) if (input.has(q_top))
00111 med.untake(input(q_top));
00112 for_all(q_bot) if (input.has(q_bot))
00113 med.take(input(q_bot));
00114 output(p) = med;
00115
00116 if (fwd)
00117
00118 while (col < max_col)
00119 {
00120 ++col;
00121 for_all(q_fm) if (input.has(q_fm))
00122 med.untake(input(q_fm));
00123 for_all(q_fp) if (input.has(q_fp))
00124 med.take(input(q_fp));
00125 output(p) = med;
00126 }
00127 else
00128
00129 while (col > min_col)
00130 {
00131 --col;
00132 for_all(q_bm) if (input.has(q_bm))
00133 med.untake(input(q_bm));
00134 for_all(q_bp) if (input.has(q_bp))
00135 med.take(input(q_bp));
00136 output(p) = med;
00137 }
00138
00139
00140 fwd = ! fwd;
00141 }
00142 }
00143
00144
00145
00146
00147
00148 template <typename I, typename O>
00149 void hmedian(const I& input, const win::hline2d& win, O& output)
00150 {
00151
00152 const int
00153 min_row = geom::min_row(input), max_row = geom::max_row(input),
00154 min_col = geom::min_col(input), max_col = geom::max_col(input);
00155 const unsigned half = win.length() / 2;
00156
00157 point2d p;
00158 int& row = p.row();
00159 int& col = p.col();
00160
00161 accu::stat::median_h<mln_vset(I)> med(input.values());
00162
00163 for (row = min_row; row <= max_row; ++row)
00164 {
00165 int ct, cu;
00166
00167
00168 med.init();
00169 for (ct = min_col; ct < min_col + half; ++ct)
00170 med.take(opt::at(input, row, ct));
00171
00172
00173 for (col = min_col; col <= min_col + half; ++col, ++ct)
00174 {
00175 med.take(opt::at(input, row, ct));
00176 output(p) = med;
00177 }
00178
00179
00180 cu = min_col;
00181 for (; col <= max_col - half; ++cu, ++col, ++ct)
00182 {
00183 med.take(opt::at(input, row, ct));
00184 med.untake(opt::at(input, row, cu));
00185 output(p) = med;
00186 }
00187
00188
00189 for (; col <= max_col; ++cu, ++col)
00190 {
00191 med.untake(opt::at(input, row, cu));
00192 output(p) = med;
00193 }
00194 }
00195
00196 }
00197
00198
00199
00200 }
00201
00202 }
00203
00204 }
00205
00206
00207 #endif // ! MLN_DATA_WAS_MEDIAN_HH