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