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
00027 #ifndef MLN_MORPHO_EROSION_HH
00028 # define MLN_MORPHO_EROSION_HH
00029
00035
00036 # include <mln/morpho/general.hh>
00037 # include <mln/morpho/includes.hh>
00038 # include <mln/accu/logic/land.hh>
00039 # include <mln/accu/logic/land_basic.hh>
00040 # include <mln/accu/stat/min.hh>
00041 # include <mln/accu/stat/min_h.hh>
00042
00043
00044 namespace mln
00045 {
00046
00047 namespace morpho
00048 {
00049
00051 template <typename I, typename W>
00052 mln_concrete(I)
00053 erosion(const Image<I>& input, const Window<W>& win);
00054
00055
00056 # ifndef MLN_INCLUDE_ONLY
00057
00058 struct erosion_op
00059 {
00060
00061 template <typename I>
00062 mln_morpho_select_accu(I, logic::land_basic, stat::min)
00063 accu(const Image<I>&) const
00064 {
00065 mln_morpho_select_accu(I, logic::land_basic, stat::min) tmp;
00066 return tmp;
00067 }
00068
00069 template <typename I>
00070 mln_morpho_select_accu(I, logic::land, stat::min_h)
00071 accu_incr(const Image<I>&) const
00072 {
00073 mln_morpho_select_accu(I, logic::land, stat::min_h) tmp;
00074 return tmp;
00075 }
00076
00077 template <typename I>
00078 mln_value(I) neutral(const Image<I>&) const
00079 {
00080 return internal::neutral<I>::supremum();
00081 }
00082
00083 };
00084
00085
00086 namespace impl
00087 {
00088
00089
00090
00091
00092 template <typename I, typename W>
00093 mln_concrete(I)
00094 general_on_set_centered(const erosion_op&,
00095 const Image<I>& input_, const Window<W>& win_)
00096 {
00097 trace::entering("morpho::impl::general_on_set_centered__erosion");
00098
00099 typedef mln_concrete(I) O;
00100 const I& input = exact(input_);
00101 const W& win = exact(win_);
00102
00103 extension::adjust_fill(input, win, true);
00104
00105 O output;
00106 output = duplicate(input);
00107
00108 mln_piter(I) p(input.domain());
00109 mln_qiter(W) q(win, p);
00110 for_all(p)
00111 if (input(p) == true)
00112 for_all(q) if (input.has(q))
00113 if (input(q) == false)
00114 {
00115 output(p) = false;
00116 break;
00117 }
00118
00119 trace::exiting("morpho::impl::general_on_set_centered__erosion");
00120 return output;
00121 }
00122
00123
00124 template <typename I, typename W>
00125 mln_concrete(I)
00126 general_on_set_centered_fastest(const erosion_op&,
00127 const Image<I>& input_, const Window<W>& win_)
00128 {
00129 trace::entering("morpho::impl::general_on_set_centered_fastest__erosion");
00130
00131 typedef mln_concrete(I) O;
00132 const I& input = exact(input_);
00133 const W& win = exact(win_);
00134
00135 extension::adjust_fill(input, win, true);
00136
00137 O output;
00138 output = duplicate(input);
00139
00140 mln_pixter(const I) p(input);
00141 mln_qixter(const I, W) q(p, win);
00142 mln_pixter(O) p_out(output);
00143 for_all_2(p, p_out)
00144 if (p.val() == true)
00145 for_all(q)
00146 if (q.val() == false)
00147 {
00148 p_out.val() = false;
00149 break;
00150 }
00151
00152 trace::exiting("morpho::impl::general_on_set_centered_fastest__erosion");
00153 return output;
00154 }
00155
00156 }
00157
00158
00159
00160 template <typename I, typename W>
00161 inline
00162 mln_concrete(I)
00163 erosion(const Image<I>& input, const Window<W>& win)
00164 {
00165 trace::entering("morpho::erosion");
00166 mln_precondition(exact(input).is_valid());
00167 mln_precondition(! exact(win).is_empty());
00168
00169 mln_concrete(I) output = general(erosion_op(), input, win);
00170
00171 if (exact(win).is_centered())
00172 mln_postcondition(output <= input);
00173
00174 trace::exiting("morpho::erosion");
00175 return output;
00176 }
00177
00178 # endif // ! MLN_INCLUDE_ONLY
00179
00180 }
00181
00182 }
00183
00184
00185 #endif // ! MLN_MORPHO_EROSION_HH