$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
mesh-complex-max-curv-extrema.cc
1 // Copyright (C) 2008, 2009, 2010, 2013 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
32 
33 #include <cstdlib>
34 #include <cmath>
35 
36 #include <utility>
37 #include <iostream>
38 
39 #include <mln/core/image/complex_image.hh>
40 #include <mln/core/image/complex_neighborhoods.hh>
41 
42 #include <mln/data/fill.hh>
43 #include <mln/literal/zero.hh>
44 
45 #include <mln/labeling/regional_minima.hh>
46 #include <mln/labeling/regional_maxima.hh>
47 
48 #include <mln/math/max.hh>
49 #include <mln/math/sqr.hh>
50 #include <mln/accu/stat/min_max.hh>
51 #include <mln/fun/v2v/linear.hh>
52 #include <mln/data/transform.hh>
53 
54 #include <mln/value/label_16.hh>
55 
56 #include <mln/literal/white.hh>
57 #include <mln/literal/grays.hh>
58 #include <mln/literal/colors.hh>
59 
60 #include <mln/io/off/load.hh>
61 #include <mln/io/off/save.hh>
62 
63 #include "misc.hh"
64 
65 
66 int main(int argc, char* argv[])
67 {
68  if (argc != 3)
69  {
70  std::cerr << "usage: " << argv[0] << " input.off output.off"
71  << std::endl;
72  std::exit(1);
73  }
74 
75  std::string input_filename = argv[1];
76  std::string output_filename = argv[2];
77 
78  /*----------------.
79  | Complex image. |
80  `----------------*/
81 
82  // Image type.
83  typedef mln::float_2complex_image3df ima_t;
84  // Dimension of the image (and therefore of the complex).
85  static const unsigned D = ima_t::dim;
86  // Geometry of the image.
87  typedef mln_geom_(ima_t) G;
88 
89  mln::bin_2complex_image3df input;
90  mln::io::off::load(input, input_filename);
91 
92  std::pair<ima_t, ima_t> curv = mln::geom::mesh_curvature(input.domain());
93 
94  // Compute the max curvature at each vertex.
95  ima_t max_curv(input.domain());
96  mln::data::fill(max_curv, mln::literal::zero);
97  mln::p_n_faces_fwd_piter<D, G> v(max_curv.domain(), 0);
98  for_all(v)
99  max_curv(v) = mln::math::max(mln::math::sqr(curv.first(v)),
100  mln::math::sqr(curv.second(v)));
101 
102  // Propagate these values on triangles.
103  mln::p_n_faces_fwd_piter<D, G> t(max_curv.domain(), 2);
104  typedef mln::complex_m_face_neighborhood<D, G> adj_vertices_nbh_t;
105  adj_vertices_nbh_t adj_vertices_nbh;
106  mln_niter_(adj_vertices_nbh_t) adj_v(adj_vertices_nbh, t);
107  /* FIXME: Not really user friendly! The `m' value should pass at
108  the construction of ADJ_V. */
109  adj_v.iter().set_m(0);
110  mln::accu::stat::min_max<float> acc;
111  // Iterate on triangles (2-faces).
112  for_all(t)
113  {
114  float s = 0.0f;
115  unsigned n = 0;
116  // Iterate on vertices (0-faces).
117  for_all(adj_v)
118  {
119  s += max_curv(adj_v);
120  ++n;
121  }
122  float m = s / n;
123  max_curv(t) = m;
124  acc.take(m);
125  // A triangle should be adjacent to exactly three vertices.
126  mln_invariant(n <= 3);
127  }
128 
129  /*----------------.
130  | Local extrema. |
131  `----------------*/
132 
135  nbh_t nbh;
136 
137  typedef mln::value::label_16 label_t;
138  typedef mln_ch_value_(ima_t, label_t) label_ima_t;
139 
140  /* FIXME: We should use something like `ima_t | p_n_faces(2)' instead
141  of `ima_t' here. Or better: `input' should only associate data
142  to 2-faces. */
143  label_t nminima;
144  label_ima_t minima =
145  mln::labeling::regional_minima(max_curv, nbh, nminima);
146  std::cout << "nminima = " << nminima << std::endl;
147 
148  label_t nmaxima;
149  label_ima_t maxima =
150  mln::labeling::regional_maxima(max_curv, nbh, nmaxima);
151  std::cout << "nmaxima = " << nmaxima << std::endl;
152 
153  /*-----------------.
154  | Colored output. |
155  `-----------------*/
156 
157  typedef mln::rgb8_2complex_image3df output_t;
158  output_t output(max_curv.domain());
159 
160  for_all(t)
161  {
162  if (minima(t) != mln::literal::zero)
163  {
164  // Special (unexpected) case: T is both a minimum and a
165  // maximum. Paint it in magenta (blue + red).
166  if (maxima(t) != mln::literal::zero)
167  {
168  std::cerr
169  << "warning: " << t << " is both a minimum and a maximum."
170  << std::endl;
171  output(t) = mln::literal::magenta;
172  }
173  else
174  // Paint minimum T in blue.
175  output(t) = mln::literal::blue;
176  }
177  else if (maxima(t) != mln::literal::zero)
178  // Paint maximum T in red.
179  output(t) = mln::literal::red;
180  else
181  // Default color.
182  output(t) = mln::literal::medium_gray;
183  }
184 
185  // Output.
186  mln::io::off::save(output, output_filename);
187 }