Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
hit_or_miss.hh
1 // Copyright (C) 2007, 2008, 2009, 2011 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_HIT_OR_MISS_HH
28 # define MLN_MORPHO_HIT_OR_MISS_HH
29 
35 
36 # include <mln/morpho/includes.hh>
37 # include <mln/pw/all.hh>
38 # include <mln/fun/p2v/ternary.hh>
39 # include <mln/fun/cast.hh>
40 # include <mln/literal/zero.hh>
41 
42 
43 namespace mln
44 {
45 
46  namespace morpho
47  {
48 
49 
50  extern bool constrained_hit_or_miss;
51 
52 
54 
57  template <typename I, typename Wh, typename Wm>
58  mln_concrete(I)
59  hit_or_miss(const Image<I>& input,
60  const Window<Wh>& win_hit, const Window<Wm>& win_miss);
61 
62 
64 
67  template <typename I, typename Wh, typename Wm>
68  mln_concrete(I)
69  hit_or_miss_opening(const Image<I>& input,
70  const Window<Wh>& win_hit, const Window<Wm>& win_miss);
71 
72 
74 
77  template <typename I, typename Wh, typename Wm>
78  mln_concrete(I)
79  hit_or_miss_background_opening(const Image<I>& input,
80  const Window<Wh>& win_hit, const Window<Wm>& win_miss);
81 
82 
84 
87  template <typename I, typename Wh, typename Wm>
88  mln_concrete(I)
89  hit_or_miss_closing(const Image<I>& input,
90  const Window<Wh>& win_hit, const Window<Wm>& win_miss);
91 
92 
94 
97  template <typename I, typename Wh, typename Wm>
98  mln_concrete(I)
99  hit_or_miss_background_closing(const Image<I>& input,
100  const Window<Wh>& win_hit, const Window<Wm>& win_miss);
101 
102 
103 
104 # ifndef MLN_INCLUDE_ONLY
105 
106 # ifndef MLN_WO_GLOBAL_VARS
107 
108  bool constrained_hit_or_miss = true;
109 
110 # endif // ! MLN_WO_GLOBAL_VARS
111 
112  namespace internal
113  {
114 
115  template <typename I, typename Wh, typename Wm>
116  inline
117  void
118  hit_or_miss_tests(const Image<I>& input_,
119  const Window<Wh>& win_hit_,
120  const Window<Wm>& win_miss_)
121  {
122  const I& input = exact(input_);
123  const Wh& win_hit = exact(win_hit_);
124  const Wm& win_miss = exact(win_miss_);
125 
126  // Tests.
127  mln_precondition(input.is_valid());
128  mln_precondition((win_hit && win_miss).is_empty());
129 
130  // Avoid warnings.
131  (void) input;
132  (void) win_hit;
133  (void) win_miss;
134  }
135 
136  } // end of namespace mln::morpho::internal
137 
138 
139  namespace impl
140  {
141 
142  // On sets.
143 
144  template <typename I, typename Wh, typename Wm>
145  inline
146  mln_concrete(I)
147  hit_or_miss_logic(const Image<I>& input,
148  const Window<Wh>& win_hit,
149  const Window<Wm>& win_miss)
150  {
151  trace::entering("morpho::impl::hit_or_miss_logic");
152  internal::hit_or_miss_tests(input, win_hit, win_miss);
153 
154  mln_concrete(I) output = logical::and_(erosion(input, win_hit),
155  erosion(complementation(input),
156  win_miss));
157 
158  trace::exiting("morpho::impl::hit_or_miss_logic");
159  return output;
160  }
161 
162 
163 
164  namespace generic
165  {
166 
167  // On functions.
168 
169  template <typename I, typename Wh, typename Wm>
170  inline
171  mln_concrete(I)
172  hit_or_miss(const Image<I>& input_,
173  const Window<Wh>& win_hit_,
174  const Window<Wm>& win_miss_)
175  {
176  trace::entering("morpho::impl::generic::hit_or_miss");
177  internal::hit_or_miss_tests(input_, win_hit_, win_miss_);
178 
179  const I& input = exact(input_);
180  const Wh& win_hit = exact(win_hit_);
181  const Wm& win_miss = exact(win_miss_);
182 
183  typedef mln_value(I) V;
184  mln_value(I) zero_V = literal::zero;
185 
186  mln_concrete(I) output;
187  initialize(output, input);
188 
189  if (constrained_hit_or_miss) // CHMT.
190  {
191  if (win_hit.is_centered())
192  {
193  mln_concrete(I)
194  ero_fg = erosion(input, win_hit),
195  dil_bg = dilation(input, win_miss);
196  data::fill(output,
197  fun::p2v::ternary(pw::value(input) == pw::value(ero_fg)
198  && pw::value(dil_bg) < pw::value(input),
199  fun::cast<V>(pw::value(input) - pw::value(dil_bg)),
200  pw::cst(zero_V)));
201  }
202  else if (win_miss.is_centered())
203  {
204  mln_concrete(I)
205  ero_bg = erosion(input, win_miss),
206  dil_fg = dilation(input, win_hit);
207  data::fill(output,
208  fun::p2v::ternary(pw::value(input) == pw::value(dil_fg)
209  && pw::value(ero_bg) > pw::value(input),
210  fun::cast<V>(pw::value(ero_bg) - pw::value(input)),
211  pw::cst(zero_V)));
212  }
213  else
214  data::fill(output, zero_V);
215  }
216  else // Unconstrained: UHMT.
217  {
218  mln_concrete(I)
219  ero = erosion(input, win_hit),
220  dil = dilation(input, win_miss);
221  data::fill(output,
222  fun::p2v::ternary(pw::value(dil) < pw::value(ero),
223  fun::cast<V>(pw::value(ero) - pw::value(dil)),
224  pw::cst(zero_V)));
225  }
226 
227  trace::exiting("morpho::impl::generic::hit_or_miss");
228  return output;
229  }
230 
231  } // end of namespace mln::morpho::impl::generic
232 
233  } // end of mln::morpho::impl
234 
235 
236  namespace internal
237  {
238 
239  template <typename I, typename Wh, typename Wm>
240  inline
241  mln_concrete(I)
242  hit_or_miss_dispatch(trait::image::kind::any,
243  const Image<I>& input,
244  const Window<Wh>& win_hit,
245  const Window<Wm>& win_miss)
246  {
247  return impl::generic::hit_or_miss(input, win_hit, win_miss);
248  }
249 
250  template <typename I, typename Wh, typename Wm>
251  inline
252  mln_concrete(I)
253  hit_or_miss_dispatch(trait::image::kind::logic,
254  const Image<I>& input,
255  const Window<Wh>& win_hit,
256  const Window<Wm>& win_miss)
257  {
258  return impl::hit_or_miss_logic(input, win_hit, win_miss);
259  }
260 
261 
262  template <typename I, typename Wh, typename Wm>
263  inline
264  mln_concrete(I)
265  hit_or_miss_dispatch(const Image<I>& input,
266  const Window<Wh>& win_hit,
267  const Window<Wm>& win_miss)
268  {
269  return hit_or_miss_dispatch(mln_trait_image_kind(I)(),
270  exact(input),
271  exact(win_hit),
272  exact(win_miss));
273  }
274 
275  } // end of namespace mln::morpho::internal
276 
277 
278  template <typename I, typename Wh, typename Wm>
279  inline
280  mln_concrete(I)
281  hit_or_miss(const Image<I>& input,
282  const Window<Wh>& win_hit,
283  const Window<Wm>& win_miss)
284  {
285  trace::entering("morpho::hit_or_miss");
286  internal::hit_or_miss_tests(input, win_hit, win_miss);
287 
288  mln_concrete(I) output = internal::hit_or_miss_dispatch(input,
289  win_hit,
290  win_miss);
291  trace::exiting("morpho::hit_or_miss");
292  return output;
293  }
294 
295 
296  template <typename I, typename Wh, typename Wm>
297  inline
298  mln_concrete(I)
299  hit_or_miss_opening(const Image<I>& input,
300  const Window<Wh>& win_hit,
301  const Window<Wm>& win_miss)
302  {
303  trace::entering("morpho::hit_or_miss_opening");
304  internal::hit_or_miss_tests(input, win_hit, win_miss);
305 
306  mln_concrete(I) output = dilation(internal::hit_or_miss_dispatch(input,
307  win_hit,
308  win_miss),
309  win::sym(win_hit));
310 
311  trace::exiting("morpho::hit_or_miss_opening");
312  return output;
313  }
314 
315 
316  template <typename I, typename Wh, typename Wm>
317  inline
318  mln_concrete(I)
320  const Window<Wh>& win_hit,
321  const Window<Wm>& win_miss)
322  {
323  trace::entering("morpho::hit_or_miss_background_opening");
324  internal::hit_or_miss_tests(input, win_hit, win_miss);
325 
326  mln_concrete(I) output = hit_or_miss_opening(complementation(input),
327  win_miss,
328  win_hit);
329 
330  mln_postcondition(dilation(internal::hit_or_miss_dispatch(input,
331  win_hit,
332  win_miss),
333  win::sym(win_miss)) == output);
334  trace::exiting("morpho::hit_or_miss_background_opening");
335  return output;
336  }
337 
338 
339  template <typename I, typename Wh, typename Wm>
340  inline
341  mln_concrete(I)
342  hit_or_miss_closing(const Image<I>& input,
343  const Window<Wh>& win_hit,
344  const Window<Wm>& win_miss)
345  {
346  trace::entering("morpho::hit_or_miss_closing");
347  internal::hit_or_miss_tests(input, win_hit, win_miss);
348 
349  mln_concrete(I) output =
351  win_hit, win_miss));
352 
353  // FIXME: Postcondition.
354  trace::exiting("morpho::hit_or_miss_closing");
355  return output;
356  }
357 
358 
359  template <typename I, typename Wh, typename Wm>
360  inline
361  mln_concrete(I)
363  const Window<Wh>& win_hit,
364  const Window<Wm>& win_miss)
365  {
366  trace::entering("morpho::hit_or_miss_background_closing");
367  internal::hit_or_miss_tests(input, win_hit, win_miss);
368 
369  mln_concrete(I) output = hit_or_miss_closing(input, win_miss, win_hit);
370 
372  complementation(input),
373  win_hit, win_miss)) == output);
374  trace::exiting("morpho::hit_or_miss_background_closing");
375  return output;
376  }
377 
378 # endif // ! MLN_INCLUDE_ONLY
379 
380  } // end of namespace mln::morpho
381 
382 } // end of namespace mln
383 
384 
385 #endif // ! MLN_MORPHO_HIT_OR_MISS_HH