Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 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 } // end of namespace data::internal 00084 00085 00086 namespace impl 00087 { 00088 00089 // Functors. 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 // i/o 00099 00100 const I& input; 00101 const W& win; 00102 O& output; 00103 00104 // aux data 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 // ctor 00112 00113 inline 00114 median_t(const I& input_, const W& win_, O& output_) 00115 : 00116 // i/o 00117 input(exact(input_)), 00118 win(exact(win_)), 00119 output(exact(output_)), 00120 // aux data 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 // parts 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 }; // end of median_t 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 } // end of namespace mln::data::impl::generic 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 } // end of namespace mln::data::impl 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 } // end of namespace data::internal 00264 00265 00266 // Facade. 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 } // end of namespace mln::data 00288 00289 } // end of namespace mln 00290 00291 00292 #endif // ! MLN_DATA_MEDIAN_HH