Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
meyer_wst.hh
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_MORPHO_MEYER_WST_HH
27 # define MLN_MORPHO_MEYER_WST_HH
28 
41 /* FIXME: This file is outdated. Compare this file with
42  mln/morpho/watershed/flooding.hh, and remove the former when
43 
44  1. it is entirely covered by the latter;
45  2. clients (including tests and Milena) are updated to use
46  mln::morpho::watershed::flooding. */
47 
48 
49 # include <mln/trait/ch_value.hh>
50 
51 // FIXME: See below.
52 # include <mln/util/greater_psite.hh>
53 # include <mln/morpho/includes.hh>
54 # include <mln/literal/zero.hh>
55 # include <mln/labeling/regional_minima.hh>
56 
57 # include <mln/core/site_set/p_queue_fast.hh>
58 # include <mln/core/site_set/p_priority.hh>
59 
60 
61 namespace mln
62 {
63 
64  namespace morpho
65  {
77  template <typename L, typename I, typename N>
78  mln_ch_value(I, L)
79  meyer_wst(const Image<I>& input, const Neighborhood<N>& nbh,
80  L& nbasins);
81 
98  template <typename L, typename I, typename N>
99  mln_ch_value(I, L)
100  meyer_wst(const Image<I>& input, const Neighborhood<N>& nbh);
101 
102 
103 
104 # ifndef MLN_INCLUDE_ONLY
105 
106  template <typename L, typename I, typename N>
107  mln_ch_value(I, L)
108  meyer_wst(const Image<I>& input_, const Neighborhood<N>& nbh_,
109  L& nbasins)
110  {
111  trace::entering("morpho::meyer_wst");
112  /* FIXME: Ensure the input image has scalar values. */
113 
114  const I input = exact(input_);
115  const N nbh = exact(nbh_);
116 
117  typedef L marker;
118  const marker unmarked = literal::zero;
119 
120  typedef mln_value(I) V;
121  const V max = mln_max(V);
122 
123  // Initialize the output with the markers (minima components).
124  mln_ch_value(I, marker) output =
125  labeling::regional_minima (input, nbh, nbasins);
126 
127  typedef mln_psite(I) psite;
128 
129  // Ordered queue.
130  typedef p_queue_fast<psite> Q;
131  p_priority<V, Q> queue;
132 
133  // In_queue structure to avoid processing sites several times.
134  mln_ch_value(I, bool) in_queue;
135  initialize(in_queue, input);
136  data::fill(in_queue, false);
137 
138  // Insert every neighbor P of every marked area in a
139  // hierarchical queue, with a priority level corresponding to
140  // the grey level input(P).
141  mln_piter(I) p(output.domain());
142  mln_niter(N) n(nbh, p);
143  for_all (p)
144  if (output(p) == unmarked)
145  for_all(n)
146  if (output.domain().has(n) && output(n) != unmarked)
147  {
148  queue.push(max - input(p), p);
149  in_queue(p) = true;
150  break;
151  }
152 
153  /* Until the queue is empty, extract a psite P from the
154  hierarchical queue, at the highest priority level, that is,
155  the lowest level. */
156  while (! queue.is_empty())
157  {
158  psite p = queue.front();
159  queue.pop();
160  // Last seen marker adjacent to P.
161  marker adjacent_marker = unmarked;
162  // Has P a single adjacent marker?
163  bool single_adjacent_marker_p = true;
164  mln_niter(N) n(nbh, p);
165  for_all(n)
166  if (output.domain().has(n) && output(n) != unmarked)
167  {
168  if (adjacent_marker == unmarked)
169  {
170  adjacent_marker = output(n);
171  single_adjacent_marker_p = true;
172  }
173  else
174  if (adjacent_marker != output(n))
175  {
176  single_adjacent_marker_p = false;
177  break;
178  }
179  }
180  /* If the neighborhood of P contains only psites with the
181  same label, then P is marked with this label, and its
182  neighbors that are not yet marked are put into the
183  hierarchical queue. */
184  if (single_adjacent_marker_p)
185  {
186  output(p) = adjacent_marker;
187  for_all(n)
188  if (output.domain().has(n) && output(n) == unmarked
189  && ! in_queue(n))
190  {
191  queue.push(max - input(n), n);
192  in_queue(n) = true;
193  }
194  }
195  }
196  trace::exiting("morpho::meyer_wst");
197  return output;
198  }
199 
200  template <typename L, typename I, typename N>
201  mln_ch_value(I, L)
202  meyer_wst(const Image<I>& input, const Neighborhood<N>& nbh)
203  {
204  L nbasins;
205  return meyer_wst<L>(input, nbh, nbasins);
206  }
207 
208 # endif // ! MLN_INCLUDE_ONLY
209 
210  } // end of namespace mln::morpho
211 
212 } // end of namespace mln
213 
214 
215 #endif // ! MLN_MORPHO_MEYER_WST_HH