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_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 // Tests. 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 } // end of namespace mln::morpho::internal 00078 00079 00080 00081 // Implementations. 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 //else 00116 // accu.take(mln_value(I)(literal::zero)); 00117 output(p) = accu; 00118 } 00119 00120 trace::exiting("morpho::impl::generic::rank_filter"); 00121 return output; 00122 } 00123 00124 } // end of namespace mln::morpho::impl::generic 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 } // end of namespace mln::morpho::impl 00164 00165 00166 00167 // Dispatch. 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 } // end of namespace mln::morpho::internal 00204 00205 00206 00207 // Facades. 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 } // end of namespace mln::morpho 00229 00230 } // end of namespace mln 00231 00232 00233 #endif // ! MLN_MORPHO_RANK_FILTER_HH