Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
approx/erosion.hh
1 // Copyright (C) 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_APPROX_EROSION_HH
27 # define MLN_MORPHO_APPROX_EROSION_HH
28 
32 
33 # include <mln/morpho/approx/dilation.hh>
34 # include <mln/logical/not.hh>
35 
36 
37 
38 namespace mln
39 {
40 
41  namespace morpho
42  {
43 
44  namespace approx
45  {
46 
47 
48  template <typename I, typename W>
49  mln_concrete(I)
50  erosion(const Image<I>& input, const Window<W>& win);
51 
52 
53 
54 # ifndef MLN_INCLUDE_ONLY
55 
56 
57  // Implementations.
58 
59  namespace impl
60  {
61 
62 
63  // By distance thresholding.
64 
65  template <typename I>
66  mln_concrete(I)
67  erosion_by_distance_thresholding_2d(const Image<I>& input_,
68  const Window< win::disk2d >& win_)
69  {
70  trace::entering("morpho::approx::impl::erosion_by_distance_thresholding_2d");
71 
72  const I& input = exact(input_);
73  const win::disk2d& win = exact(win_);
74 
75  mln_precondition(input.is_valid());
76  mln_precondition(win.is_valid());
77 
78  int ws[] = { 00, 11, 0, 11, 0,
79  11, 7, 5, 7, 11,
80  00, 5, 0, 5, 0,
81  11, 7, 5, 7, 11,
82  00, 11, 0, 11, 0 };
83  const unsigned coef = 5;
84 
85  unsigned
86  radius = coef * win.diameter() / 2,
87  dmax = radius + 1;
88 
89 
90  mln_concrete(I) background = logical::not_(input);
91  mln_ch_value(I, unsigned) dmap = transform::distance_front(background,
92  c4(), make::w_window2d_int(ws),
93  dmax);
94  mln_concrete(I) output;
95  output = duplicate((pw::value(dmap) > pw::cst(radius)) | input.domain());
96 
97  trace::exiting("morpho::approx::impl::erosion_by_distance_thresholding_2d");
98  return output;
99  }
100 
101 
102 
103  template <typename I>
104  mln_concrete(I)
105  erosion_by_distance_thresholding_3d(const Image<I>& input_,
106  const Window< win::sphere3d >& win_)
107  {
108  trace::entering("morpho::approx::impl::erosion_by_distance_thresholding_3d");
109 
110  const I& input = exact(input_);
111  const win::sphere3d& win = exact(win_);
112 
113  mln_precondition(input.is_valid());
114  mln_precondition(win.is_valid());
115 
116  int ws[] = { 00, 21, 00,
117  21, 17, 21,
118  00, 21, 00,
119 
120  17, 12, 17,
121  12, 00, 12,
122  17, 12, 17,
123 
124  00, 21, 00,
125  21, 17, 21,
126  00, 21, 00 };
127  const unsigned coef = 12;
128 
129  unsigned
130  radius = coef * win.diameter() / 2,
131  dmax = radius + 1;
132 
133  mln_concrete(I) background = logical::not_(input);
134  mln_ch_value(I, unsigned) dmap = transform::distance_front(background,
135  c6(), make::w_window3d_int(ws),
136  dmax);
137  mln_concrete(I) output;
138  output = duplicate((pw::value(dmap) > pw::cst(radius)) | input.domain());
139 
140  trace::exiting("morpho::approx::impl::erosion_by_distance_thresholding_3d");
141  return output;
142  }
143 
144 
145  } // end of namespace mln::morpho::approx::impl
146 
147 
148 
149  // Dispatch.
150 
151  namespace internal
152  {
153 
154  template <typename I>
155  mln_concrete(I)
156  erosion_dispatch(trait::image::kind::logic,
157  const I& input,
158  const win::disk2d& win)
159  {
160  return impl::erosion_by_distance_thresholding_2d(input, win);
161  }
162 
163  template <typename I>
164  mln_concrete(I)
165  erosion_dispatch(trait::image::kind::logic,
166  const I& input,
167  const win::sphere3d& win)
168  {
169  return impl::erosion_by_distance_thresholding_3d(input, win);
170  }
171 
172  // Entry point.
173 
174  template <typename I, typename W>
175  mln_concrete(I)
176  erosion_dispatch(const I& input, const W& win)
177  {
178  return erosion_dispatch(mln_trait_image_kind(I)(),
179  input, win);
180  }
181 
182  } // end of namespace mln::morpho::approx::internal
183 
184 
185  // Facade.
186 
187  template <typename I, typename W>
188  inline
189  mln_concrete(I)
190  erosion(const Image<I>& input, const Window<W>& win)
191  {
192  trace::entering("morpho::approx::erosion");
193 
194  mln_precondition(exact(input).is_valid());
195  mln_precondition(exact(win).is_valid());
196 
197  mln_concrete(I) output;
198  output = internal::erosion_dispatch(exact(input), exact(win));
199 
200  if (exact(win).is_centered())
201  mln_postcondition(output <= input);
202 
203  trace::exiting("morpho::approx::erosion");
204  return output;
205  }
206 
207 
208 # endif // ! MLN_INCLUDE_ONLY
209 
210  } // end of namespace mln::morpho::approx
211 
212  } // end of namespace mln::morpho
213 
214 } // end of namespace mln
215 
216 
217 #endif // ! MLN_MORPHO_APPROX_EROSION_HH