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_LINEAR_CONVOLVE_HH
00027 # define MLN_LINEAR_CONVOLVE_HH
00028
00032
00033 # include <mln/core/concept/image.hh>
00034 # include <mln/core/concept/weighted_window.hh>
00035 # include <mln/linear/ch_convolve.hh>
00036 # include <mln/accu/convolve.hh>
00037 # include <mln/extension/adjust_duplicate.hh>
00038
00039
00040 namespace mln
00041 {
00042
00043 namespace linear
00044 {
00045
00056 template <typename I, typename W>
00057 mln_ch_convolve(I, W)
00058 convolve(const Image<I>& input, const Weighted_Window<W>& w_win);
00059
00060
00061
00062 # ifndef MLN_INCLUDE_ONLY
00063
00064
00065
00066 namespace internal
00067 {
00068
00069 template <typename I, typename W>
00070 void
00071 convolve_tests(const Image<I>& input,
00072 const Weighted_Window<W>& w_win)
00073 {
00074 mln_precondition(exact(input).is_valid());
00075 mln_precondition(exact(w_win).is_valid());
00076 (void) input;
00077 (void) w_win;
00078 }
00079
00080 }
00081
00082
00083
00084
00085 namespace impl
00086 {
00087
00088 namespace generic
00089 {
00090
00091 template <typename I, typename W>
00092 mln_ch_convolve(I, W)
00093 convolve(const Image<I>& input_,
00094 const Weighted_Window<W>& w_win_)
00095 {
00096 trace::entering("linear::impl::generic::convolve");
00097
00098 const I& input = exact(input_);
00099 const W& w_win = exact(w_win_);
00100 internal::convolve_tests(input, w_win);
00101
00102 extension::adjust_duplicate(input, w_win);
00103
00104 typedef mln_ch_convolve(I, W) O;
00105 O output;
00106 initialize(output, input);
00107
00108 accu::convolve<mln_value(I), mln_weight(W)> a;
00109
00110 mln_piter(I) p(input.domain());
00111 mln_qiter(W) q(w_win, p);
00112
00113 for_all(p)
00114 {
00115 a.init();
00116 for_all(q) if (input.has(q))
00117 a.take(input(q), q.w());
00118 output(p) = a.to_result();
00119 }
00120
00121 trace::exiting("linear::impl::generic::convolve");
00122 return output;
00123 }
00124
00125 }
00126
00127
00128 template <typename I, typename W>
00129 mln_ch_convolve(I, W)
00130 convolve_fastest(const Image<I>& input_,
00131 const Weighted_Window<W>& w_win_)
00132 {
00133 trace::entering("linear::impl::convolve_fastest");
00134
00135 const I& input = exact(input_);
00136 const W& w_win = exact(w_win_);
00137 internal::convolve_tests(input, w_win);
00138
00139 extension::adjust_duplicate(input, w_win);
00140
00141 typedef mln_ch_convolve(I, W) O;
00142 O output;
00143 initialize(output, input);
00144 mln_pixter(O) p_out(output);
00145
00146 accu::convolve<mln_value(I), mln_weight(W)> a;
00147
00148 mln_pixter(const I) p(input);
00149 mln_qixter(const I, W) q(p, w_win);
00150
00151 for_all_2(p, p_out)
00152 {
00153 a.init();
00154 unsigned i = 0;
00155 for_all(q)
00156 a.take(q.val(), w_win.w(i++));
00157 p_out.val() = a.to_result();
00158 }
00159
00160 trace::exiting("linear::impl::convolve_fastest");
00161 return output;
00162 }
00163
00164 }
00165
00166
00167
00168
00169 namespace internal
00170 {
00171
00172 template <typename I, typename W>
00173 mln_ch_convolve(I, W)
00174 convolve_dispatch(trait::image::speed::any,
00175 const Image<I>& input,
00176 const Weighted_Window<W>& w_win)
00177 {
00178 return impl::generic::convolve(input, w_win);
00179 }
00180
00181 template <typename I, typename W>
00182 mln_ch_convolve(I, W)
00183 convolve_dispatch(trait::image::speed::fastest,
00184 const Image<I>& input,
00185 const Weighted_Window<W>& w_win)
00186 {
00187 return impl::convolve_fastest(input, w_win);
00188 }
00189
00190 template <typename I, typename W>
00191 mln_ch_convolve(I, W)
00192 convolve_dispatch(const Image<I>& input,
00193 const Weighted_Window<W>& w_win)
00194 {
00195 return convolve_dispatch(mln_trait_image_speed(I)(),
00196 input, w_win);
00197 }
00198
00199 }
00200
00201
00202
00203
00204 template <typename I, typename W>
00205 mln_ch_convolve(I, W)
00206 convolve(const Image<I>& input, const Weighted_Window<W>& w_win)
00207 {
00208 trace::entering("linear::convolve");
00209
00210 internal::convolve_tests(input, w_win);
00211
00212 mln_ch_convolve(I, W) output;
00213 output = internal::convolve_dispatch(mln_trait_image_speed(I)(),
00214 input, w_win);
00215
00216 trace::exiting("linear::convolve");
00217 return output;
00218 }
00219
00220 # endif // ! MLN_INCLUDE_ONLY
00221
00222 }
00223
00224 }
00225
00226
00227 #endif // ! MLN_LINEAR_CONVOLVE_HH