$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
complex_image.cc
1 // Copyright (C) 2008, 2009 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 
26 #include <iostream>
27 
28 #include <mln/value/int_u8.hh>
29 #include <mln/core/alias/point2d.hh>
30 
31 #include <mln/core/site_set/p_faces.hh>
32 #include <mln/core/image/complex_image.hh>
33 
34 // FIXME: Include these elsewhere? (In complex_image.hh?)
35 #include <mln/core/image/complex_neighborhoods.hh>
36 #include <mln/core/image/complex_neighborhood_piter.hh>
37 
38 /* FIXME: Split this test (and maybe factor common parts, like the
39  construction of the complex), since it exercises too many features
40  in a single file. */
41 
42 // Forward declaration.
43 template <typename I, typename N>
44 void
45 test_neighborhood(const mln::Image<I>& ima_, const mln::Neighborhood<N> nbh,
46  const std::string& comment);
47 
48 
49 int main()
50 {
51  using namespace mln;
52 
53  /*----------.
54  | Complex. |
55  `----------*/
56 
57  /* A 2-d (simplicial) complex and its adjacency graph.
58 
59  c 0 1 2 3
60  r .------------------------
61  | v0 e3 v3
62  0 | o-----------o v0----e3----v3
63  | / \ ,-----. / / \ | /
64  | / . \ \ t1/ / / \ t1 /
65  1 | e0 / / \ e1\ / / e4 e0. ,e1' `e4
66  | / /t0 \ \ ' / / t0 \ /
67  | / `-----' \ / / | \ /
68  2 | o-----------o v1----e2----v2
69  | v1 e2 v2
70 
71  v = vertex
72  e = edge
73  t = triangle
74  */
75 
76 
77  const unsigned D = 2;
78 
80 
81  // 0-faces (points).
82  topo::n_face<0, D> v0 = c.add_face();
83  topo::n_face<0, D> v1 = c.add_face();
84  topo::n_face<0, D> v2 = c.add_face();
85  topo::n_face<0, D> v3 = c.add_face();
86 
87  // 1-faces (segments).
88  topo::n_face<1, D> e0 = c.add_face(v0 + v1);
89  topo::n_face<1, D> e1 = c.add_face(v0 + v2);
90  topo::n_face<1, D> e2 = c.add_face(v1 + v2);
91  topo::n_face<1, D> e3 = c.add_face(v0 + v3);
92  topo::n_face<1, D> e4 = c.add_face(v2 + v3);
93 
94  // 2-faces (triangles).
95  topo::n_face<2, D> t0 = c.add_face(e0 + e1 + e2);
96  topo::n_face<2, D> t1 = c.add_face(e1 + e3 + e4);
97 
98 
99  /*------------------------------.
100  | Complex geometry (location). |
101  `------------------------------*/
102 
103  typedef point2d P;
105  G geom;
106  geom.add_location(point2d(0,1)); // 0-face #0.
107  geom.add_location(point2d(2,0)); // 0-face #1.
108  geom.add_location(point2d(2,2)); // 0-face #2.
109  geom.add_location(point2d(0,3)); // 0-face #3.
110 
111 
112  /*---------------------.
113  | Complex-based pset. |
114  `---------------------*/
115 
116  // A pset.
117  p_complex<D, G> pc(c, geom);
118  topo::face<D> af(e0);
119  // An associated psite.
120  complex_psite<D, G> cs(pc, af);
121 
122 
123  /*--------------------.
124  | Faces-based psets. |
125  `--------------------*/
126 
127  /* FIXME: Not that p_faces have become less interesting since the
128  introduction of p_complex_faces_{fwd,bkd}_piter_. Keep this part
129  of the test? */
130 
131  // Pset of 0-faces.
132  p_faces<0, D, G> pf0(c);
133  // Pset of 1-faces.
134  p_faces<1, D, G> pf1(c);
135  // Pset of 2-faces.
136  p_faces<2, D, G> pf2(c);
137 
138  // Some psites on faces.
139  faces_psite<0, D, G> fs0(pf0, v0);
140  faces_psite<1, D, G> fs1(pf1, e0);
141  faces_psite<2, D, G> fs2(pf2, t0);
142 
143 
144  /*----------------------.
145  | Complex-based image. |
146  `----------------------*/
147 
148  using mln::value::int_u8;
149 
150  // An image type built on a 2-complex with mln::int_u8 values on
151  // each face.
152  typedef complex_image<D, G, int_u8> ima_t;
153 
154  // Values.
155  metal::vec<D + 1, std::vector< int_u8 > > values;
156  // Assign 0 to 0-faces, 1 to 1-faces and 2 to 2-faces.
157  for (unsigned d = 0; d <= D; ++d)
158  for (unsigned n = 0; n < pc.cplx().nfaces_of_dim(d); ++n)
159  values[d].push_back(d);
160 
161  // Create and init an image based on PC.
162  ima_t ima(pc, values);
163 
164  // Check the value associated to edge E0 (through complex psite CS).
165  mln_assertion(ima(cs) == 1u);
166 
167 
168  /*--------------------------------.
169  | Complex-based image iterators. |
170  `--------------------------------*/
171 
172  // ---------------------------- //
173  // Iterators on all the faces. //
174  // ---------------------------- //
175 
176  mln_fwd_piter_(ima_t) fp(ima.domain());
177  for_all(fp)
178  std::cout << "ima(" << fp << ") = " << ima(fp) << std::endl;
179  std::cout << std::endl;
180 
181  mln_bkd_piter_(ima_t) bp(ima.domain());
182  for_all(bp)
183  std::cout << "ima(" << bp << ") = " << ima(bp) << std::endl;
184  std::cout << std::endl;
185 
186 
187  // ----------------------------------------------- //
188  // Iterators on n-faces (with n fixed in [0, D]). //
189  // ----------------------------------------------- //
190 
191  // Dynamic version.
192  for (unsigned n = 0; n <= D; ++n)
193  {
194  p_n_faces_fwd_piter<D, G> fwd_np(ima.domain(), n);
195  p_n_faces_bkd_piter<D, G> bkd_np(ima.domain(), n);
196  for_all_2(fwd_np, bkd_np)
197  std::cout << "ima(" << fwd_np << ") = " << ima(fwd_np) << '\t'
198  << "ima(" << bkd_np << ") = " << ima(bkd_np)
199  << std::endl;
200  std::cout << std::endl;
201  }
202 
203  // Static version.
204 // FIXME: Disabled (moved to the attic).
205 # if 0
206  // FIXME: Sugar the name of the iterator.
207  p_complex_faces_fwd_piter_<0, D, G> f0p(ima.domain());
208  for_all(f0p)
209  std::cout << "ima(" << f0p << ") = " << ima(f0p) << std::endl;
210 #endif
211 
212  /* FIXME: Implement other psite iterators, for instance:
213 
214  - iterators on N-faces with N in a subset of [0, D];
215  - etc. */
216 
217  // ---------------------------- //
218  // Iterators on neighborhoods. //
219  // ---------------------------- //
220 
221 
222  test_neighborhood(ima, complex_lower_neighborhood<D, G>(),
223  "Lower-dimension faces");
224  test_neighborhood(ima, complex_higher_neighborhood<D, G>(),
225  "Higher-dimension faces");
226  test_neighborhood(ima, complex_lower_higher_neighborhood<D, G>(),
227  "Lower- and higer-dimension faces");
228 
229  test_neighborhood(ima,
231  "Lower-dimension connected n-faces");
232  test_neighborhood(ima,
234  "Higher-dimension connected n-faces");
235 
236  /* FIXME: Implement other neighborhoods (and windows) and
237  corresponding iterators for complex-based images.
238 
239  For a given (fixed) dimension N and a psite P on a N-face,
240  implement windows returning
241 
242  - the set of N-faces sharing a (N-1)-face with P;
243  - the set of N-faces sharing a (N-1)-face or (N-2)-face (by
244  transitivity) with P (is it useful?);
245 
246  - the set of the ``cell'' including P (named ``P-hat'' in
247  couprie.08.pami), i.e., the set of all M-faces adjacent to P,
248  where M is in [0, N-1].
249 
250  In that definition, P is said adjacent to an M-face Q if
251  there is a sequence (M1, M2, ..., Mk) of faces so that
252  - M1 is an (N-1)-face adjacent to P ;
253  - M2 is an (N-2)-face adjacent to M1 ;
254  - and so on;
255  - Mk is an (M+1)-face adjacent to Q.
256 
257  - what else?
258 
259  We might want to look at operators on (simplicial?) complexes
260  like star, link, etc. and possibly implement them.
261 
262  See also https://trac.lrde.org/olena/ticket/162. */
263 }
264 
265 
266 template <typename I, typename N>
267 void
268 test_neighborhood(const mln::Image<I>& ima_, const mln::Neighborhood<N> nbh,
269  const std::string& comment)
270 {
271  const I& ima = exact(ima_);
272  mln_fwd_piter(I) fp(ima.domain());
273 
274  mln_fwd_niter(N) fn(nbh, fp);
275  mln_bkd_niter(N) bn(nbh, fp);
276  for_all(fp)
277  {
278  std::cout << comment << " adjacent to " << fp << std::endl;
279  for_all_2(fn, bn)
280  {
281  mln_assertion((fn.center() == static_cast<const mln_psite(I)&>(fp)));
282  mln_assertion((bn.center() == static_cast<const mln_psite(I)&>(fp)));
283  std::cout << " " << fn << '\t' << bn << std::endl;
284  }
285  }
286  std::cout << std::endl;
287 }