27 #ifndef APPS_GRAPH_MORPHO_MORPHO_HH
28 # define APPS_GRAPH_MORPHO_MORPHO_HH
40 # include <mln/core/alias/complex_image.hh>
41 # include <mln/core/image/image2d.hh>
43 # include <mln/core/image/dmorph/image_if.hh>
45 # include <mln/core/image/dmorph/extension_ima.hh>
47 # include <mln/core/routine/extend.hh>
48 # include <mln/core/routine/duplicate.hh>
50 # include <mln/core/site_set/p_n_faces_piter.hh>
51 # include <mln/core/image/complex_neighborhoods.hh>
52 # include <mln/core/image/complex_neighborhood_piter.hh>
54 # include <mln/world/inter_pixel/dim2/is_pixel.hh>
55 # include <mln/world/inter_pixel/dim2/is_edge.hh>
56 # include <mln/world/inter_pixel/neighb2d.hh>
58 # include <mln/data/paste.hh>
60 # include <mln/morpho/dilation.hh>
61 # include <mln/morpho/erosion.hh>
63 # include <mln/topo/is_n_face.hh>
100 template <
typename T>
108 return is_vertex_fun;
142 template <
typename G,
typename V>
143 struct graph< mln::complex_image<1, G, V> >
150 return is_vertex_fun;
192 template <
typename I>
195 combine(const mln::Image<I>& vertices_, const mln::Image<I>& edges_)
201 mln_precondition(vertices.domain() == edges.domain());
203 mln::initialize(output, vertices);
205 mln::
data::
paste(vertices | T::is_vertex(), output);
206 mln::
data::
paste(edges | T::is_edge(), output);
232 template <typename I>
235 dilation_e2v(const mln::Image<I>& input)
240 mln::initialize(output, mln::exact(input));
250 template <typename I>
253 erosion_v2e(const mln::Image<I>& input)
258 mln::initialize(output, mln::exact(input));
268 template <typename I>
271 erosion_e2v(const mln::Image<I>& input)
276 mln::initialize(output, mln::exact(input));
286 template <typename I>
289 dilation_v2e(const mln::Image<I>& input)
294 mln::initialize(output, mln::exact(input));
309 template <typename I>
312 dilation_vertex(const mln::Image<I>& input)
314 return dilation_e2v(dilation_v2e(input));
318 template <
typename I>
321 erosion_vertex(const mln::Image<I>& input)
323 return erosion_e2v(erosion_v2e(input));
328 template <
typename I>
331 dilation_edge(const mln::Image<I>& input)
333 return dilation_v2e(dilation_e2v(input));
337 template <
typename I>
340 erosion_edge(const mln::Image<I>& input)
342 return erosion_v2e(erosion_e2v(input));
347 template <
typename I>
350 dilation_graph(const mln::Image<I>& input)
352 return combine(dilation_vertex(input), dilation_edge(input));
356 template <
typename I>
359 erosion_graph(const mln::Image<I>& input)
361 return combine(erosion_vertex(input), erosion_edge(input));
369 template <
typename I>
372 alpha1(const mln::Image<I>& input)
375 mln::initialize(vertices, input);
377 return combine(vertices, input);
380 template <typename I>
383 beta1(const mln::Image<I>& input)
385 return combine(dilation_e2v(input), input);
388 template <
typename I>
391 alpha2(const mln::Image<I>& input)
393 return combine(input, erosion_v2e(input));
396 template <
typename I>
399 beta2(const mln::Image<I>& input)
402 mln::initialize(edges, input);
404 return combine(input, edges);
407 template <typename I>
410 alpha3(const mln::Image<I>& input)
412 return combine(erosion_e2v(input), erosion_v2e(erosion_e2v(input)));
415 template <
typename I>
418 beta3(const mln::Image<I>& input)
420 return combine(dilation_e2v(dilation_v2e(input)), dilation_v2e(input));
429 template <
typename I>
432 opening_vertex(const mln::Image<I>& input)
434 return dilation_vertex(erosion_vertex(input));
438 template <
typename I>
441 closing_vertex(const mln::Image<I>& input)
443 return erosion_vertex(dilation_vertex(input));
448 template <
typename I>
451 opening_edge(const mln::Image<I>& input)
453 return dilation_edge(erosion_edge(input));
457 template <
typename I>
460 closing_edge(const mln::Image<I>& input)
462 return erosion_edge(dilation_edge(input));
467 template <
typename I>
470 opening_graph(const mln::Image<I>& input)
472 return combine(opening_vertex(input), opening_edge(input));
476 template <
typename I>
479 closing_graph(const mln::Image<I>& input)
481 return combine(closing_vertex(input), closing_edge(input));
490 template <
typename I>
493 half_opening_vertex(const mln::Image<I>& input)
495 return dilation_e2v(erosion_v2e(input));
499 template <
typename I>
502 half_closing_vertex(const mln::Image<I>& input)
504 return erosion_e2v(dilation_v2e(input));
509 template <
typename I>
512 half_opening_edge(const mln::Image<I>& input)
514 return dilation_v2e(erosion_e2v(input));
518 template <
typename I>
521 half_closing_edge(const mln::Image<I>& input)
523 return erosion_v2e(dilation_e2v(input));
528 template <
typename I>
531 half_opening_graph(const mln::Image<I>& input)
533 return combine(half_opening_vertex(input), half_opening_edge(input));
537 template <
typename I>
540 half_closing_graph(const mln::Image<I>& input)
542 return combine(half_closing_vertex(input), half_closing_edge(input));
551 template <
typename I>
554 opening(const mln::Image<I>& input,
unsigned lambda)
556 unsigned i = lambda / 2;
557 unsigned j = lambda % 2;
559 for (
unsigned m = 0; m < i; ++m)
560 output = erosion_graph(output);
561 for (
unsigned m = 0; m < j; ++m)
562 output = half_opening_graph(output);
563 for (
unsigned m = 0; m < i; ++m)
564 output = dilation_graph(output);
569 template <typename I>
572 closing(const mln::Image<I>& input,
unsigned lambda)
574 unsigned i = lambda / 2;
575 unsigned j = lambda % 2;
577 for (
unsigned m = 0; m < i; ++m)
578 output = dilation_graph(output);
579 for (
unsigned m = 0; m < j; ++m)
580 output = half_closing_graph(output);
581 for (
unsigned m = 0; m < i; ++m)
582 output = erosion_graph(output);
591 template <typename I>
594 asf(const mln::Image<I>& input,
unsigned lambda)
597 for (
unsigned m = 1; m <= lambda; ++m)
598 output = opening(closing(output, m), m);
602 #endif // ! APPS_GRAPH_MORPHO_MORPHO_HH