Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
mesh-complex-segm.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 
30 
31 #include <cstdlib>
32 #include <cmath>
33 
34 #include <utility>
35 #include <iostream>
36 
37 #include <mln/core/image/complex_image.hh>
38 #include <mln/core/image/complex_neighborhoods.hh>
39 
40 #include <mln/morpho/closing/area.hh>
41 #include <mln/morpho/meyer_wst.hh>
42 
43 #include <mln/literal/white.hh>
44 
45 #include <mln/io/off/load.hh>
46 #include <mln/io/off/save.hh>
47 
48 
49 
50 int main(int argc, char* argv[])
51 {
52  if (argc != 4)
53  {
54  std::cerr << "usage: " << argv[0] << " input.off lambda output.off"
55  << std::endl;
56  std::exit(1);
57  }
58 
59  std::string input_filename = argv[1];
60  unsigned lambda = atoi(argv[2]);
61  std::string output_filename = argv[3];
62 
63  /*----------------.
64  | Complex image. |
65  `----------------*/
66 
67  // Image type.
68  typedef mln::float_2complex_image3df ima_t;
69  // Dimension of the image (and therefore of the complex).
70  static const unsigned D = ima_t::dim;
71  // Geometry of the image.
72  typedef mln_geom_(ima_t) G;
73 
74  ima_t input;
75  mln::io::off::load(input, input_filename);
76 
77  // Values on edges.
78  mln::p_n_faces_fwd_piter<D, G> e(input.domain(), 1);
79  typedef mln::complex_higher_neighborhood<D, G> adj_polygons_nbh_t;
80  adj_polygons_nbh_t adj_polygons_nbh;
81  mln_niter_(adj_polygons_nbh_t) adj_p(adj_polygons_nbh, e);
82  // Iterate on edges (1-faces).
83  for_all(e)
84  {
85  float s = 0.0f;
86  unsigned n = 0;
87  for_all(adj_p)
88  {
89  s += input(adj_p);
90  ++n;
91  }
92  input(e) = s / n;
93  // An edge should be adjacent to two polygons at most.
94  mln_invariant(n <= 2);
95  }
96 
97  /*-----------------.
98  | Simplification. |
99  `-----------------*/
100 
102  typedef
103  mln::complex_higher_dim_connected_n_face_neighborhood<D, G>
104  adj_edges_nbh_t;
105  adj_edges_nbh_t adj_edges_nbh;
106 
107  ima_t closed_input = mln::morpho::closing::area(input, adj_edges_nbh, lambda);
108 
109  /*------.
110  | WST. |
111  `------*/
112 
113  /* FIXME: Note that the WST is doing too much work, since we have
114  not constrained the domain of the image to 1-faces only.
115  It would be great if we could use something like this:
116 
117  closed_input | mln::p_faces<1, D, G>(closed_input.domain())
118 
119  as input of the WST. */
120 
121  // Compute the WST on edges.
122  typedef unsigned wst_val_t;
123  wst_val_t nbasins;
124  typedef mln::unsigned_2complex_image3df wst_ima_t;
125  wst_ima_t wshed =
126  mln::morpho::meyer_wst(closed_input, adj_edges_nbh, nbasins);
127  std::cout << "nbasins = " << nbasins << std::endl;
128 
129  // Label polygons (i.e., propagate labels from edges to polygons).
130  for_all(e)
131  if (wshed(e) != 0)
132  for_all(adj_p)
133  wshed(adj_p) = wshed(e);
134 
135  /*---------.
136  | Output. |
137  `---------*/
138 
139  mln::rgb8_2complex_image3df output(wshed.domain());
140  mln::data::fill(output, mln::literal::white);
141 
142  // FIXME: Use a colorize functor instead.
143  // Choose random colors for each basin number.
144  std::vector<mln::value::rgb8> basin_color (nbasins + 1);
145  for (unsigned i = 0; i <= nbasins; ++i)
146  basin_color[i] = mln::value::rgb8(random() % 256,
147  random() % 256,
148  random() % 256);
149  mln_piter_(ima_t) f(wshed.domain());
150  for_all(f)
151  output(f) = basin_color[wshed(f)];
152 
153  mln::io::off::save(output, output_filename);
154 }