* apps/papers/levillain.09.ismm/classif-graph.cc: New.
* apps/papers/levillain.09.ismm/Makefile.am (noinst_PROGRAMS):
Add classif-graph.
(classif_graph_SOURCES): New.
(noinst_DATA): Add classwst-graph.ppm.
(classwst-graph.ppm): New target.
---
milena/ChangeLog | 11 ++
milena/apps/papers/levillain.09.ismm/Makefile.am | 15 ++-
.../{classif-1complex.cc => classif-graph.cc} | 162 +++++++++-----------
3 files changed, 93 insertions(+), 95 deletions(-)
copy milena/apps/papers/levillain.09.ismm/{classif-1complex.cc => classif-graph.cc}
(61%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index f25821c..bad4207 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,14 @@
+2011-10-11 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Graph-based version of the classification example.
+
+ * apps/papers/levillain.09.ismm/classif-graph.cc: New.
+ * apps/papers/levillain.09.ismm/Makefile.am (noinst_PROGRAMS):
+ Add classif-graph.
+ (classif_graph_SOURCES): New.
+ (noinst_DATA): Add classwst-graph.ppm.
+ (classwst-graph.ppm): New target.
+
2011-10-10 Roland Levillain <roland(a)lrde.epita.fr>
Rename apps/papers/levillain.09.ismm/classif.cc.
diff --git a/milena/apps/papers/levillain.09.ismm/Makefile.am
b/milena/apps/papers/levillain.09.ismm/Makefile.am
index 3651c4f..79814de 100644
--- a/milena/apps/papers/levillain.09.ismm/Makefile.am
+++ b/milena/apps/papers/levillain.09.ismm/Makefile.am
@@ -25,12 +25,14 @@ AM_CXXFLAGS = $(APPS_CXXFLAGS)
noinst_HEADERS = chain.hh io.hh influence_zones.hh
-noinst_PROGRAMS = image2d graph complex classif-1complex
+noinst_PROGRAMS = image2d graph complex classif-graph classif-1complex
image2d_SOURCES = image2d.cc
graph_SOURCES = graph.cc
complex_SOURCES = complex.cc
-# This example has been shown in the ISMM 2009 presentation only (not
-# in the paper).
+# This example (implemented both with graph- and 1-complex-based
+# images) has been shown in the ISMM 2009 presentation only (not in
+# the paper).
+classif_graph_SOURCES = classif-graph.cc
classif_1complex_SOURCES = classif-1complex.cc
# Input images.
@@ -38,7 +40,9 @@ classif_1complex_SOURCES = classif-1complex.cc
dist_noinst_DATA = seeds.pgm m283-c.off classseedsi.pbm
# Output images.
-noinst_DATA = lena-s.ppm graph-s.png m283-s.off classwst-1complex.ppm
+noinst_DATA = \
+ lena-s.ppm graph-s.png m283-s.off \
+ classwst-graph.ppm classwst-1complex.ppm
MOSTLYCLEANFILES = $(noinst_DATA) graph-s.neato
# FIXME: Also generate intermediate images (gradients, etc.).
@@ -54,5 +58,8 @@ graph-s.neato: seeds.pgm graph$(EXEEXT)
m283-s.off: m283-c.off complex$(EXEEXT)
./complex$(EXEEXT) $< 100 $@
+classwst-graph.ppm: classseedsi.pbm classif-graph$(EXEEXT)
+ ./classif-graph$(EXEEXT) $< 4 $@
+
classwst-1complex.ppm: classseedsi.pbm classif-1complex$(EXEEXT)
./classif-1complex$(EXEEXT) $< 4 $@
diff --git a/milena/apps/papers/levillain.09.ismm/classif-1complex.cc
b/milena/apps/papers/levillain.09.ismm/classif-graph.cc
similarity index 61%
copy from milena/apps/papers/levillain.09.ismm/classif-1complex.cc
copy to milena/apps/papers/levillain.09.ismm/classif-graph.cc
index 43853e3..36a6369 100644
--- a/milena/apps/papers/levillain.09.ismm/classif-1complex.cc
+++ b/milena/apps/papers/levillain.09.ismm/classif-graph.cc
@@ -41,12 +41,9 @@
#include <mln/value/int_u8.hh>
#include <mln/core/alias/point2d.hh>
-#include <mln/core/site_set/p_faces.hh>
-#include <mln/core/image/complex_image.hh>
-#include <mln/core/alias/complex_image.hh>
+#include <mln/util/site_pair.hh>
-#include <mln/core/image/complex_neighborhoods.hh>
-#include <mln/core/image/complex_neighborhood_piter.hh>
+#include <mln/core/image/edge_image.hh>
#include <mln/data/fill.hh>
#include <mln/norm/l2.hh>
@@ -56,13 +53,15 @@
#include "influence_zones.hh"
#include "chain.hh"
+/* FIXME: Introduce aliases for common specializations of graph images
+ such as the return type of make_graph_image. */
/** Create a 1-complex (graph) image from the connected components of
\a seeds. The values associated to a 1-face (edge) is equal to
the L2-distance between its two adjacent vertices. The values on
a 0-face (vertex) is set to 0. */
-mln::int_u8_1complex_image2d
-make_complex_image(const mln::image2d<bool>& seeds)
+mln::edge_image<mln::util::site_pair<mln::point2d>, mln::value::int_u8>
+make_graph_image(const mln::image2d<bool>& seeds)
{
using namespace mln;
using mln::value::int_u8;
@@ -98,9 +97,9 @@ make_complex_image(const mln::image2d<bool>& seeds)
#endif
}
- /*--------------------------------.
- | Construction of the 1-complex. |
- `--------------------------------*/
+ /*----------------------------.
+ | Construction of the graph. |
+ `----------------------------*/
// Adjacency matrix.
std::vector< std::vector<bool> > adj(nlabels + 1);
@@ -129,67 +128,68 @@ make_complex_image(const mln::image2d<bool>& seeds)
}
}
+ // Graph structure.
+ typedef util::graph G;
+ G g;
- const unsigned D = 1;
- // 1-complex data structure.
- topo::complex<D> c;
+ // Vertices. Note that vertex 0 corresponds to the background, and
+ // is therefore not connected to any other vertex.
+ g.add_vertices(nlabels + 1);
- typedef point2d P;
- // Geometry (spatial locations) associated to the complex's faces.
- typedef geom::complex_geometry<D, P> G;
- G geom;
-
- // Convenience typedefs.
- typedef topo::n_face<0, D> vertex;
- typedef topo::n_face<1, D> edge;
+ // Sites associated to edges.
+ typedef util::site_pair<point2d> site_t;
+ typedef fun::i2v::array<site_t> fsite_t;
+ fsite_t sites;
{
- // 0-faces (vertices).
- std::vector<vertex> v;
+ // Vertices locations.
+ std::vector<point2d> v_site (nlabels + 1, point2d(0,0));
{
box2d::piter p(label.domain());
for_all(p)
if (label(p) != 0)
- {
- geom.add_location(p);
- v.push_back(c.add_face());
- }
+ v_site[label(p)] = p;
}
- std::cout << "v size = " << v.size() << std::endl;
+ std::cout << "v_site size = " << v_site.size() <<
std::endl;
- // 1-faces (edges).
- std::vector<edge> e;
+ // Edges.
+ std::vector<util::edge_id_t> e;
{
for (unsigned l = 1; l <= nlabels; ++l)
for (unsigned ll = l + 1; ll <= nlabels; ++ll)
if (adj[l][ll])
- // Create an edge as an oriented (``algebraic'') face.
- e.push_back(c.add_face(-v[l-1] + v[ll-1]));
+ {
+ sites.append(site_t(v_site[l], v_site[ll]));
+ e.push_back(g.add_edge(l, ll));
+ }
}
std::cout << "e size = " << e.size() << std::endl;
}
- /*-------------------------.
- | Complex-based site set. |
- `-------------------------*/
-
- p_complex<D, G> pc(c, geom);
-
- /*----------------------.
- | Complex-based image. |
- `----------------------*/
-
- // An image type built on a 1-complex with int_u8 values on each
- // face (both vertices and edges).
- typedef complex_image<D, G, int_u8> dist_ima_t;
-
- // Create and initialize an image based on PC.
- dist_ima_t dist_ima(pc);
+ /*-------------.
+ | Edge image. |
+ `-------------*/
+
+ /* FIXME: edge_image should provide a ctor to initialize an instance
+ with just a graph an an edge-to-site function (but no values).
+ Currently this is not possible. Hence the ``adhead of time''
+ creation of these values . */
+ // Values.
+ typedef fun::i2v::array<int_u8> dist_values_t;
+ dist_values_t dist_values(sites.size());
+ for (unsigned i = 0; i < dist_values.size(); ++i)
+ dist_values(i) = 0;
+
+
+ // Type of an edge-valued graph image located in a discrete 2D space
+ // with int_u8 values on each edge.
+ typedef edge_image<site_t, int_u8, util::graph> dist_ima_t;
+ dist_ima_t dist_ima(g, sites, dist_values);
data::fill(dist_ima, 0u);
- /*--------------------------------.
- | Complex-based image iterators. |
- `--------------------------------*/
+ /*------------------------.
+ | Graph image iterators. |
+ `------------------------*/
accu::stat::max<int_u8> dist_max;
@@ -197,23 +197,14 @@ make_complex_image(const mln::image2d<bool>& seeds)
image2d<int_u8> canvas(seeds.domain());
data::fill(canvas, 0);
- // Iterator on the edges of DIST_IMA.
- p_n_faces_fwd_piter<D, G> e(dist_ima.domain(), 1);
- // n-face to (n-1)-faces neighborhood (here, the pair of vertices
- // adjacent to an edge).
- typedef complex_lower_neighborhood<D, G> v_nbh_t;
- v_nbh_t v_nbh;
- // For each edge (1-face), compute the distance between the two
- // adjacent vertices (0-faces).
- mln_niter_(v_nbh_t) v(v_nbh, e);
+ // Iterator on (the edges of) DIST_IMA.
+ mln_piter_(dist_ima_t) e(dist_ima.domain());
for_all(e)
{
- v.start();
- point2d p1 = v.to_site().front();
- v.next();
- point2d p2 = v.to_site().front();
- v.next();
- mln_invariant(!v.is_valid());
+ // Site associated to E.
+ site_t p = e;
+ point2d p1 = e.first();
+ point2d p2 = e.second();
dist_ima(e) = norm::l2_distance(p1.to_vec(), p2.to_vec());
dist_max.take(dist_ima(e));
@@ -253,27 +244,22 @@ main(int argc, char* argv[])
image2d<bool> seeds;
io::pbm::load(seeds, input_filename);
- // Shortcut: type of a 1-complex image located in a discrete 2D
- // space with int_u8 values for each face.
- typedef int_u8_1complex_image2d ima_t;
- // Shortcuts: dimension and geometry (set of spatial locations)
- // associated to this image type.
- const unsigned D = 1;
- typedef mln_geom_(ima_t) G;
+ // Shortcut: type of an edge-valued graph image located in a
+ // discrete 2D space with int_u8 values for each edge.
+ typedef edge_image<util::site_pair<point2d>, int_u8> ima_t;
// Image computed from the graph of influence zones (IZ) of seeds.
- ima_t ima = make_complex_image(seeds);
+ ima_t ima = make_graph_image(seeds);
- // Adjacency relation between two n-faces through a shared adjacent
- // (n-1)-face. (An edge is adjacent to its neighboring edges; a
- // vertex has no neighbors.)
- typedef complex_lower_dim_connected_n_face_neighborhood<D, G> nbh_t;
+ // IMA's elementary neighborhood: adjacency relation between two
+ // edges through a shared vertex
+ typedef ima_t::nbh_t nbh_t;
nbh_t nbh;
typedef unsigned wst_val_t;
wst_val_t nbasins;
// Output image type.
- typedef complex_image<D, G, wst_val_t> wst_ima_t;
+ typedef edge_image<util::site_pair<point2d>, wst_val_t> wst_ima_t;
// Chain.
wst_ima_t wst_ima = chain(ima, nbh, lambda, nbasins);
@@ -283,21 +269,15 @@ main(int argc, char* argv[])
image2d<int_u8> canvas_wst(seeds.domain());
data::fill(canvas_wst, 255);
- // Iterator on the edges (1-faces) of WST_IMA.
- p_n_faces_fwd_piter<D, G> e(wst_ima.domain(), 1);
- typedef complex_lower_neighborhood<D, G> v_nbh_t;
- v_nbh_t v_nbh;
- // Iterator on the vertices adjacent to E.
- mln_niter_(v_nbh_t) v(v_nbh, e);
+ // Iterator on (the edges of) WST_IMA.
+ mln_piter_(wst_ima_t) e(wst_ima.domain());
for_all(e)
{
- v.start();
- point2d p1 = v.to_site().front();
- v.next();
- point2d p2 = v.to_site().front();
- v.next();
- mln_invariant(!v.is_valid());
+ // Site associated to E.
+ util::site_pair<point2d> p = e;
+ point2d p1 = e.first();
+ point2d p2 = e.second();
draw::line(canvas_wst, p1, p2, wst_ima(e));
}
--
1.7.2.5