$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
edge_image.cc
1 // Copyright (C) 2009, 2011 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
32 
33 #include <mln/core/image/image2d.hh>
34 
35 #include <mln/util/graph.hh>
36 #include <mln/fun/i2v/array.hh>
37 #include <mln/util/site_pair.hh>
38 #include <mln/core/image/edge_image.hh>
39 
40 #include <mln/accu/shape/bbox.hh>
41 #include <mln/debug/draw_graph.hh>
42 
43 
44 int main()
45 {
46  using namespace mln;
47 
48  /*--------.
49  | Graph. |
50  `--------*/
51 
52  /* The graph and its corresponding line graph are as follows:
53 
54  0 1 2 3 4 0 1 2 3 4
55  .----------- .-----------
56  | |
57  0 | 0 2 0 | * *
58  1 | \ / | 1 | 0 1 |
59  2 | 1 | 2 | * 4
60  3 | \ | 3 | 2 |
61  4 | 3-4 4 | *3*
62 
63  Numbers in the graph represent the vertices and edges identifers
64  (resp.). */
65 
66  // Graph.
67  util::graph g;
68 
69  // Populate the graph with 5 vertices.
70  g.add_vertices(5);
71 
72  // Populate the graph with edges.
73  g.add_edge(0, 1);
74  g.add_edge(1, 2);
75  g.add_edge(1, 3);
76  g.add_edge(3, 4);
77  g.add_edge(4, 2);
78 
79  // Sites (points) associated to edges.
80  /* FIXME: It would be nicer to deduce these pairs from points
81  attached to a vertex graph (image) rather than building them
82  manually. */
83  typedef util::site_pair<point2d> site_t;
84  typedef fun::i2v::array<site_t> fsite_t;
85  fsite_t sites(5);
86  sites(0) = site_t(point2d(0,0), point2d(2,2)); // Site associated to edge 0.
87  sites(1) = site_t(point2d(2,2), point2d(0,4)); // Site associated to edge 1.
88  sites(2) = site_t(point2d(2,2), point2d(4,3)); // Site associated to edge 2.
89  sites(3) = site_t(point2d(4,3), point2d(4,4)); // Site associated to edge 3.
90  sites(4) = site_t(point2d(4,4), point2d(0,4)); // Site associated to edge 4.
91 
92  /*-------------.
93  | Edge image. |
94  `-------------*/
95 
96  // Graph values.
97  typedef fun::i2v::array<unsigned> viota_t;
98  viota_t iota(g.v_nmax());
99  for (unsigned i = 0; i < iota.size(); ++i)
100  iota(i) = 10 + i;
101 
102  typedef edge_image<site_t,unsigned> ima_t;
103  ima_t ima(g, sites, iota);
104 
105  // FIXME: As of 2011-10-06, this visualization does not work.
106  {
107  // FIXME: Move this part to a special test case.
108 
109  // Compute the bounding box of 'ima'.
111  mln_piter_(ima_t) p(ima.domain());
112  for_all(p)
113  {
114  a.take(p.first());
115  a.take(p.second());
116  }
117  box2d bbox = a.to_result();
118  mln_assertion(bbox == make::box2d(5, 5));
119 
120  // Print the image.
121  /* FIXME: Unfortunately, displaying graph images is not easy right
122  now(2008-02-05). We could use
123 
124  debug::println(ima);
125 
126  but there's not specialization working for graph_image; the one
127  selected by the compiler is based on a 2-D bbox, and expects the
128  interface of graph_image to work with points(not psites).
129  Moreover, this implementation only shows *values*, not the graph
130  itself.
131 
132  An alternative is to use debug::graph,
133  but it doesn't show the values, only the vertices and edges of the
134  graph.
135 
136  The current solution is a mix between debug::graph and hand-made
137  iterations. */
138  image2d<int> ima_rep(bbox);
139 
140  // We use the value 9 in debug::graph to represent edges to distinguish it
141  // from vertices holding a value of 1.
142  debug::draw_graph(ima_rep, ima.domain(), 1, 9);
143  }
144 
145  /*------------.
146  | Iterators. |
147  `------------*/
148 
149  // Invalid identifier.
150  const unsigned X = mln_max(unsigned);
151 
152  // Expected neighbors for forward and backward iterations on an
153  // elementary window.
154  const unsigned expected_fwd_nbh[5][3] = { { 1, 2, X },
155  { 0, 2, 4 },
156  { 0, 1, 3 },
157  { 2, 4, X },
158  { 1, 3, X } };
159 
160  const unsigned expected_bkd_nbh[5][3] = { { 2, 1, X },
161  { 4, 2, 0 },
162  { 3, 1, 0 },
163  { 4, 2, X },
164  { 3, 1, X } };
165 
166  // Iteration over the domain of IMA.
167  mln_piter_(ima_t) p(ima.domain());
168  unsigned i = 10;
169  for_all(p)
170  mln_assertion(ima(p) == i++);
171 
172  // Elementary window.
173  typedef ima_t::win_t win_t;
174  win_t win;
175 
176  {
177  // Window -- Forward iteration.
178  mln_fwd_qiter_(win_t) q(win, p);
179  for_all(p)
180  {
181  i = 0;
182  for_all(q)
183  {
184  mln_assertion(expected_fwd_nbh[p.id()][i] == q.id());
185  ++i;
186  }
187  }
188  }
189 
190  {
191  // Window -- Backward iteration.
192  mln_bkd_qiter_(win_t) q(win, p);
193  for_all(p)
194  {
195  i = 0;
196  for_all(q)
197  {
198  mln_assertion(expected_bkd_nbh[p.id()][i] == q.id());
199  ++i;
200  }
201  }
202  }
203 
204 
205  // Elementary neighborhood.
206  typedef ima_t::nbh_t nbh_t;
207  nbh_t nbh;
208 
209  {
210  // Neighborhood -- Forward iteration.
211  mln_fwd_niter_(nbh_t) n(nbh, p);
212  for_all(p)
213  {
214  i = 0;
215  for_all(n)
216  {
217  mln_assertion(expected_fwd_nbh[p.id()][i] == n.id());
218  ++i;
219  }
220  }
221  }
222 
223  {
224  // Neighborhood -- Backward iteration.
225  mln_bkd_niter_(nbh_t) n(nbh, p);
226  for_all(p)
227  {
228  i = 0;
229  for_all(n)
230  {
231  mln_assertion(expected_bkd_nbh[p.id()][i] == n.id());
232  ++i;
233  }
234  }
235  }
236 }