olena-2.0-7-g75d065e Split apps/papers/levillain.09.ismm/graph.cc.

* apps/papers/levillain.09.ismm/graph.cc: Misc. changes. (mln::influence_zones) (mln::io::neato::save): Move functions... * apps/papers/levillain.09.ismm/influence_zones.hh, * apps/papers/levillain.09.ismm/io.hh: ...here (new files). * apps/papers/levillain.09.ismm/Makefile.am (noinst_HEADERS): Add io.hh and influence_zones.hh --- milena/ChangeLog | 14 + milena/apps/papers/levillain.09.ismm/Makefile.am | 7 +- milena/apps/papers/levillain.09.ismm/graph.cc | 259 +------------------- .../papers/levillain.09.ismm/influence_zones.hh} | 85 ++++---- milena/apps/papers/levillain.09.ismm/io.hh | 242 ++++++++++++++++++ 5 files changed, 315 insertions(+), 292 deletions(-) copy milena/{mln/literal/black.hh => apps/papers/levillain.09.ismm/influence_zones.hh} (55%) create mode 100644 milena/apps/papers/levillain.09.ismm/io.hh diff --git a/milena/ChangeLog b/milena/ChangeLog index 544cc30..d79c220 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,19 @@ 2011-10-04 Roland Levillain <roland@lrde.epita.fr> + Split apps/papers/levillain.09.ismm/graph.cc. + + * apps/papers/levillain.09.ismm/graph.cc: Misc. changes. + (mln::influence_zones) + (mln::io::neato::save): + Move functions... + * apps/papers/levillain.09.ismm/influence_zones.hh, + * apps/papers/levillain.09.ismm/io.hh: + ...here (new files). + * apps/papers/levillain.09.ismm/Makefile.am (noinst_HEADERS): + Add io.hh and influence_zones.hh + +2011-10-04 Roland Levillain <roland@lrde.epita.fr> + Handle the case of filling an empty border. * mln/border/fill.hh (mln::border::impl::fill_size_1): Here. diff --git a/milena/apps/papers/levillain.09.ismm/Makefile.am b/milena/apps/papers/levillain.09.ismm/Makefile.am index ec5d328..ac583f8 100644 --- a/milena/apps/papers/levillain.09.ismm/Makefile.am +++ b/milena/apps/papers/levillain.09.ismm/Makefile.am @@ -1,4 +1,5 @@ -# Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE). +# Copyright (C) 2008, 2009, 2011 EPITA Research and Development +# Laboratory (LRDE). # # This file is part of Olena. # @@ -22,7 +23,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/milena -I$(top_builddir)/milena APPS_CXXFLAGS = @APPS_CXXFLAGS@ AM_CXXFLAGS = $(APPS_CXXFLAGS) -noinst_HEADERS = chain.hh +noinst_HEADERS = chain.hh io.hh influence_zones.hh noinst_PROGRAMS = image2d graph complex image2d_SOURCES = image2d.cc @@ -37,6 +38,8 @@ dist_noinst_DATA = seeds.pgm m283-c.off noinst_DATA = lena-s.ppm graph-s.png m283-s.off MOSTLYCLEANFILES = $(noinst_DATA) graph-s.neato +# FIXME: Also generate intermediate images (gradients, etc.). + lena-s.ppm: $(top_srcdir)/milena/img/lena.pgm image2d$(EXEEXT) ./image2d$(EXEEXT) $< 1000 $@ diff --git a/milena/apps/papers/levillain.09.ismm/graph.cc b/milena/apps/papers/levillain.09.ismm/graph.cc index bd6f983..714037d 100644 --- a/milena/apps/papers/levillain.09.ismm/graph.cc +++ b/milena/apps/papers/levillain.09.ismm/graph.cc @@ -24,16 +24,16 @@ // executable file might be covered by the GNU General Public License. #include <iostream> -#include <iomanip> #include <vector> #include <mln/core/image/image2d.hh> -#include <mln/core/routine/duplicate.hh> #include <mln/core/alias/neighb2d.hh> -#include <mln/core/site_set/p_queue_fast.hh> + #include <mln/labeling/blobs.hh> #include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/data/stretch.hh> #include <mln/debug/println.hh> #include <mln/draw/line.hh> #include <mln/pw/all.hh> @@ -57,251 +57,11 @@ #include <mln/morpho/gradient.hh> #include <mln/labeling/colorize.hh> +#include "io.hh" +#include "influence_zones.hh" #include "chain.hh" -// FIXME: Copied and adjusted from pics/graph.cc; factor. - -namespace mln -{ - - template <typename I, typename N> - mln_concrete(I) - influence_zones(const I& input, const N& nbh) - { - mln_concrete(I) output = duplicate(input); - - p_queue_fast<mln_site(I)> q; - - { - // Initialization. - mln_piter(I) p(input.domain()); - mln_niter(N) n(nbh, p); - for_all(p) - if (input(p) != 0) - for_all(n) if (input.has(n)) - if (input(n) == 0) - { - q.push(p); - break; - } - } - { - // Body. - mln_site(I) p; - mln_niter(N) n(nbh, p); - while (! q.is_empty()) - { - p = q.pop_front(); - mln_invariant(output(p) != 0); - for_all(n) if (input.has(n)) - if (output(n) == 0) - { - output(n) = output(p); - q.push(n); - } - } - } - - return output; - - } - - - namespace io - { - - namespace neato - { - - /* FIXME: This is just the gray-level version. Handle other value - types as well. */ - void - save(const complex_image<1, discrete_plane_1complex_geometry, - value::int_u8>& ima, - const std::string& filename, - const std::string& bgcolor = "#0000C0", - const std::string& fontcolor = "#0000C0", - bool empty_vertex_label = true) - { - typedef value::int_u8 V; - typedef complex_image<1, discrete_plane_1complex_geometry, V> I; - const unsigned D = 1; - typedef discrete_plane_1complex_geometry G; - - std::ofstream g(filename.c_str()); - g << "graph wst" << std::endl - << "{" << std::endl - << " graph [bgcolor = \"" << bgcolor << "\"]" << std::endl - << " edge [color = \"#FFFFFF\"]" << std::endl - << " node [color = \"#FFFFFF\", height=\"5\", width=\"5\"," - << " fontsize=\"100\", fontcolor = \"" << fontcolor << "\"]" - << std::endl; - - // Vertices. - p_n_faces_fwd_piter<D, G> v(ima.domain(), 0); - typedef complex_higher_neighborhood<D, G> e_nbh_t; - e_nbh_t e_nbh; - for_all(v) - { - V vertex_color = ima(v); - std::ostringstream vertex_color_str; - // FIXME: Only valid for gray-level images. - vertex_color_str << '#' - << std::hex - << std::setfill('0') - << std::setw(2) << vertex_color - << std::setw(2) << vertex_color - << std::setw(2) << vertex_color - << std::dec; - - g << " v" << v.unproxy_().face_id() - << " [pos = \"" - << std::fixed << std::setprecision(1) - << (float)v.to_site().front()[1] << ", " - << -(float)v.to_site().front()[0] - << "\", color = \"" << vertex_color_str.str() - << "\", fillcolor = \"" << vertex_color_str.str() - << "\", pin = \"true\", style=\"filled,setlinewidth(3)\""; - if (empty_vertex_label) - g << ", label = \"\""; - g << "];" - << std::endl; - } - - // Edges. - p_n_faces_fwd_piter<D, G> e(ima.domain(), 1); - typedef complex_lower_neighborhood<D, G> v_nbh_t; - v_nbh_t v_nbh; - mln_niter_(v_nbh_t) adj_v(v_nbh, e); - for_all(e) - { - V edge_color = ima(e); - std::ostringstream edge_color_str; - edge_color_str << '#' - << std::hex - << std::setfill('0') - << std::setw(2) << edge_color - << std::setw(2) << edge_color - << std::setw(2) << edge_color - << std::dec; - - // Adjacent vertices. - adj_v.start(); - topo::face<1> v1 = adj_v.unproxy_().face(); - point2d p1 = adj_v.to_site().front(); - adj_v.next(); - topo::face<1> v2 = adj_v.unproxy_().face(); - point2d p2 = adj_v.to_site().front(); - adj_v.next(); - mln_invariant(!adj_v.is_valid()); - - g << " v" << v1.face_id() << " -- v" << v2.face_id() << " "; - g << "[color = \"" << edge_color_str.str() - << "\", style=\"setlinewidth(10)\"];" << std::endl; - } - - g << "}" << std::endl; - g.close(); - } - - // FIXME: Factor with the previous version. - void - save(const complex_image<1, discrete_plane_1complex_geometry, - value::rgb8>& ima, - const std::string& filename, - const std::string& bgcolor = "#0000C0", - const std::string& fontcolor = "#0000C0", - bool empty_vertex_label = true) - { - typedef value::rgb8 V; - typedef complex_image<1, discrete_plane_1complex_geometry, V> I; - const unsigned D = 1; - typedef discrete_plane_1complex_geometry G; - - std::ofstream g(filename.c_str()); - g << "graph wst" << std::endl - << "{" << std::endl - << " graph [bgcolor = \"" << bgcolor << "\"]" << std::endl - << " edge [color = \"#FFFFFF\"]" << std::endl - << " node [color = \"#FFFFFF\", height=\"5\", width=\"5\"," - << " fontsize=\"100\", fontcolor = \"" << fontcolor << "\"]" - << std::endl; - - // Vertices. - p_n_faces_fwd_piter<D, G> v(ima.domain(), 0); - typedef complex_higher_neighborhood<D, G> e_nbh_t; - e_nbh_t e_nbh; - for_all(v) - { - V vertex_color = ima(v); - std::ostringstream vertex_color_str; - // FIXME: Only valid for gray-level images. - vertex_color_str << '#' - << std::hex - << std::setfill('0') - << std::setw(2) << vertex_color.red() - << std::setw(2) << vertex_color.green() - << std::setw(2) << vertex_color.blue() - << std::dec; - - g << " v" << v.unproxy_().face_id() - << " [pos = \"" - << std::fixed << std::setprecision(1) - << (float)v.to_site().front()[1] << ", " - << -(float)v.to_site().front()[0] - << "\", color = \"" << vertex_color_str.str() - << "\", fillcolor = \"" << vertex_color_str.str() - << "\", pin = \"true\", style=\"filled,setlinewidth(3)\""; - if (empty_vertex_label) - g << ", label = \"\""; - g << "];" - << std::endl; - } - - // Edges. - p_n_faces_fwd_piter<D, G> e(ima.domain(), 1); - typedef complex_lower_neighborhood<D, G> v_nbh_t; - v_nbh_t v_nbh; - mln_niter_(v_nbh_t) adj_v(v_nbh, e); - for_all(e) - { - V edge_color = ima(e); - std::ostringstream edge_color_str; - edge_color_str << '#' - << std::hex - << std::setfill('0') - << std::setw(2) << edge_color.red() - << std::setw(2) << edge_color.green() - << std::setw(2) << edge_color.blue() - << std::dec; - - // Adjacent vertices. - adj_v.start(); - topo::face<1> v1 = adj_v.unproxy_().face(); - point2d p1 = adj_v.to_site().front(); - adj_v.next(); - topo::face<1> v2 = adj_v.unproxy_().face(); - point2d p2 = adj_v.to_site().front(); - adj_v.next(); - mln_invariant(!adj_v.is_valid()); - - g << " v" << v1.face_id() << " -- v" << v2.face_id() << " "; - g << "[color = \"" << edge_color_str.str() - << "\", style=\"setlinewidth(10)\"];" << std::endl; - } - - g << "}" << std::endl; - g.close(); - } - - } // end of namespace mln::io::neato - - } // end of namespace mln::io - -} // end of namespace mln - - // FIXME: Clean up and move into Milena? mln::int_u8_1complex_image2d make_complex_image(const mln::image2d<mln::value::int_u8>& input) @@ -331,6 +91,9 @@ make_complex_image(const mln::image2d<mln::value::int_u8>& input) data::paste(iz, IZ); } +#if 0 + io::pgm::save (data::stretch(mln::value::int_u8(), iz), "iz.pgm"); +#endif // Make graph/complex. @@ -480,14 +243,16 @@ int main(int argc, char* argv[]) // Input image computed from the graph of influence zones (IZ) of seeds. typedef int_u8_graph_image2d ima_t; ima_t ima = make_complex_image(seeds); - io::neato::save(ima, "apps/graph.neato"); +#if 0 + io::neato::save(ima, "graph.neato"); +#endif // Gradient. input g = morpho::gradient(ima, make_elt_win(ima)); #if 0 // FIXME: get the name as argument. - io::neato::save(g, "apps/graph-g.neato"); + io::neato::save(g, "graph-g.neato"); #endif // Chain. diff --git a/milena/mln/literal/black.hh b/milena/apps/papers/levillain.09.ismm/influence_zones.hh similarity index 55% copy from milena/mln/literal/black.hh copy to milena/apps/papers/levillain.09.ismm/influence_zones.hh index ab05cae..353b16e 100644 --- a/milena/mln/literal/black.hh +++ b/milena/apps/papers/levillain.09.ismm/influence_zones.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2007, 2008, 2009 EPITA Research and Development +// Copyright (C) 2008, 2009, 2011 EPITA Research and Development // Laboratory (LRDE) // // This file is part of Olena. @@ -24,62 +24,61 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -#ifndef MLN_LITERAL_BLACK_HH -# define MLN_LITERAL_BLACK_HH - /// \file -/// \brief Definition of the 'black' literal. +/// \brief Computation of the influence zones of the objects of an +/// image. + +// FIXME: Refactor and move into the library. -# include <mln/core/concept/literal.hh> +#include <mln/core/routine/duplicate.hh> + +#include <mln/core/site_set/p_queue_fast.hh> namespace mln { - namespace literal + // FIXME: Add Image and Neighborhood concept constraints. + template <typename I, typename N> + inline + mln_concrete(I) + influence_zones(const I& input, const N& nbh) { + mln_concrete(I) output = duplicate(input); - /// Type of literal black. - struct black_t : public Literal<black_t> - { -# ifdef MLN_NEW_VALUE_TYPES - operator float() const; - operator double() const; -# endif // MLN_NEW_VALUE_TYPES - }; - - - /// Literal black. - extern const black_t& black; - - -# ifndef MLN_INCLUDE_ONLY + p_queue_fast<mln_site(I)> q; -# ifndef MLN_WO_GLOBAL_VARS - - const black_t& black = black_t(); - -# endif - -# ifdef MLN_NEW_VALUE_TYPES - inline - black_t::operator float() const { - return 0.f; + // Initialization. + mln_piter(I) p(input.domain()); + mln_niter(N) n(nbh, p); + for_all(p) + if (input(p) != 0) + for_all(n) if (input.has(n)) + if (input(n) == 0) + { + q.push(p); + break; + } } - - inline - black_t::operator double() const { - return 0.; + // Body. + mln_site(I) p; + mln_niter(N) n(nbh, p); + while (! q.is_empty()) + { + p = q.pop_front(); + mln_invariant(output(p) != 0); + for_all(n) if (input.has(n)) + if (output(n) == 0) + { + output(n) = output(p); + q.push(n); + } + } } -# endif // MLN_NEW_VALUE_TYPES -# endif // ! MLN_INCLUDE_ONLY - - } // end of namespace mln::literal + return output; + } } // end of namespace mln - - -#endif // ! MLN_LITERAL_BLACK_HH diff --git a/milena/apps/papers/levillain.09.ismm/io.hh b/milena/apps/papers/levillain.09.ismm/io.hh new file mode 100644 index 0000000..d39aae6 --- /dev/null +++ b/milena/apps/papers/levillain.09.ismm/io.hh @@ -0,0 +1,242 @@ +// Copyright (C) 2008, 2009, 2011 EPITA Research and Development +// Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +/// \file +/// \brief Some neato (Graphviz) I/O routines. + +// FIXME: Refactor and move into the library. + +#include <fstream> +#include <sstream> +#include <iomanip> + +#include <string> + +#include <mln/core/image/complex_image.hh> +#include <mln/core/alias/complex_geometry.hh> + +#include <mln/core/image/complex_neighborhoods.hh> +#include <mln/core/image/complex_neighborhood_piter.hh> + +#include <mln/value/int_u8.hh> + + +namespace mln +{ + + namespace io + { + + namespace neato + { + + /* FIXME: This is just the gray-level version. Handle other value + types as well. */ + // FIXME: Use an alias instead of the long type name. + void + save(const complex_image<1, discrete_plane_1complex_geometry, + value::int_u8>& ima, + const std::string& filename, + const std::string& bgcolor = "#0000C0", + const std::string& fontcolor = "#0000C0", + bool empty_vertex_label = true) + { + typedef value::int_u8 V; + typedef complex_image<1, discrete_plane_1complex_geometry, V> I; + const unsigned D = 1; + typedef discrete_plane_1complex_geometry G; + + std::ofstream g(filename.c_str()); + g << "graph wst" << std::endl + << "{" << std::endl + << " graph [bgcolor = \"" << bgcolor << "\"]" << std::endl + << " edge [color = \"#FFFFFF\"]" << std::endl + << " node [color = \"#FFFFFF\", height=\"5\", width=\"5\"," + << " fontsize=\"100\", fontcolor = \"" << fontcolor << "\"]" + << std::endl; + + // Vertices. + p_n_faces_fwd_piter<D, G> v(ima.domain(), 0); + typedef complex_higher_neighborhood<D, G> e_nbh_t; + e_nbh_t e_nbh; + for_all(v) + { + V vertex_color = ima(v); + std::ostringstream vertex_color_str; + // FIXME: Only valid for gray-level images. + vertex_color_str << '#' + << std::hex + << std::setfill('0') + << std::setw(2) << vertex_color + << std::setw(2) << vertex_color + << std::setw(2) << vertex_color + << std::dec; + + g << " v" << v.unproxy_().face_id() + << " [pos = \"" + << std::fixed << std::setprecision(1) + << (float)v.to_site().front()[1] << ", " + << -(float)v.to_site().front()[0] + << "\", color = \"" << vertex_color_str.str() + << "\", fillcolor = \"" << vertex_color_str.str() + << "\", pin = \"true\", style=\"filled,setlinewidth(3)\""; + if (empty_vertex_label) + g << ", label = \"\""; + g << "];" + << std::endl; + } + + // Edges. + p_n_faces_fwd_piter<D, G> e(ima.domain(), 1); + typedef complex_lower_neighborhood<D, G> v_nbh_t; + v_nbh_t v_nbh; + mln_niter_(v_nbh_t) adj_v(v_nbh, e); + for_all(e) + { + V edge_color = ima(e); + std::ostringstream edge_color_str; + edge_color_str << '#' + << std::hex + << std::setfill('0') + << std::setw(2) << edge_color + << std::setw(2) << edge_color + << std::setw(2) << edge_color + << std::dec; + + // Adjacent vertices. + adj_v.start(); + topo::face<1> v1 = adj_v.unproxy_().face(); + point2d p1 = adj_v.to_site().front(); + adj_v.next(); + topo::face<1> v2 = adj_v.unproxy_().face(); + point2d p2 = adj_v.to_site().front(); + adj_v.next(); + mln_invariant(!adj_v.is_valid()); + + g << " v" << v1.face_id() << " -- v" << v2.face_id() << " "; + g << "[color = \"" << edge_color_str.str() + << "\", style=\"setlinewidth(10)\"];" << std::endl; + } + + g << "}" << std::endl; + g.close(); + } + + // FIXME: Factor with the previous version. + void + save(const complex_image<1, discrete_plane_1complex_geometry, + value::rgb8>& ima, + const std::string& filename, + const std::string& bgcolor = "#0000C0", + const std::string& fontcolor = "#0000C0", + bool empty_vertex_label = true) + { + typedef value::rgb8 V; + typedef complex_image<1, discrete_plane_1complex_geometry, V> I; + const unsigned D = 1; + typedef discrete_plane_1complex_geometry G; + + std::ofstream g(filename.c_str()); + g << "graph wst" << std::endl + << "{" << std::endl + << " graph [bgcolor = \"" << bgcolor << "\"]" << std::endl + << " edge [color = \"#FFFFFF\"]" << std::endl + << " node [color = \"#FFFFFF\", height=\"5\", width=\"5\"," + << " fontsize=\"100\", fontcolor = \"" << fontcolor << "\"]" + << std::endl; + + // Vertices. + p_n_faces_fwd_piter<D, G> v(ima.domain(), 0); + typedef complex_higher_neighborhood<D, G> e_nbh_t; + e_nbh_t e_nbh; + for_all(v) + { + V vertex_color = ima(v); + std::ostringstream vertex_color_str; + // FIXME: Only valid for gray-level images. + vertex_color_str << '#' + << std::hex + << std::setfill('0') + << std::setw(2) << vertex_color.red() + << std::setw(2) << vertex_color.green() + << std::setw(2) << vertex_color.blue() + << std::dec; + + g << " v" << v.unproxy_().face_id() + << " [pos = \"" + << std::fixed << std::setprecision(1) + << (float)v.to_site().front()[1] << ", " + << -(float)v.to_site().front()[0] + << "\", color = \"" << vertex_color_str.str() + << "\", fillcolor = \"" << vertex_color_str.str() + << "\", pin = \"true\", style=\"filled,setlinewidth(3)\""; + if (empty_vertex_label) + g << ", label = \"\""; + g << "];" + << std::endl; + } + + // Edges. + p_n_faces_fwd_piter<D, G> e(ima.domain(), 1); + typedef complex_lower_neighborhood<D, G> v_nbh_t; + v_nbh_t v_nbh; + mln_niter_(v_nbh_t) adj_v(v_nbh, e); + for_all(e) + { + V edge_color = ima(e); + std::ostringstream edge_color_str; + edge_color_str << '#' + << std::hex + << std::setfill('0') + << std::setw(2) << edge_color.red() + << std::setw(2) << edge_color.green() + << std::setw(2) << edge_color.blue() + << std::dec; + + // Adjacent vertices. + adj_v.start(); + topo::face<1> v1 = adj_v.unproxy_().face(); + point2d p1 = adj_v.to_site().front(); + adj_v.next(); + topo::face<1> v2 = adj_v.unproxy_().face(); + point2d p2 = adj_v.to_site().front(); + adj_v.next(); + mln_invariant(!adj_v.is_valid()); + + g << " v" << v1.face_id() << " -- v" << v2.face_id() << " "; + g << "[color = \"" << edge_color_str.str() + << "\", style=\"setlinewidth(10)\"];" << std::endl; + } + + g << "}" << std::endl; + g.close(); + } + + } // end of namespace mln::io::neato + + } // end of namespace mln::io + +} // end of namespace mln -- 1.7.2.5
participants (1)
-
Roland Levillain