* apps/graph-morpho/convert.hh,
* apps/graph-morpho/debug.hh:
New files.
* apps/graph-morpho/io.hh (println): Remove function.
* apps/graph-morpho/samples-image2d.cc,
* apps/graph-morpho/samples-complex1d.cc:
Adjust clients.
* apps/graph-morpho/Makefile.am (noinst_HEADERS):
Add convert.hh and debug.hh.
---
milena/ChangeLog | 14 +++
milena/apps/graph-morpho/Makefile.am | 2 +-
milena/apps/graph-morpho/convert.hh | 117 +++++++++++++++++++++++++
milena/apps/graph-morpho/debug.hh | 99 +++++++++++++++++++++
milena/apps/graph-morpho/io.hh | 81 -----------------
milena/apps/graph-morpho/samples-complex1d.cc | 39 ++++----
milena/apps/graph-morpho/samples-image2d.cc | 38 ++++----
7 files changed, 269 insertions(+), 121 deletions(-)
create mode 100644 milena/apps/graph-morpho/convert.hh
create mode 100644 milena/apps/graph-morpho/debug.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 669d4f9..dcad3c7 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,17 @@
+2009-10-01 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Clean up some conversion and pretty-printing routines in graph-morpho.
+
+ * apps/graph-morpho/convert.hh,
+ * apps/graph-morpho/debug.hh:
+ New files.
+ * apps/graph-morpho/io.hh (println): Remove function.
+ * apps/graph-morpho/samples-image2d.cc,
+ * apps/graph-morpho/samples-complex1d.cc:
+ Adjust clients.
+ * apps/graph-morpho/Makefile.am (noinst_HEADERS):
+ Add convert.hh and debug.hh.
+
2009-09-30 Roland Levillain <roland(a)lrde.epita.fr>
Generic vertices-edges combinator in apps/graph-morpho/.
diff --git a/milena/apps/graph-morpho/Makefile.am b/milena/apps/graph-morpho/Makefile.am
index 70e177e..76fb7d7 100644
--- a/milena/apps/graph-morpho/Makefile.am
+++ b/milena/apps/graph-morpho/Makefile.am
@@ -20,7 +20,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/milena -I$(top_builddir)/milena
APPS_CXXFLAGS = @APPS_CXXFLAGS@
AM_CXXFLAGS = $(APPS_CXXFLAGS)
-noinst_HEADERS = io.hh morpho.hh make_complex2d.hh
+noinst_HEADERS = convert.hh debug.hh io.hh morpho.hh make_complex2d.hh
noinst_PROGRAMS = samples-complex1d samples-image2d asf-complex1d asf-image2d
samples_complex1d_SOURCES = samples-complex1d.cc
diff --git a/milena/apps/graph-morpho/convert.hh b/milena/apps/graph-morpho/convert.hh
new file mode 100644
index 0000000..e51b4ac
--- /dev/null
+++ b/milena/apps/graph-morpho/convert.hh
@@ -0,0 +1,117 @@
+// Copyright (C) 2009 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.
+
+#ifndef APPS_GRAPH_MORPHO_CONVERT_HH
+# define APPS_GRAPH_MORPHO_CONVERT_HH
+
+/// \file
+/// \brief Conversion between various graph/complex image types.
+
+# include <mln/core/alias/complex_image.hh>
+# include <mln/core/image/image2d.hh>
+
+
+namespace convert
+{
+
+ /// Convert an mln::bin_1complex_image2d to an mln::image2d<bool>.
+ inline
+ mln::image2d<bool>
+ to_image2d(const mln::bin_1complex_image2d& input)
+ {
+ using namespace mln;
+
+ const unsigned dim = 1;
+ typedef geom::complex_geometry<dim, point2d> geom_t;
+
+ // Compute the bounding box of the domain of FROM.
+ accu::shape::bbox<point2d> bbox;
+ p_n_faces_fwd_piter<dim, geom_t> v(input.domain(), 0);
+ for_all(v)
+ {
+ mln_site_(geom_t) s(v);
+ // Site S is point2d multi-site and should be a singleton (since V
+ // iterates on vertices).
+ mln_invariant(s.size() == 1);
+ point2d p = s.front();
+ bbox.take(p);
+ }
+ mln::box2d support = bbox;
+
+ image2d<bool> output(box2d(point2d(support.pmin().row() * 2,
+ support.pmin().col() * 2),
+ point2d(support.pmax().row() * 2,
+ support.pmax().col() * 2)));
+ data::fill(output, false);
+
+ // Iterate on vertices.
+ for_all(v)
+ {
+ mln_site_(geom_t) s(v);
+ // Site S is point2d multi-site and should be a singleton (since V
+ // iterates on vertices).
+ mln_invariant(s.size() == 1);
+ point2d p_in = s.front();
+ point2d p_out(p_in.row() * 2, p_in.col() * 2);
+ output(p_out) = input(v);
+ }
+
+ // Iterate on edges.
+ p_n_faces_fwd_piter<dim, geom_t> e(input.domain(), 1);
+ for_all(e)
+ {
+ mln_site_(geom_t) s(e);
+ // Site S is point2d multi-site and should be a pair (since E
+ // iterates on vertices).
+ mln_invariant(s.size() == 2);
+ point2d p1 = s[0];
+ point2d p2 = s[1];
+ if (p1.row() == p2.row())
+ {
+ // Horizontal edge.
+ point2d p_out(p1.row() * 2,
+ p1.col() + p2.col());
+ output(p_out) = input(e);
+ }
+ else if (p1.col() == p2.col())
+ {
+ // Vertical edge.
+ point2d p_out(p1.row() + p2.row(),
+ p1.col() * 2);
+ output(p_out) = input(e);
+ }
+ else
+ {
+ // Edge not fitting in the 2D regular grid canvas, aborting.
+ abort();
+ }
+ }
+ return output;
+ }
+
+} // end of namespace convert
+
+
+#endif // ! APPS_GRAPH_MORPHO_CONVERT_HH
diff --git a/milena/apps/graph-morpho/debug.hh b/milena/apps/graph-morpho/debug.hh
new file mode 100644
index 0000000..5ad3045
--- /dev/null
+++ b/milena/apps/graph-morpho/debug.hh
@@ -0,0 +1,99 @@
+// Copyright (C) 2009 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.
+
+#ifndef APPS_GRAPH_MORPHO_DEBUG_HH
+# define APPS_GRAPH_MORPHO_DEBUG_HH
+
+/// \file
+/// \brief Pretty-printing between graph/complex image types.
+
+# include <mln/core/alias/complex_image.hh>
+# include <mln/core/image/image2d.hh>
+
+# include <mln/debug/println.hh>
+
+# include "apps/graph-morpho/convert.hh"
+
+
+namespace debug
+{
+
+ /// Pretty print an mln::image2d<bool> viewed as a graph.
+ void
+ println_graph(const std::string& message, const mln::image2d<bool>&
input)
+ {
+ // INPUT must have odd numbers of rows and columns.
+ mln_precondition(input.nrows() % 2 == 1);
+ mln_precondition(input.ncols() % 2 == 1);
+
+ mln::image2d<char> output;
+ mln::initialize(output, input);
+ for (int row = input.domain().pmin().row();
+ row <= input.domain().pmax().row(); ++row)
+ {
+ if (row % 2 == 0)
+ // Even row: line with vertices and horizontal edges.
+ for (int col = input.domain().pmin().col();
+ col <= input.domain().pmax().col(); ++col)
+ {
+ mln::point2d p(row, col);
+ if (col % 2 == 0)
+ // Even column: vertex.
+ output(p) = input(p) ? 'O' : '.';
+ else
+ // Odd column: horizontal edge.
+ output(p) = input(p) ? '-' : ' ';
+ }
+ else
+ // Odd row: line with vertical edges and inter-edge spaces
+ // (squares).
+ for (int col = input.domain().pmin().col();
+ col <= input.domain().pmax().col(); ++col)
+ {
+ mln::point2d p(row, col);
+ if (col % 2 == 0)
+ // Even column: vertical edge.
+ output(p) = input(p) ? '|' : ' ';
+ else
+ // Odd column: space.
+ output(p) = ' ';
+ }
+ }
+ mln::debug::println(message, output);
+ }
+
+
+ /// Pretty-print an mln::bin_1complex_image2d viewed as a graph.
+ void
+ println_graph(const std::string& message,
+ const mln::bin_1complex_image2d& input)
+ {
+ println_graph(message, convert::to_image2d(input));
+ }
+
+} // end of namespace debug
+
+
+#endif // ! APPS_GRAPH_MORPHO_DEBUG_HH
diff --git a/milena/apps/graph-morpho/io.hh b/milena/apps/graph-morpho/io.hh
index cdc54bb..8c92949 100644
--- a/milena/apps/graph-morpho/io.hh
+++ b/milena/apps/graph-morpho/io.hh
@@ -153,85 +153,4 @@ make_regular_complex1d_image(const mln::Image<I>& input_)
}
-inline
-void
-println(const std::string& message, const mln::bin_1complex_image2d& ima,
- const mln::box2d& support)
-{
- using namespace mln;
-
- // These are admittedly loose preconditions, but we cannot check
- // much anyway.
- mln_precondition(ima.domain().nfaces_of_dim(0) == support.nsites());
-
- image2d<bool> vertices(support);
- image2d<bool> h_edges(box2d(support.pmin(), support.pmax() - dpoint2d(0, 1)));
- image2d<bool> v_edges(box2d(support.pmin(), support.pmax() - dpoint2d(1, 0)));
-
- const unsigned dim = 1;
- typedef geom::complex_geometry<dim, point2d> geom_t;
-
- // Iterator on vertices.
- p_n_faces_fwd_piter<dim, geom_t> v(ima.domain(), 0);
- for_all(v)
- {
- mln_site_(geom_t) s(v);
- // Site S is point2d multi-site and should be a singleton (since V
- // iterates on vertices).
- mln_invariant(s.size() == 1);
- point2d p = s.front();
- vertices(p) = ima(v);
- }
-
- // Iterator on edges.
- p_n_faces_fwd_piter<dim, geom_t> e(ima.domain(), 1);
- for_all(e)
- {
- mln_site_(geom_t) s(e);
- // Site S is point2d multi-site and should be a pair (since E
- // iterates on vertices).
- mln_invariant(s.size() == 2);
- point2d p1 = s[0];
- point2d p2 = s[1];
- if (p1.row() == p2.row())
- {
- // Horizontal edge.
- h_edges(p1) = ima(e);
- }
- else
- {
- // Vertical edge.
- mln_assertion(p1.col() == p2.col());
- v_edges(p1) = ima(e);
- }
- }
-
- std::cout << message << std::endl;
- for (int row = vertices.domain().pmin().row();
- row <= vertices.domain().pmax().row(); ++row)
- {
- for (int col = vertices.domain().pmin().col();
- col <= vertices.domain().pmax().col(); ++col)
- {
- point2d p(row, col);
- // Vertex.
- std::cout << (vertices(p) ? "O" : ".");
- // Potential horizontal edge on the right of the vertex.
- if (col != vertices.domain().pmax().col())
- std::cout << (h_edges(p) ? " - " : " ");
- }
- std::cout << std::endl;
-
- // Potential vertical edge below the vertices of the current ROW.
- if (row != vertices.domain().pmax().row())
- for (int col = vertices.domain().pmin().col();
- col <= vertices.domain().pmax().col(); ++col)
- {
- point2d p(row, col);
- std::cout << (v_edges(p) ? "| " : " ");
- }
- std::cout << std::endl;
- }
-}
-
#endif // ! APPS_GRAPH_MORPHO_IO_HH
diff --git a/milena/apps/graph-morpho/samples-complex1d.cc
b/milena/apps/graph-morpho/samples-complex1d.cc
index bc8f21b..0b32236 100644
--- a/milena/apps/graph-morpho/samples-complex1d.cc
+++ b/milena/apps/graph-morpho/samples-complex1d.cc
@@ -35,6 +35,8 @@
#include "apps/graph-morpho/morpho.hh"
#include "apps/graph-morpho/io.hh"
+#include "apps/graph-morpho/debug.hh"
+
#include "apps/data.hh"
@@ -57,20 +59,19 @@ int main()
paper from Jean Cousty et al. */
image2d<bool> x_pbm = io::pbm::load(MLN_APPS_DIR
"/graph-morpho/x.pbm");
ima_t x = make_regular_complex1d_image(x_pbm);
- box2d x_box(x_pbm.nrows() / 2 + 1, x_pbm.ncols() / 2 + 1);
- println("x:", x, x_box);
+ ::debug::println_graph("x:", x);
- println("dilation_e2v(x):", dilation_e2v(x), x_box);
- println("erosion_v2e(x):", erosion_v2e(x), x_box);
+ ::debug::println_graph("dilation_e2v(x):", dilation_e2v(x));
+ ::debug::println_graph("erosion_v2e(x):", erosion_v2e(x));
- println("erosion_e2v(x):", erosion_e2v(x), x_box);
- println("dilation_v2e(x):", dilation_v2e(x), x_box);
+ ::debug::println_graph("erosion_e2v(x):", erosion_e2v(x));
+ ::debug::println_graph("dilation_v2e(x):", dilation_v2e(x));
- println("dilation_graph(x):", dilation_graph(x), x_box);
- println("erosion_graph(x):", erosion_graph(x), x_box);
+ ::debug::println_graph("dilation_graph(x):", dilation_graph(x));
+ ::debug::println_graph("erosion_graph(x):", erosion_graph(x));
- println("alpha3(x):", alpha3(x), x_box);
- println("beta3(x):", beta3(x), x_box);
+ ::debug::println_graph("alpha3(x):", alpha3(x));
+ ::debug::println_graph("beta3(x):", beta3(x));
// --------- //
// Filters. //
@@ -79,20 +80,18 @@ int main()
// Create an image corresponding to the graph Y.
image2d<bool> y_pbm = io::pbm::load(MLN_APPS_DIR
"/graph-morpho/y.pbm");
ima_t y = make_regular_complex1d_image(y_pbm);
- box2d y_box(y_pbm.nrows() / 2 + 1, y_pbm.ncols() / 2 + 1);
- println("y:", y, y_box);
+ ::debug::println_graph("y:", y);
- println("opening_graph(y):", opening_graph(y), y_box);
- println("half_opening_graph(y):", half_opening_graph(y), y_box);
- println("beta3(alpha3(y)):", beta3(alpha3(y)), y_box);
+ ::debug::println_graph("opening_graph(y):", opening_graph(y));
+ ::debug::println_graph("half_opening_graph(y):", half_opening_graph(y));
+ ::debug::println_graph("beta3(alpha3(y)):", beta3(alpha3(y)));
// Create an image corresponding to the graph Z.
image2d<bool> z_pbm = io::pbm::load(MLN_APPS_DIR
"/graph-morpho/z.pbm");
ima_t z = make_regular_complex1d_image(z_pbm);
- box2d z_box(z_pbm.nrows() / 2 + 1, z_pbm.ncols() / 2 + 1);
- println("z:", z, z_box);
+ ::debug::println_graph("z:", z);
- println("closing_graph(z):", closing_graph(z), z_box);
- println("half_closing_graph(z):", half_closing_graph(z), z_box);
- println("alpha3(beta3(z)):", alpha3(beta3(z)), z_box);
+ ::debug::println_graph("closing_graph(z):", closing_graph(z));
+ ::debug::println_graph("half_closing_graph(z):", half_closing_graph(z));
+ ::debug::println_graph("alpha3(beta3(z)):", alpha3(beta3(z)));
}
diff --git a/milena/apps/graph-morpho/samples-image2d.cc
b/milena/apps/graph-morpho/samples-image2d.cc
index 455a147..76d5f7f 100644
--- a/milena/apps/graph-morpho/samples-image2d.cc
+++ b/milena/apps/graph-morpho/samples-image2d.cc
@@ -29,11 +29,11 @@
#include <mln/io/pbm/load.hh>
-#include <mln/debug/println.hh>
-
#include "apps/graph-morpho/morpho.hh"
#include "apps/graph-morpho/io.hh"
+#include "apps/graph-morpho/debug.hh"
+
#include "apps/data.hh"
@@ -58,19 +58,19 @@ int main()
/* Create an image corresponding to the graph X of the ISMM 2009
paper from Jean Cousty et al. */
image2d<bool> x = io::pbm::load(MLN_APPS_DIR "/graph-morpho/x.pbm");
- debug::println("x:", x);
+ ::debug::println_graph("x:", x);
- debug::println("dilation_e2v(x):", dilation_e2v(x)) ;
- debug::println("erosion_v2e(x):", erosion_v2e(x));
+ ::debug::println_graph("dilation_e2v(x):", dilation_e2v(x)) ;
+ ::debug::println_graph("erosion_v2e(x):", erosion_v2e(x));
- debug::println("erosion_e2v(x):", erosion_e2v(x));
- debug::println("dilation_v2e(x):", dilation_v2e(x));
+ ::debug::println_graph("erosion_e2v(x):", erosion_e2v(x));
+ ::debug::println_graph("dilation_v2e(x):", dilation_v2e(x));
- debug::println("dilation_graph(x):", dilation_graph(x));
- debug::println("erosion_graph(x):", erosion_graph(x));
+ ::debug::println_graph("dilation_graph(x):", dilation_graph(x));
+ ::debug::println_graph("erosion_graph(x):", erosion_graph(x));
- debug::println("alpha3(x):", alpha3(x));
- debug::println("beta3(x):", beta3(x));
+ ::debug::println_graph("alpha3(x):", alpha3(x));
+ ::debug::println_graph("beta3(x):", beta3(x));
// --------- //
// Filters. //
@@ -78,17 +78,17 @@ int main()
// Create an image corresponding to the graph Y.
image2d<bool> y = io::pbm::load(MLN_APPS_DIR "/graph-morpho/y.pbm");
- debug::println("y:", y);
+ ::debug::println_graph("y:", y);
- debug::println("opening_graph(y):", opening_graph(y));
- debug::println("half_opening_graph(y):", half_opening_graph(y));
- debug::println("beta3(alpha3(y)):", beta3(alpha3(y)));
+ ::debug::println_graph("opening_graph(y):", opening_graph(y));
+ ::debug::println_graph("half_opening_graph(y):", half_opening_graph(y));
+ ::debug::println_graph("beta3(alpha3(y)):", beta3(alpha3(y)));
// Create an image corresponding to the graph Z.
image2d<bool> z = io::pbm::load(MLN_APPS_DIR "/graph-morpho/z.pbm");
- debug::println("z:", z);
+ ::debug::println_graph("z:", z);
- debug::println("closing_graph(z):", closing_graph(z));
- debug::println("half_closing_graph(z):", half_closing_graph(z));
- debug::println("alpha3(beta3(z)):", alpha3(beta3(z)));
+ ::debug::println_graph("closing_graph(z):", closing_graph(z));
+ ::debug::println_graph("half_closing_graph(z):", half_closing_graph(z));
+ ::debug::println_graph("alpha3(beta3(z)):", alpha3(beta3(z)));
}
--
1.6.3.1