26 #ifndef APPS_GRAPH_MORPHO_MORPHO_HH
27 # define APPS_GRAPH_MORPHO_MORPHO_HH
39 # include <mln/core/alias/complex_image.hh>
40 # include <mln/core/image/image2d.hh>
42 # include <mln/core/image/dmorph/image_if.hh>
44 # include <mln/core/image/dmorph/extension_ima.hh>
46 # include <mln/core/routine/extend.hh>
47 # include <mln/core/routine/duplicate.hh>
49 # include <mln/core/site_set/p_n_faces_piter.hh>
50 # include <mln/core/image/complex_neighborhoods.hh>
51 # include <mln/core/image/complex_neighborhood_piter.hh>
53 # include <mln/world/inter_pixel/dim2/is_pixel.hh>
54 # include <mln/world/inter_pixel/dim2/is_edge.hh>
55 # include <mln/world/inter_pixel/neighb2d.hh>
57 # include <mln/data/paste.hh>
59 # include <mln/morpho/dilation.hh>
60 # include <mln/morpho/erosion.hh>
62 # include <mln/topo/is_n_face.hh>
98 const mln::world::inter_pixel::dim2::is_pixel& is_vertex()
100 static mln::world::inter_pixel::dim2::is_pixel is_vertex_fun;
101 return is_vertex_fun;
106 const mln::world::inter_pixel::dim2::is_edge& is_edge()
108 static mln::world::inter_pixel::dim2::is_edge is_edge_fun;
116 return mln::world::inter_pixel::v2e().win();
123 return mln::world::inter_pixel::e2v().win();
132 template <
typename G,
typename V>
133 struct graph< mln::complex_image<1, G, V> >
140 return is_vertex_fun;
153 const mln::complex_higher_window<1, G>& v2e()
155 static mln::complex_higher_window<1, G> v2e_win;
161 const mln::complex_lower_window<1, G>& e2v()
163 static mln::complex_lower_window<1, G> e2v_win;
182 template <
typename I>
185 combine(const mln::Image<I>& vertices_, const mln::Image<I>& edges_)
188 const I& vertices = mln::exact(vertices_);
189 const I& edges = mln::exact(edges_);
191 mln_precondition(vertices.domain() == edges.domain());
192 mln_concrete(I) output;
193 mln::initialize(output, vertices);
194 mln::
data::fill(output, false);
195 mln::
data::paste(vertices | T::is_vertex(), output);
196 mln::
data::paste(edges | T::is_edge(), output);
222 template <typename I>
225 dilation_e2v(const mln::Image<I>& input)
229 mln_concrete(I) output;
230 mln::initialize(output, mln::exact(input));
231 mln::
data::fill(output, false);
232 mln::
data::paste(mln::morpho::dilation(mln::extend(input | T::is_vertex(),
240 template <typename I>
243 erosion_v2e(const mln::Image<I>& input)
247 mln_concrete(I) output;
248 mln::initialize(output, mln::exact(input));
249 mln::
data::fill(output, false);
250 mln::
data::paste(mln::morpho::erosion(mln::extend(input | T::is_edge(),
258 template <typename I>
261 erosion_e2v(const mln::Image<I>& input)
265 mln_concrete(I) output;
266 mln::initialize(output, mln::exact(input));
267 mln::
data::fill(output, false);
268 mln::
data::paste(mln::morpho::erosion(mln::extend(input | T::is_vertex(),
276 template <typename I>
279 dilation_v2e(const mln::Image<I>& input)
283 mln_concrete(I) output;
284 mln::initialize(output, mln::exact(input));
285 mln::
data::fill(output, false);
286 mln::
data::paste(mln::morpho::dilation(mln::extend(input | T::is_edge(),
299 template <typename I>
302 dilation_vertex(const mln::Image<I>& input)
304 return dilation_e2v(dilation_v2e(input));
308 template <
typename I>
311 erosion_vertex(const mln::Image<I>& input)
313 return erosion_e2v(erosion_v2e(input));
318 template <
typename I>
321 dilation_edge(const mln::Image<I>& input)
323 return dilation_v2e(dilation_e2v(input));
327 template <
typename I>
330 erosion_edge(const mln::Image<I>& input)
332 return erosion_v2e(erosion_e2v(input));
337 template <
typename I>
340 dilation_graph(const mln::Image<I>& input)
342 return combine(dilation_vertex(input), dilation_edge(input));
346 template <
typename I>
349 erosion_graph(const mln::Image<I>& input)
351 return combine(erosion_vertex(input), erosion_edge(input));
359 template <
typename I>
362 alpha1(const mln::Image<I>& input)
364 mln_concrete(I) vertices;
365 mln::initialize(vertices, input);
366 mln::
data::fill(vertices, true);
367 return combine(vertices, input);
370 template <typename I>
373 beta1(const mln::Image<I>& input)
375 return combine(dilation_e2v(input), input);
378 template <
typename I>
381 alpha2(const mln::Image<I>& input)
383 return combine(input, erosion_v2e(input));
386 template <
typename I>
389 beta2(const mln::Image<I>& input)
391 mln_concrete(I) edges;
392 mln::initialize(edges, input);
393 mln::
data::fill(edges, false);
394 return combine(input, edges);
397 template <typename I>
400 alpha3(const mln::Image<I>& input)
402 return combine(erosion_e2v(input), erosion_v2e(erosion_e2v(input)));
405 template <
typename I>
408 beta3(const mln::Image<I>& input)
410 return combine(dilation_e2v(dilation_v2e(input)), dilation_v2e(input));
419 template <
typename I>
422 opening_vertex(const mln::Image<I>& input)
424 return dilation_vertex(erosion_vertex(input));
428 template <
typename I>
431 closing_vertex(const mln::Image<I>& input)
433 return erosion_vertex(dilation_vertex(input));
438 template <
typename I>
441 opening_edge(const mln::Image<I>& input)
443 return dilation_edge(erosion_edge(input));
447 template <
typename I>
450 closing_edge(const mln::Image<I>& input)
452 return erosion_edge(dilation_edge(input));
457 template <
typename I>
460 opening_graph(const mln::Image<I>& input)
462 return combine(opening_vertex(input), opening_edge(input));
466 template <
typename I>
469 closing_graph(const mln::Image<I>& input)
471 return combine(closing_vertex(input), closing_edge(input));
480 template <
typename I>
483 half_opening_vertex(const mln::Image<I>& input)
485 return dilation_e2v(erosion_v2e(input));
489 template <
typename I>
492 half_closing_vertex(const mln::Image<I>& input)
494 return erosion_e2v(dilation_v2e(input));
499 template <
typename I>
502 half_opening_edge(const mln::Image<I>& input)
504 return dilation_v2e(erosion_e2v(input));
508 template <
typename I>
511 half_closing_edge(const mln::Image<I>& input)
513 return erosion_v2e(dilation_e2v(input));
518 template <
typename I>
521 half_opening_graph(const mln::Image<I>& input)
523 return combine(half_opening_vertex(input), half_opening_edge(input));
527 template <
typename I>
530 half_closing_graph(const mln::Image<I>& input)
532 return combine(half_closing_vertex(input), half_closing_edge(input));
541 template <
typename I>
544 opening(const mln::Image<I>& input,
unsigned lambda)
546 unsigned i = lambda / 2;
547 unsigned j = lambda % 2;
548 mln_concrete(I) output = mln::duplicate(input);
549 for (
unsigned m = 0; m < i; ++m)
550 output = erosion_graph(output);
551 for (
unsigned m = 0; m < j; ++m)
552 output = half_opening_graph(output);
553 for (
unsigned m = 0; m < i; ++m)
554 output = dilation_graph(output);
559 template <typename I>
562 closing(const mln::Image<I>& input,
unsigned lambda)
564 unsigned i = lambda / 2;
565 unsigned j = lambda % 2;
566 mln_concrete(I) output = mln::duplicate(input);
567 for (
unsigned m = 0; m < i; ++m)
568 output = dilation_graph(output);
569 for (
unsigned m = 0; m < j; ++m)
570 output = half_closing_graph(output);
571 for (
unsigned m = 0; m < i; ++m)
572 output = erosion_graph(output);
581 template <typename I>
584 asf(const mln::Image<I>& input,
unsigned lambda)
586 mln_concrete(I) output = mln::duplicate(input);
587 for (
unsigned m = 1; m <= lambda; ++m)
588 output = opening(closing(output, m), m);
592 #endif // ! APPS_GRAPH_MORPHO_MORPHO_HH