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