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