$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
sort_offsets.hh
1 // Copyright (C) 2007, 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_DATA_SORT_OFFSETS_HH
27 # define MLN_DATA_SORT_OFFSETS_HH
28 
33 
34 # include <algorithm>
35 
36 # include <mln/core/concept/image.hh>
37 # include <mln/histo/compute.hh>
38 # include <mln/util/array.hh>
39 # include <mln/util/ord.hh>
40 # include <mln/geom/nsites.hh>
41 
42 
43 namespace mln
44 {
45 
46  namespace data
47  {
48 
52  template <typename I>
53  util::array<unsigned>
54  sort_offsets_increasing(const Image<I>& input);
55 
56 
57  // /// Sort pixel offsets of the image \p input wrt decreasing pixel
58  // /// values.
59  // ///
60  // template <typename I>
61  // util::array<unsigned>
62  // sort_offsets_decreasing(const Image<I>& input);
63 
64 
65 
66 # ifndef MLN_INCLUDE_ONLY
67 
68  namespace impl
69  {
70 
71  namespace generic
72  {
73 
74  // increasing
75 
76  template <typename I>
77  struct value_offset_less_
78  {
79  const I& ima_;
80  inline value_offset_less_(const I& ima) : ima_(ima) {}
81  inline bool operator()(unsigned lhs, unsigned rhs) const
82  {
83  return util::ord_strict(ima_.element(lhs), ima_.element(rhs))
84  || (ima_.element(lhs) == ima_.element(rhs)
85  &&
86  lhs < rhs);
87  }
88  };
89 
90  template <typename I>
91  inline
92  util::array<unsigned>
93  sort_offsets_increasing(const Image<I>& input_)
94  {
95  mln_trace("data::impl::generic::sort_offsets_increasing");
96 
97  const I& input = exact(input_);
98 
99  util::array<unsigned> v;
100  v.reserve(input.nelements());
101  mln_fwd_pixter(const I) pxl(input);
102  for_all(pxl)
103  v.append(pxl.offset());
104  std::sort(v.hook_std_vector_().begin(), v.hook_std_vector_().end(),
105  value_offset_less_<I>(input));
106 
107  return v;
108  }
109 
110 
111  // decreasing
112 
113  template <typename I>
114  struct value_offset_greater_
115  {
116  const I& ima_;
117  inline value_offset_greater_(const I& ima) : ima_(ima) {}
118  inline bool operator()(unsigned lhs, unsigned rhs) const
119  {
120  return util::ord_strict(ima_.element(rhs), ima_.element(lhs))
121  || (ima_.element(lhs) == ima_.element(rhs)
122  &&
123  lhs > rhs);
124  }
125  };
126 
127  template <typename I>
128  inline
129  util::array<unsigned>
130  sort_offsets_decreasing(const Image<I>& input_)
131  {
132  mln_trace("data::impl::generic::sort_offsets_decreasing");
133 
134  const I& input = exact(input_);
135 
136  util::array<unsigned> v;
137  v.reserve(input.nelements());
138  mln_fwd_pixter(const I) pxl(input);
139  for_all(pxl)
140  v.append(pxl.offset());
141  std::sort(v.hook_std_vector_().begin(), v.hook_std_vector_().end(),
142  value_offset_greater_<I>(input));
143 
144  return v;
145  }
146 
147 
148  } // end of namespace mln::data::impl::generic
149 
150 
151 
152  // increasing
153 
154  template <typename I>
155  inline
156  util::array<unsigned>
157  sort_offsets_increasing_radix(const Image<I>& input_)
158  {
159  mln_trace("data::impl::sort_offsets_increasing_radix");
160 
161  const I& input = exact(input_);
162 
163  typedef mln_vset(I) S;
164  const S& vset = input.values_eligible();
165  const unsigned n = vset.nvalues();
166 
167  // h
168  histo::array<mln_value(I)> h = histo::compute(input);
169 
170  // preparing output data
171  std::vector<unsigned> loc(vset.nvalues());
172  loc[0] = 0;
173  for (unsigned i = 1; i != n; ++i)
174  loc[i] = loc[i-1] + h[i-1];
175 
176  // computing output data
177  util::array<unsigned> vec(geom::nsites(input));
178  mln_fwd_pixter(const I) pxl(input);
179  for_all(pxl)
180  vec[loc[vset.index_of(pxl.val())]++] = pxl.offset();
181 
182  return vec;
183  }
184 
185 
186  // decreasing
187 
188  template <typename I>
189  inline
190  util::array<unsigned>
191  sort_offsets_decreasing_radix(const Image<I>& input_)
192  {
193  mln_trace("data::impl::sort_offsets_decreasing_radix");
194 
195  const I& input = exact(input_);
196 
197  typedef mln_vset(I) S;
198  const S& vset = input.values_eligible();
199  const unsigned n = vset.nvalues();
200 
201  // h
202  histo::array<mln_value(I)> h = histo::compute(input);
203 
204  // preparing output data
205  std::vector<unsigned> loc(vset.nvalues());
206  loc[n-1] = 0;
207  for (int i = n - 2; i >= 0; --i)
208  loc[i] = loc[i+1] + h[i+1];
209 
210  // computing output data
211  util::array<unsigned> vec(geom::nsites(input));
212  mln_fwd_pixter(const I) pxl(input);
213  for_all(pxl)
214  vec[loc[vset.index_of(pxl.val())]++] = pxl.offset();
215 
216  return vec;
217  }
218 
219 
220  } // end of namespace mln::data::impl
221 
222 
223 
224  namespace internal
225  {
226 
227  // increasing
228 
229  template <typename I>
230  inline
231  util::array<unsigned>
232  sort_offsets_increasing_dispatch(trait::image::quant::any,
233  const Image<I>& input)
234  {
236  }
237 
238  template <typename I>
239  inline
240  util::array<unsigned>
241  sort_offsets_increasing_dispatch(trait::image::quant::low,
242  const Image<I>& input)
243  {
244  return impl::sort_offsets_increasing_radix(input);
245  }
246 
247  template <typename I>
248  inline
249  util::array<unsigned>
250  sort_offsets_increasing_dispatch(const Image<I>& input)
251  {
252  return sort_offsets_increasing_dispatch(mln_trait_image_quant(I)(),
253  input);
254  }
255 
256  // decreasing
257 
258  template <typename I>
259  inline
260  util::array<unsigned>
261  sort_offsets_decreasing_dispatch(trait::image::quant::any,
262  const Image<I>& input)
263  {
264  return impl::generic::sort_offsets_decreasing(input);
265  }
266 
267  template <typename I>
268  inline
269  util::array<unsigned>
270  sort_offsets_decreasing_dispatch(trait::image::quant::low,
271  const Image<I>& input)
272  {
273  return impl::sort_offsets_decreasing_radix(input);
274  }
275 
276  template <typename I>
277  inline
278  util::array<unsigned>
279  sort_offsets_decreasing_dispatch(const Image<I>& input)
280  {
281  return sort_offsets_decreasing_dispatch(mln_trait_image_quant(I)(),
282  input);
283  }
284 
285  } // end of namespace mln::data::internal
286 
287 
288 
289  // Facades.
290 
291  template <typename I>
292  inline
293  util::array<unsigned>
294  sort_offsets_increasing(const Image<I>& input)
295  {
296  mln_trace("data::sort_offsets_increasing");
297  mlc_is(mln_trait_image_speed(I),
298  trait::image::speed::fastest)::check();
299 
300  mln_precondition(exact(input).is_valid());
301  util::array<unsigned> output = internal::sort_offsets_increasing_dispatch(input);
302 
303  return output;
304  }
305 
306  template <typename I>
307  inline
308  util::array<unsigned>
309  sort_offsets_decreasing(const Image<I>& input)
310  {
311  mln_trace("data::sort_offsets_decreasing");
312  mlc_is(mln_trait_image_speed(I),
313  trait::image::speed::fastest)::check();
314 
315  mln_precondition(exact(input).is_valid());
316  util::array<unsigned> output = internal::sort_offsets_decreasing_dispatch(input);
317 
318  return output;
319  }
320 
321 # endif // ! MLN_INCLUDE_ONLY
322 
323  } // end of namespace mln::data
324 
325 } // end of namespace mln
326 
327 
328 #endif // ! MLN_DATA_SORT_OFFSETS_HH