Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
rank_filter.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_MORPHO_RANK_FILTER_HH
27 # define MLN_MORPHO_RANK_FILTER_HH
28 
34 
35 # include <mln/morpho/includes.hh>
36 # include <mln/accu/transform_line.hh>
37 # include <mln/convert/to_p_array.hh>
38 
39 
40 
41 namespace mln
42 {
43 
44  namespace morpho
45  {
46 
48  template <typename I, typename W>
49  mln_concrete(I)
50  rank_filter(const Image<I>& input, const Window<W>& win, unsigned k);
51 
52 
53 # ifndef MLN_INCLUDE_ONLY
54 
55 
56  // Tests.
57 
58 
59  namespace internal
60  {
61 
62  template <typename I, typename W>
63  inline
64  void
65  rank_filter_tests(const Image<I>& input_, const Window<W>& win_, unsigned k)
66  {
67  const I& input = exact(input_);
68  const W& win = exact(win_);
69 
70  mln_precondition(input.is_valid());
71  mln_precondition(! win.is_empty());
72  (void) input;
73  (void) win;
74  (void) k;
75  }
76 
77  } // end of namespace mln::morpho::internal
78 
79 
80 
81  // Implementations.
82 
83 
84  namespace impl
85  {
86 
87  namespace generic
88  {
89 
90  template <typename I, typename W>
91  inline
92  mln_concrete(I)
93  rank_filter(const Image<I>& input_, const Window<W>& win_, unsigned k)
94  {
95  trace::entering("morpho::impl::generic::rank_filter");
96 
97  internal::rank_filter_tests(input_, win_, k);
98 
99  const I& input = exact(input_);
100  const W& win = exact(win_);
101 
102  mln_concrete(I) output;
103  initialize(output, input);
104 
105  accu::stat::rank<mln_value(I)> accu(k);
106  extension::adjust_fill(input, geom::delta(win) + 1, accu);
107  mln_piter(I) p(input.domain());
108  mln_qiter(W) q(win, p);
109  for_all(p)
110  {
111  accu.init();
112  for_all(q)
113  if (input.has(q))
114  accu.take(input(q));
115  //else
116  // accu.take(mln_value(I)(literal::zero));
117  output(p) = accu;
118  }
119 
120  trace::exiting("morpho::impl::generic::rank_filter");
121  return output;
122  }
123 
124  } // end of namespace mln::morpho::impl::generic
125 
126 
127  template <typename I, typename W>
128  inline
129  mln_concrete(I)
130  rank_filter_line(const Image<I>& input, const Window<W>& win, unsigned k, unsigned dir)
131  {
132  trace::entering("morpho::impl::rank_filter_line");
133 
134  internal::rank_filter_tests(input, win, k);
135 
136  accu::stat::rank<mln_value(I)> accu(k);
137  extension::adjust_fill(input, geom::delta(win) + 1, accu);
138  mln_concrete(I) output = accu::transform_line(accu, input, exact(win).length(), dir);
139 
140  trace::exiting("morpho::impl::rank_filter_line");
141  return output;
142  }
143 
144 
145  template <typename I, typename W>
146  inline
147  mln_concrete(I)
148  rank_filter_directional(const Image<I>& input, const Window<W>& win, unsigned k, unsigned dir)
149  {
150  trace::entering("morpho::impl::rank_filter_directional");
151 
152  internal::rank_filter_tests(input, win, k);
153 
154  accu::stat::rank<mln_value(I)> accu(k);
155  extension::adjust_fill(input, geom::delta(win) + 1, accu);
156  mln_concrete(I) output = accu::transform_directional(accu, input, win, dir);
157 
158  trace::exiting("morpho::impl::rank_filter_directional");
159  return output;
160  }
161 
162 
163  } // end of namespace mln::morpho::impl
164 
165 
166 
167  // Dispatch.
168 
169 
170  namespace internal
171  {
172 
173  template <typename I, typename M, unsigned i, typename C>
174  inline
175  mln_concrete(I)
176  rank_filter_dispatch(const Image<I>& input, const win::line<M, i, C>& win, unsigned k)
177  {
178  return impl::rank_filter_line(input, win, k, i);
179  }
180 
181  template <typename I>
182  inline
183  mln_concrete(I)
184  rank_filter_dispatch(const Image<I>& input, const win::rectangle2d& win, unsigned k)
185  {
186  if (win.height() <= 3 && win.width() <= 3)
187  return impl::generic::rank_filter(input, win, k);
188  else
189  if (win.height() < win.width())
190  return impl::rank_filter_directional(input, win, k, 1);
191  else
192  return impl::rank_filter_directional(input, win, k, 0);
193  }
194 
195  template <typename I, typename W>
196  inline
197  mln_concrete(I)
198  rank_filter_dispatch(const Image<I>& input, const Window<W>& win, unsigned k)
199  {
200  return impl::generic::rank_filter(input, win, k);
201  }
202 
203  } // end of namespace mln::morpho::internal
204 
205 
206 
207  // Facades.
208 
209 
210  template <typename I, typename W>
211  inline
212  mln_concrete(I)
213  rank_filter(const Image<I>& input, const Window<W>& win, unsigned k)
214  {
215  trace::entering("morpho::rank_filter");
216 
217  mln_precondition(exact(input).is_valid());
218  mln_precondition(! exact(win).is_empty());
219 
220  mln_concrete(I) output = internal::rank_filter_dispatch(exact(input), exact(win), k);
221 
222  trace::exiting("morpho::rank_filter");
223  return output;
224  }
225 
226 # endif // ! MLN_INCLUDE_ONLY
227 
228  } // end of namespace mln::morpho
229 
230 } // end of namespace mln
231 
232 
233 #endif // ! MLN_MORPHO_RANK_FILTER_HH