Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 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_ELEMENTARY_GRADIENT_HH 00027 # define MLN_MORPHO_ELEMENTARY_GRADIENT_HH 00028 00032 00033 # include <mln/morpho/includes.hh> 00034 # include <mln/accu/stat/min_max.hh> 00035 00036 00037 namespace mln 00038 { 00039 00040 namespace morpho 00041 { 00042 00043 namespace elementary 00044 { 00045 00046 00047 template <typename I, typename N> 00048 mln_concrete(I) 00049 gradient(const Image<I>& input, const Neighborhood<N>& nbh); 00050 00051 00052 # ifndef MLN_INCLUDE_ONLY 00053 00054 namespace internal 00055 { 00056 00057 template <typename I, typename N> 00058 void 00059 gradient_tests(const Image<I>& input, const Neighborhood<N>& nbh) 00060 { 00061 mln_precondition(exact(input).is_valid()); 00062 mln_precondition(exact(nbh).is_valid()); 00063 (void) input; 00064 (void) nbh; 00065 } 00066 00067 } // end of namespace mln::morpho::elementary::tests 00068 00069 00070 namespace impl 00071 { 00072 00073 template <typename I, typename N> 00074 mln_concrete(I) 00075 gradient_on_function(const Image<I>& input_, const Neighborhood<N>& nbh_) 00076 { 00077 trace::entering("morpho::elementary::impl::gradient_on_function"); 00078 00079 const I& input = exact(input_); 00080 const N& nbh = exact(nbh_); 00081 internal::gradient_tests(input, nbh); 00082 00083 accu::stat::min_max<mln_value(I)> a; 00084 00085 extension::adjust_duplicate(input, nbh); 00086 00087 mln_concrete(I) output; 00088 initialize(output, input); 00089 00090 mln_piter(I) p(input.domain()); 00091 mln_niter(N) n(nbh, p); 00092 for_all(p) 00093 { 00094 a.take_as_init(input(p)); 00095 for_all(n) if (input.has(n)) 00096 a.take(input(n)); 00097 output(p) = a.second() - a.first(); 00098 } 00099 00100 trace::exiting("morpho::elementary::impl::gradient_on_function"); 00101 return output; 00102 } 00103 00104 template <typename I, typename N> 00105 mln_concrete(I) 00106 gradient_on_set(const Image<I>& input_, const Neighborhood<N>& nbh_) 00107 { 00108 trace::entering("morpho::elementary::impl::gradient_on_set"); 00109 00110 const I& input = exact(input_); 00111 const N& nbh = exact(nbh_); 00112 internal::gradient_tests(input, nbh); 00113 00114 extension::adjust_duplicate(input, nbh); 00115 00116 mln_concrete(I) output; 00117 initialize(output, input); 00118 data::fill(output, false); 00119 00120 mln_piter(I) p(input.domain()); 00121 mln_niter(N) n(nbh, p); 00122 for_all(p) 00123 if (input(p) == true) 00124 { 00125 for_all(n) if (input.has(n)) 00126 if (input(n) == false) 00127 { 00128 output(p) = true; 00129 break; 00130 } 00131 } 00132 else // input(p) == false 00133 { 00134 for_all(n) if (input.has(n)) 00135 if (input(n) == true) 00136 { 00137 output(p) = true; 00138 break; 00139 } 00140 } 00141 00142 trace::exiting("morpho::elementary::impl::gradient_on_set"); 00143 return output; 00144 } 00145 00146 00147 template <typename I, typename N> 00148 mln_concrete(I) 00149 gradient_on_function_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_) 00150 { 00151 trace::entering("morpho::elementary::impl::gradient_on_function_fastest"); 00152 00153 const I& input = exact(input_); 00154 const N& nbh = exact(nbh_); 00155 internal::gradient_tests(input, nbh); 00156 00157 accu::stat::min_max<mln_value(I)> a; 00158 extension::adjust_duplicate(input, nbh); 00159 00160 typedef mln_concrete(I) O; 00161 O output; 00162 initialize(output, input); 00163 00164 mln_pixter(const I) p_in(input); 00165 mln_pixter(O) p_out(output); 00166 mln_nixter(const I, N) n(p_in, nbh); 00167 for_all_2(p_in, p_out) 00168 { 00169 a.take_as_init(p_in.val()); 00170 for_all(n) 00171 a.take(n.val()); 00172 p_out.val() = a.second() - a.first(); 00173 } 00174 00175 trace::exiting("morpho::elementary::impl::gradient_on_function_fastest"); 00176 return output; 00177 } 00178 00179 } // end of namespace mln::morpho::elementary::impl 00180 00181 00182 namespace internal 00183 { 00184 00185 // Dispatch. 00186 00187 template <typename I, typename N> 00188 mln_concrete(I) 00189 gradient_dispatch(trait::image::kind::any, 00190 trait::image::speed::any, 00191 const Image<I>& input, const Neighborhood<N>& nbh) 00192 { 00193 return impl::gradient_on_function(input, nbh); 00194 } 00195 00196 template <typename I, typename N> 00197 mln_concrete(I) 00198 gradient_dispatch(trait::image::kind::any, 00199 trait::image::speed::fastest, 00200 const Image<I>& input, const Neighborhood<N>& nbh) 00201 { 00202 return impl::gradient_on_function_fastest(input, nbh); 00203 } 00204 00205 template <typename I, typename N> 00206 mln_concrete(I) 00207 gradient_dispatch(trait::image::kind::logic, 00208 trait::image::speed::any, 00209 const Image<I>& input, const Neighborhood<N>& nbh) 00210 { 00211 return impl::gradient_on_set(input, nbh); 00212 } 00213 00214 // May be redundant with the previous version but fixes an ambiguity 00215 // with image*d<bool> which is fasted AND logic. 00216 template <typename I, typename N> 00217 mln_concrete(I) 00218 gradient_dispatch(trait::image::kind::logic, 00219 trait::image::speed::fastest, 00220 const Image<I>& input, const Neighborhood<N>& nbh) 00221 { 00222 return impl::gradient_on_set(input, nbh); 00223 } 00224 00225 template <typename I, typename N> 00226 mln_concrete(I) 00227 gradient_dispatch(const Image<I>& input, const Neighborhood<N>& nbh) 00228 { 00229 return gradient_dispatch(mln_trait_image_kind(I)(), 00230 mln_trait_image_speed(I)(), 00231 input, nbh); 00232 } 00233 00234 } // end of namespace mln::morpho::elementary::internal 00235 00236 00237 // Facade. 00238 00239 template <typename I, typename N> 00240 mln_concrete(I) 00241 gradient(const Image<I>& input, const Neighborhood<N>& nbh) 00242 { 00243 trace::entering("morpho::elementary::gradient"); 00244 00245 internal::gradient_tests(input, nbh); 00246 mln_concrete(I) output = internal::gradient_dispatch(input, nbh); 00247 00248 trace::exiting("morpho::elementary::gradient"); 00249 return output; 00250 } 00251 00252 # endif // ! MLN_INCLUDE_ONLY 00253 00254 } // end of namespace mln::morpho::elementary 00255 00256 } // end of namespace mln::morpho 00257 00258 } // end of namespace mln 00259 00260 00261 #endif // ! MLN_MORPHO_ELEMENTARY_GRADIENT_HH