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_MORPHO_RANK_FILTER_HH
00027 # define MLN_MORPHO_RANK_FILTER_HH
00028
00034
00035 # include <mln/morpho/includes.hh>
00036 # include <mln/accu/transform_line.hh>
00037 # include <mln/convert/to_p_array.hh>
00038
00039
00040
00041 namespace mln
00042 {
00043
00044 namespace morpho
00045 {
00046
00048 template <typename I, typename W>
00049 mln_concrete(I)
00050 rank_filter(const Image<I>& input, const Window<W>& win, unsigned k);
00051
00052
00053 # ifndef MLN_INCLUDE_ONLY
00054
00055
00056
00057
00058
00059 namespace internal
00060 {
00061
00062 template <typename I, typename W>
00063 inline
00064 void
00065 rank_filter_tests(const Image<I>& input_, const Window<W>& win_, unsigned k)
00066 {
00067 const I& input = exact(input_);
00068 const W& win = exact(win_);
00069
00070 mln_precondition(input.is_valid());
00071 mln_precondition(! win.is_empty());
00072 (void) input;
00073 (void) win;
00074 (void) k;
00075 }
00076
00077 }
00078
00079
00080
00081
00082
00083
00084 namespace impl
00085 {
00086
00087 namespace generic
00088 {
00089
00090 template <typename I, typename W>
00091 inline
00092 mln_concrete(I)
00093 rank_filter(const Image<I>& input_, const Window<W>& win_, unsigned k)
00094 {
00095 trace::entering("morpho::impl::generic::rank_filter");
00096
00097 internal::rank_filter_tests(input_, win_, k);
00098
00099 const I& input = exact(input_);
00100 const W& win = exact(win_);
00101
00102 mln_concrete(I) output;
00103 initialize(output, input);
00104
00105 accu::stat::rank<mln_value(I)> accu(k);
00106 extension::adjust_fill(input, geom::delta(win) + 1, accu);
00107 mln_piter(I) p(input.domain());
00108 mln_qiter(W) q(win, p);
00109 for_all(p)
00110 {
00111 accu.init();
00112 for_all(q)
00113 if (input.has(q))
00114 accu.take(input(q));
00115
00116
00117 output(p) = accu;
00118 }
00119
00120 trace::exiting("morpho::impl::generic::rank_filter");
00121 return output;
00122 }
00123
00124 }
00125
00126
00127 template <typename I, typename W>
00128 inline
00129 mln_concrete(I)
00130 rank_filter_line(const Image<I>& input, const Window<W>& win, unsigned k, unsigned dir)
00131 {
00132 trace::entering("morpho::impl::rank_filter_line");
00133
00134 internal::rank_filter_tests(input, win, k);
00135
00136 accu::stat::rank<mln_value(I)> accu(k);
00137 extension::adjust_fill(input, geom::delta(win) + 1, accu);
00138 mln_concrete(I) output = accu::transform_line(accu, input, exact(win).length(), dir);
00139
00140 trace::exiting("morpho::impl::rank_filter_line");
00141 return output;
00142 }
00143
00144
00145 template <typename I, typename W>
00146 inline
00147 mln_concrete(I)
00148 rank_filter_directional(const Image<I>& input, const Window<W>& win, unsigned k, unsigned dir)
00149 {
00150 trace::entering("morpho::impl::rank_filter_directional");
00151
00152 internal::rank_filter_tests(input, win, k);
00153
00154 accu::stat::rank<mln_value(I)> accu(k);
00155 extension::adjust_fill(input, geom::delta(win) + 1, accu);
00156 mln_concrete(I) output = accu::transform_directional(accu, input, win, dir);
00157
00158 trace::exiting("morpho::impl::rank_filter_directional");
00159 return output;
00160 }
00161
00162
00163 }
00164
00165
00166
00167
00168
00169
00170 namespace internal
00171 {
00172
00173 template <typename I, typename M, unsigned i, typename C>
00174 inline
00175 mln_concrete(I)
00176 rank_filter_dispatch(const Image<I>& input, const win::line<M, i, C>& win, unsigned k)
00177 {
00178 return impl::rank_filter_line(input, win, k, i);
00179 }
00180
00181 template <typename I>
00182 inline
00183 mln_concrete(I)
00184 rank_filter_dispatch(const Image<I>& input, const win::rectangle2d& win, unsigned k)
00185 {
00186 if (win.height() <= 3 && win.width() <= 3)
00187 return impl::generic::rank_filter(input, win, k);
00188 else
00189 if (win.height() < win.width())
00190 return impl::rank_filter_directional(input, win, k, 1);
00191 else
00192 return impl::rank_filter_directional(input, win, k, 0);
00193 }
00194
00195 template <typename I, typename W>
00196 inline
00197 mln_concrete(I)
00198 rank_filter_dispatch(const Image<I>& input, const Window<W>& win, unsigned k)
00199 {
00200 return impl::generic::rank_filter(input, win, k);
00201 }
00202
00203 }
00204
00205
00206
00207
00208
00209
00210 template <typename I, typename W>
00211 inline
00212 mln_concrete(I)
00213 rank_filter(const Image<I>& input, const Window<W>& win, unsigned k)
00214 {
00215 trace::entering("morpho::rank_filter");
00216
00217 mln_precondition(exact(input).is_valid());
00218 mln_precondition(! exact(win).is_empty());
00219
00220 mln_concrete(I) output = internal::rank_filter_dispatch(exact(input), exact(win), k);
00221
00222 trace::exiting("morpho::rank_filter");
00223 return output;
00224 }
00225
00226 # endif // ! MLN_INCLUDE_ONLY
00227
00228 }
00229
00230 }
00231
00232
00233 #endif // ! MLN_MORPHO_RANK_FILTER_HH