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_MEYER_WST_HH
00027 # define MLN_MORPHO_MEYER_WST_HH
00028
00041
00042
00043
00044
00045
00046
00047
00048
00049 # include <mln/trait/ch_value.hh>
00050
00051
00052 # include <mln/util/greater_psite.hh>
00053 # include <mln/morpho/includes.hh>
00054 # include <mln/literal/zero.hh>
00055 # include <mln/labeling/regional_minima.hh>
00056
00057 # include <mln/core/site_set/p_queue_fast.hh>
00058 # include <mln/core/site_set/p_priority.hh>
00059
00060
00061 namespace mln
00062 {
00063
00064 namespace morpho
00065 {
00077 template <typename L, typename I, typename N>
00078 mln_ch_value(I, L)
00079 meyer_wst(const Image<I>& input, const Neighborhood<N>& nbh,
00080 L& nbasins);
00081
00098 template <typename L, typename I, typename N>
00099 mln_ch_value(I, L)
00100 meyer_wst(const Image<I>& input, const Neighborhood<N>& nbh);
00101
00102
00103
00104 # ifndef MLN_INCLUDE_ONLY
00105
00106 template <typename L, typename I, typename N>
00107 mln_ch_value(I, L)
00108 meyer_wst(const Image<I>& input_, const Neighborhood<N>& nbh_,
00109 L& nbasins)
00110 {
00111 trace::entering("morpho::meyer_wst");
00112
00113
00114 const I input = exact(input_);
00115 const N nbh = exact(nbh_);
00116
00117 typedef L marker;
00118 const marker unmarked = literal::zero;
00119
00120 typedef mln_value(I) V;
00121 const V max = mln_max(V);
00122
00123
00124 mln_ch_value(I, marker) output =
00125 labeling::regional_minima (input, nbh, nbasins);
00126
00127 typedef mln_psite(I) psite;
00128
00129
00130 typedef p_queue_fast<psite> Q;
00131 p_priority<V, Q> queue;
00132
00133
00134 mln_ch_value(I, bool) in_queue;
00135 initialize(in_queue, input);
00136 data::fill(in_queue, false);
00137
00138
00139
00140
00141 mln_piter(I) p(output.domain());
00142 mln_niter(N) n(nbh, p);
00143 for_all (p)
00144 if (output(p) == unmarked)
00145 for_all(n)
00146 if (output.domain().has(n) && output(n) != unmarked)
00147 {
00148 queue.push(max - input(p), p);
00149 in_queue(p) = true;
00150 break;
00151 }
00152
00153
00154
00155
00156 while (! queue.is_empty())
00157 {
00158 psite p = queue.front();
00159 queue.pop();
00160
00161 marker adjacent_marker = unmarked;
00162
00163 bool single_adjacent_marker_p = true;
00164 mln_niter(N) n(nbh, p);
00165 for_all(n)
00166 if (output.domain().has(n) && output(n) != unmarked)
00167 {
00168 if (adjacent_marker == unmarked)
00169 {
00170 adjacent_marker = output(n);
00171 single_adjacent_marker_p = true;
00172 }
00173 else
00174 if (adjacent_marker != output(n))
00175 {
00176 single_adjacent_marker_p = false;
00177 break;
00178 }
00179 }
00180
00181
00182
00183
00184 if (single_adjacent_marker_p)
00185 {
00186 output(p) = adjacent_marker;
00187 for_all(n)
00188 if (output.domain().has(n) && output(n) == unmarked
00189 && ! in_queue(n))
00190 {
00191 queue.push(max - input(n), n);
00192 in_queue(n) = true;
00193 }
00194 }
00195 }
00196 trace::exiting("morpho::meyer_wst");
00197 return output;
00198 }
00199
00200 template <typename L, typename I, typename N>
00201 mln_ch_value(I, L)
00202 meyer_wst(const Image<I>& input, const Neighborhood<N>& nbh)
00203 {
00204 L nbasins;
00205 return meyer_wst<L>(input, nbh, nbasins);
00206 }
00207
00208 # endif // ! MLN_INCLUDE_ONLY
00209
00210 }
00211
00212 }
00213
00214
00215 #endif // ! MLN_MORPHO_MEYER_WST_HH