27 #ifndef MLN_MORPHO_HIT_OR_MISS_HH
28 # define MLN_MORPHO_HIT_OR_MISS_HH
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>
50 extern bool constrained_hit_or_miss;
57 template <
typename I,
typename Wh,
typename Wm>
60 const Window<Wh>& win_hit, const Window<Wm>& win_miss);
67 template <typename I, typename Wh, typename Wm>
70 const Window<Wh>& win_hit, const Window<Wm>& win_miss);
77 template <typename I, typename Wh, typename Wm>
80 const Window<Wh>& win_hit, const Window<Wm>& win_miss);
87 template <typename I, typename Wh, typename Wm>
90 const Window<Wh>& win_hit, const Window<Wm>& win_miss);
97 template <typename I, typename Wh, typename Wm>
100 const Window<Wh>& win_hit, const Window<Wm>& win_miss);
104 # ifndef MLN_INCLUDE_ONLY
106 # ifndef MLN_WO_GLOBAL_VARS
108 bool constrained_hit_or_miss =
true;
110 # endif // ! MLN_WO_GLOBAL_VARS
115 template <
typename I,
typename Wh,
typename Wm>
118 hit_or_miss_tests(
const Image<I>& input_,
119 const Window<Wh>& win_hit_,
120 const Window<Wm>& win_miss_)
122 const I& input = exact(input_);
123 const Wh& win_hit = exact(win_hit_);
124 const Wm& win_miss = exact(win_miss_);
127 mln_precondition(input.is_valid());
128 mln_precondition((win_hit && win_miss).is_empty());
144 template <
typename I,
typename Wh,
typename Wm>
147 hit_or_miss_logic(const Image<I>& input,
148 const Window<Wh>& win_hit,
149 const Window<Wm>& win_miss)
151 trace::entering(
"morpho::impl::hit_or_miss_logic");
152 internal::hit_or_miss_tests(input, win_hit, win_miss);
154 mln_concrete(I) output = logical::and_(
erosion(input, win_hit),
158 trace::exiting("morpho::impl::hit_or_miss_logic");
169 template <
typename I,
typename Wh,
typename Wm>
173 const Window<Wh>& win_hit_,
174 const Window<Wm>& win_miss_)
176 trace::entering(
"morpho::impl::generic::hit_or_miss");
177 internal::hit_or_miss_tests(input_, win_hit_, win_miss_);
179 const I& input = exact(input_);
180 const Wh& win_hit = exact(win_hit_);
181 const Wm& win_miss = exact(win_miss_);
183 typedef mln_value(I) V;
184 mln_value(I) zero_V = literal::zero;
186 mln_concrete(I) output;
187 initialize(output, input);
189 if (constrained_hit_or_miss)
191 if (win_hit.is_centered())
194 ero_fg =
erosion(input, win_hit),
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)),
202 else if (win_miss.is_centered())
205 ero_bg =
erosion(input, win_miss),
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)),
214 data::fill(output, zero_V);
222 fun::p2v::ternary(pw::value(dil) < pw::value(ero),
223 fun::cast<V>(pw::value(ero) - pw::value(dil)),
227 trace::exiting("morpho::impl::generic::
hit_or_miss");
239 template <
typename I,
typename Wh,
typename Wm>
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)
247 return impl::generic::hit_or_miss(input, win_hit, win_miss);
250 template <
typename I,
typename Wh,
typename Wm>
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)
258 return impl::hit_or_miss_logic(input, win_hit, win_miss);
262 template <
typename I,
typename Wh,
typename Wm>
265 hit_or_miss_dispatch(const Image<I>& input,
266 const Window<Wh>& win_hit,
267 const Window<Wm>& win_miss)
269 return hit_or_miss_dispatch(mln_trait_image_kind(I)(),
278 template <
typename I,
typename Wh,
typename Wm>
282 const
Window<Wh>& win_hit,
283 const
Window<Wm>& win_miss)
285 trace::entering(
"morpho::hit_or_miss");
286 internal::hit_or_miss_tests(input, win_hit, win_miss);
288 mln_concrete(I) output = internal::hit_or_miss_dispatch(input,
291 trace::exiting(
"morpho::hit_or_miss");
296 template <
typename I,
typename Wh,
typename Wm>
300 const
Window<Wh>& win_hit,
301 const
Window<Wm>& win_miss)
303 trace::entering(
"morpho::hit_or_miss_opening");
304 internal::hit_or_miss_tests(input, win_hit, win_miss);
306 mln_concrete(I) output =
dilation(internal::hit_or_miss_dispatch(input,
311 trace::exiting(
"morpho::hit_or_miss_opening");
316 template <
typename I,
typename Wh,
typename Wm>
320 const
Window<Wh>& win_hit,
321 const
Window<Wm>& win_miss)
323 trace::entering(
"morpho::hit_or_miss_background_opening");
324 internal::hit_or_miss_tests(input, win_hit, win_miss);
330 mln_postcondition(
dilation(internal::hit_or_miss_dispatch(input,
334 trace::exiting(
"morpho::hit_or_miss_background_opening");
339 template <
typename I,
typename Wh,
typename Wm>
343 const
Window<Wh>& win_hit,
344 const
Window<Wm>& win_miss)
346 trace::entering(
"morpho::hit_or_miss_closing");
347 internal::hit_or_miss_tests(input, win_hit, win_miss);
349 mln_concrete(I) output =
354 trace::exiting(
"morpho::hit_or_miss_closing");
359 template <
typename I,
typename Wh,
typename Wm>
363 const
Window<Wh>& win_hit,
364 const
Window<Wm>& win_miss)
366 trace::entering(
"morpho::hit_or_miss_background_closing");
367 internal::hit_or_miss_tests(input, win_hit, win_miss);
373 win_hit, win_miss)) == output);
374 trace::exiting(
"morpho::hit_or_miss_background_closing");
378 # endif // ! MLN_INCLUDE_ONLY
385 #endif // ! MLN_MORPHO_HIT_OR_MISS_HH