00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00032
00033 #include <cstdlib>
00034 #include <cmath>
00035
00036 #include <utility>
00037 #include <iostream>
00038
00039 #include <mln/core/image/complex_image.hh>
00040 #include <mln/core/image/complex_neighborhoods.hh>
00041
00042 #include <mln/morpho/closing/area.hh>
00043 #include <mln/morpho/meyer_wst.hh>
00044
00045 #include <mln/math/max.hh>
00046 #include <mln/math/sqr.hh>
00047
00048 #include <mln/literal/white.hh>
00049
00050 #include <mln/io/off/load.hh>
00051 #include <mln/io/off/save.hh>
00052
00053 #include "trimesh/misc.hh"
00054
00055
00056
00057 static const float pi = 4 * atanf(1);
00058
00059
00060 int main(int argc, char* argv[])
00061 {
00062 if (argc != 4)
00063 {
00064 std::cerr << "usage: " << argv[0] << " input.off lambda output.off"
00065 << std::endl;
00066 std::exit(1);
00067 }
00068
00069 std::string input_filename = argv[1];
00070 unsigned lambda = atoi(argv[2]);
00071 std::string output_filename = argv[3];
00072
00073
00074
00075
00076
00077
00078 typedef mln::float_2complex_image3df ima_t;
00079
00080 static const unsigned D = ima_t::dim;
00081
00082 typedef mln_geom_(ima_t) G;
00083
00084 mln::bin_2complex_image3df bin_input;
00085 mln::io::off::load(bin_input, input_filename);
00086 std::pair<ima_t, ima_t> curv = mln::geom::mesh_curvature(bin_input.domain());
00087
00088
00089 ima_t input(bin_input.domain());
00090 mln::p_n_faces_fwd_piter<D, G> v(input.domain(), 0);
00091 for_all(v)
00092 {
00093 float h = (curv.first(v) + curv.second(v)) / 2;
00094
00095 float h_inv = 1 / pi * (atan(-h) + pi / 2);
00096 input(v) = h_inv;
00097
00098
00099
00100
00101 }
00102
00103
00104 mln::p_n_faces_fwd_piter<D, G> e(input.domain(), 1);
00105 typedef mln::complex_lower_neighborhood<D, G> adj_vertices_nbh_t;
00106 adj_vertices_nbh_t adj_vertices_nbh;
00107 mln_niter_(adj_vertices_nbh_t) adj_v(adj_vertices_nbh, e);
00108
00109 for_all(e)
00110 {
00111 float s = 0.0f;
00112 unsigned n = 0;
00113
00114 for_all(adj_v)
00115 {
00116 s += input(adj_v);
00117 ++n;
00118 }
00119 input(e) = s / n;
00120
00121 mln_invariant(n <= 2);
00122 }
00123
00124
00125
00126
00127
00129 typedef
00130 mln::complex_higher_dim_connected_n_face_neighborhood<D, G>
00131 adj_edges_nbh_t;
00132 adj_edges_nbh_t adj_edges_nbh;
00133
00134 ima_t closed_input = mln::morpho::closing::area(input, adj_edges_nbh, lambda);
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 typedef unsigned wst_val_t;
00150 wst_val_t nbasins;
00151 typedef mln::unsigned_2complex_image3df wst_ima_t;
00152 wst_ima_t wshed =
00153 mln::morpho::meyer_wst(closed_input, adj_edges_nbh, nbasins);
00154 std::cout << "nbasins = " << nbasins << std::endl;
00155
00156
00157 typedef mln::complex_higher_neighborhood<D, G> adj_polygons_nbh_t;
00158 adj_polygons_nbh_t adj_polygons_nbh;
00159 mln_niter_(adj_polygons_nbh_t) adj_p(adj_polygons_nbh, e);
00160 for_all(e)
00161 if (wshed(e) != 0)
00162 for_all(adj_p)
00163 wshed(adj_p) = wshed(e);
00164
00165
00166
00167
00168
00169 mln::rgb8_2complex_image3df output(wshed.domain());
00170 mln::data::fill(output, mln::literal::white);
00171
00172
00173
00174 std::vector<mln::value::rgb8> basin_color (nbasins + 1);
00175 for (unsigned i = 0; i <= nbasins; ++i)
00176 basin_color[i] = mln::value::rgb8(random() % 256,
00177 random() % 256,
00178 random() % 256);
00179 mln_piter_(ima_t) f(wshed.domain());
00180 for_all(f)
00181 output(f) = basin_color[wshed(f)];
00182
00183 mln::io::off::save(output, output_filename);
00184 }