Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 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_APPROX_EROSION_HH 00027 # define MLN_MORPHO_APPROX_EROSION_HH 00028 00032 00033 # include <mln/morpho/approx/dilation.hh> 00034 # include <mln/logical/not.hh> 00035 00036 00037 00038 namespace mln 00039 { 00040 00041 namespace morpho 00042 { 00043 00044 namespace approx 00045 { 00046 00047 00048 template <typename I, typename W> 00049 mln_concrete(I) 00050 erosion(const Image<I>& input, const Window<W>& win); 00051 00052 00053 00054 # ifndef MLN_INCLUDE_ONLY 00055 00056 00057 // Implementations. 00058 00059 namespace impl 00060 { 00061 00062 00063 // By distance thresholding. 00064 00065 template <typename I> 00066 mln_concrete(I) 00067 erosion_by_distance_thresholding_2d(const Image<I>& input_, 00068 const Window< win::disk2d >& win_) 00069 { 00070 trace::entering("morpho::approx::impl::erosion_by_distance_thresholding_2d"); 00071 00072 const I& input = exact(input_); 00073 const win::disk2d& win = exact(win_); 00074 00075 mln_precondition(input.is_valid()); 00076 mln_precondition(win.is_valid()); 00077 00078 int ws[] = { 00, 11, 0, 11, 0, 00079 11, 7, 5, 7, 11, 00080 00, 5, 0, 5, 0, 00081 11, 7, 5, 7, 11, 00082 00, 11, 0, 11, 0 }; 00083 const unsigned coef = 5; 00084 00085 unsigned 00086 radius = coef * win.diameter() / 2, 00087 dmax = radius + 1; 00088 00089 00090 mln_concrete(I) background = logical::not_(input); 00091 mln_ch_value(I, unsigned) dmap = transform::distance_front(background, 00092 c4(), make::w_window2d_int(ws), 00093 dmax); 00094 mln_concrete(I) output; 00095 output = duplicate((pw::value(dmap) > pw::cst(radius)) | input.domain()); 00096 00097 trace::exiting("morpho::approx::impl::erosion_by_distance_thresholding_2d"); 00098 return output; 00099 } 00100 00101 00102 00103 template <typename I> 00104 mln_concrete(I) 00105 erosion_by_distance_thresholding_3d(const Image<I>& input_, 00106 const Window< win::sphere3d >& win_) 00107 { 00108 trace::entering("morpho::approx::impl::erosion_by_distance_thresholding_3d"); 00109 00110 const I& input = exact(input_); 00111 const win::sphere3d& win = exact(win_); 00112 00113 mln_precondition(input.is_valid()); 00114 mln_precondition(win.is_valid()); 00115 00116 int ws[] = { 00, 21, 00, 00117 21, 17, 21, 00118 00, 21, 00, 00119 00120 17, 12, 17, 00121 12, 00, 12, 00122 17, 12, 17, 00123 00124 00, 21, 00, 00125 21, 17, 21, 00126 00, 21, 00 }; 00127 const unsigned coef = 12; 00128 00129 unsigned 00130 radius = coef * win.diameter() / 2, 00131 dmax = radius + 1; 00132 00133 mln_concrete(I) background = logical::not_(input); 00134 mln_ch_value(I, unsigned) dmap = transform::distance_front(background, 00135 c6(), make::w_window3d_int(ws), 00136 dmax); 00137 mln_concrete(I) output; 00138 output = duplicate((pw::value(dmap) > pw::cst(radius)) | input.domain()); 00139 00140 trace::exiting("morpho::approx::impl::erosion_by_distance_thresholding_3d"); 00141 return output; 00142 } 00143 00144 00145 } // end of namespace mln::morpho::approx::impl 00146 00147 00148 00149 // Dispatch. 00150 00151 namespace internal 00152 { 00153 00154 template <typename I> 00155 mln_concrete(I) 00156 erosion_dispatch(trait::image::kind::logic, 00157 const I& input, 00158 const win::disk2d& win) 00159 { 00160 return impl::erosion_by_distance_thresholding_2d(input, win); 00161 } 00162 00163 template <typename I> 00164 mln_concrete(I) 00165 erosion_dispatch(trait::image::kind::logic, 00166 const I& input, 00167 const win::sphere3d& win) 00168 { 00169 return impl::erosion_by_distance_thresholding_3d(input, win); 00170 } 00171 00172 // Entry point. 00173 00174 template <typename I, typename W> 00175 mln_concrete(I) 00176 erosion_dispatch(const I& input, const W& win) 00177 { 00178 return erosion_dispatch(mln_trait_image_kind(I)(), 00179 input, win); 00180 } 00181 00182 } // end of namespace mln::morpho::approx::internal 00183 00184 00185 // Facade. 00186 00187 template <typename I, typename W> 00188 inline 00189 mln_concrete(I) 00190 erosion(const Image<I>& input, const Window<W>& win) 00191 { 00192 trace::entering("morpho::approx::erosion"); 00193 00194 mln_precondition(exact(input).is_valid()); 00195 mln_precondition(exact(win).is_valid()); 00196 00197 mln_concrete(I) output; 00198 output = internal::erosion_dispatch(exact(input), exact(win)); 00199 00200 if (exact(win).is_centered()) 00201 mln_postcondition(output <= input); 00202 00203 trace::exiting("morpho::approx::erosion"); 00204 return output; 00205 } 00206 00207 00208 # endif // ! MLN_INCLUDE_ONLY 00209 00210 } // end of namespace mln::morpho::approx 00211 00212 } // end of namespace mln::morpho 00213 00214 } // end of namespace mln 00215 00216 00217 #endif // ! MLN_MORPHO_APPROX_EROSION_HH