$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Rd.hh
1 // Copyright (C) 2007, 2008, 2009, 2012 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_MORPHO_RD_HH
28 # define MLN_MORPHO_RD_HH
29 
30 // FIXME: This file, as well its functions and classes, shall not
31 // contain capital letters.
32 
36 
37 # include <vector>
38 # include <mln/core/concept/image.hh>
39 # include <mln/core/concept/neighborhood.hh>
40 # include <mln/trait/value_.hh>
41 # include <mln/data/fill.hh>
42 # include <mln/data/compare.hh>
43 # include <mln/util/ord.hh>
44 
45 
46 namespace mln
47 {
48 
49  namespace morpho
50  {
51 
52  template <typename I, typename N>
53  I
54  Rd(const Image<I>& f, const Image<I>& g, const Neighborhood<N>& nbh);
55 
56 
57 # ifndef MLN_INCLUDE_ONLY
58 
59  namespace impl
60  {
61 
62  template <typename I>
63  inline
64  std::vector<unsigned> compute_histo(const I& ima)
65  {
66  std::vector<unsigned> h(256, 0);
67  mln_piter(I) p(ima.domain());
68  for_all(p)
69  ++h[ima(p)];
70  return h;
71  }
72 
73  template <typename I>
74  inline
75  std::vector<mln_psite(I)> histo_reverse_sort(const I& ima)
76  {
77  std::vector<unsigned> h = compute_histo(ima);
78  // preparing output data
79  std::vector<int> loc(256);
80  loc[255] = 0;
81  for (int l = 254; l >= 0; --l)
82  loc[l] = loc[l+1] + h[l+1];
83  std::vector<mln_psite(I)> vec(ima.domain().nsites());
84  // storing output data
85  mln_piter(I) p(ima.domain());
86  for_all(p)
87  vec[loc[ima(p)]++] = p;
88  return vec;
89  }
90 
91 
92  template <typename I, typename N>
93  struct Rd
94  {
95  typedef mln_psite(I) point;
96  typedef mln_value(I) value;
97 
98  // in:
99  const I& f;
100  const I& g;
101  const N& nbh;
102 
103  // out:
104  I o;
105 
106  // aux:
107  mln_ch_value(I, bool) is_proc;
108  mln_ch_value(I, point) parent;
109  std::vector<point> S;
110 
111  inline
112  Rd(const I& f, const I& g, const N& nbh)
113  : f(f), g(g), nbh(nbh),
114  o(f.domain()),
115  is_proc(f.domain()),
116  parent(f.domain())
117  {
118  // init
119  data::fill(o, f);
120  S = histo_reverse_sort(g);
121  data::fill(is_proc, false); // FIXME: rm
122 
123  // first pass
124  for (unsigned i = 0; i < S.size(); ++i)
125  {
126  point p = S[i];
127 
128  make_set(p);
129  mln_niter(N) n(nbh, p);
130  for_all(n)
131  {
132  if (f.domain().has(n))
133  assert(is_proc(n) == is_proc__(n, p));
134  if (f.has(n) && is_proc(n))
135  do_union(n, p);
136  }
137  is_proc(p) = true;
138  }
139 
140  // second pass
141  for (int i = S.size() - 1; i >= 0; --i)
142  {
143  point p = S[i];
144  if (parent(p) == p)
145  {
146  if (o(p) == mln_max(value))
147  o(p) = g(p);
148  else
149  o(p) = o(parent(p));
150  }
151  }
152 
153  }
154 
155  inline
156  bool is_proc__(const point& n, const point& p) const
157  {
158  return g(n) > g(p) || (g(n) == g(p) && util::ord_strict(point(n), p));
159  }
160 
161  inline
162  void make_set(const point& p)
163  {
164  parent(p) = p;
165  }
166 
167  inline
168  point find_root(const point& x)
169  {
170  if (parent(x) == x)
171  return x;
172  else
173  return parent(x) = find_root(parent(x));
174  }
175 
176  inline
177  bool equiv(const point& r, const point& p)
178  {
179  return g(r) == g(p) || g(p) >= o(r);
180  }
181 
182  inline
183  void do_union(const point& n, const point& p)
184  {
185  point r = find_root(n);
186  if (r != p)
187  {
188  if (equiv(r, p))
189  {
190  parent(r) = p;
191  if (o(r) > o(p))
192  o(p) = o(r); // increasing criterion
193  }
194  else
195  o(p) = mln_max(value);
196  }
197  }
198 
199  };
200 
201  } // end of namespace mln::morpho::impl
202 
203 
204  // facade
205 
206  template <typename I, typename N>
207  inline
208  I
209  Rd(const Image<I>& f, const Image<I>& g, const Neighborhood<N>& nbh)
210  {
211  assert(f <= g);
212  impl::Rd<I,N> run(exact(f), exact(g), exact(nbh));
213  return run.o;
214  }
215 
216 # endif // ! MLN_INCLUDE_ONLY
217 
218  } // end of namespace mln::morpho
219 
220 } // end of namespace mln
221 
222 
223 #endif // ! MLN_MORPHO_RD_HH