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
00030
00031 #include <iostream>
00032
00033 #include <mln/core/image/complex_image.hh>
00034 #include <mln/core/image/complex_neighborhoods.hh>
00035
00036 #include <mln/core/site_set/p_set.hh>
00037
00038 #include <mln/value/label_16.hh>
00039
00040 #include <mln/labeling/regional_minima.hh>
00041 #include <mln/morpho/closing/area.hh>
00042
00043 #include <mln/topo/is_n_face.hh>
00044 #include <mln/topo/is_simple_cell.hh>
00045 #include <mln/topo/detach.hh>
00046 #include <mln/topo/skeleton/breadth_first_thinning.hh>
00047
00048 #include <mln/io/off/load.hh>
00049
00050
00051 #include "save_bin_alt.hh"
00052
00053
00054 int
00055 main(int argc, char* argv[])
00056 {
00057 if (argc != 4)
00058 {
00059 std::cerr << "usage: " << argv[0] << " input.off lambda output.off"
00060 << std::endl;
00061 std::exit(1);
00062 }
00063
00064 std::string input_filename = argv[1];
00065 unsigned lambda = atoi(argv[2]);
00066 std::string output_filename = argv[3];
00067
00068
00069
00070
00071
00072
00073 typedef mln::float_2complex_image3df ima_t;
00074
00075 static const unsigned D = ima_t::dim;
00076
00077 typedef mln_geom_(ima_t) G;
00078
00079 ima_t input;
00080 mln::io::off::load(input, input_filename);
00081
00082
00083
00084 mln::p_n_faces_fwd_piter<D, G> v(input.domain(), 0);
00085 for_all(v)
00086 input(v) = mln_max(float);
00087 mln::p_n_faces_fwd_piter<D, G> e(input.domain(), 1);
00088 for_all(e)
00089 input(e) = mln_max(float);
00090
00091
00092
00093
00094
00096 typedef mln::complex_lower_dim_connected_n_face_neighborhood<D, G> nbh_t;
00097 nbh_t nbh;
00098
00099 ima_t closed_input = mln::morpho::closing::area(input, nbh, lambda);
00100
00101
00102
00103
00104
00105 typedef mln::value::label_16 label_t;
00106 label_t nminima;
00107
00108
00109
00110
00111 typedef mln_ch_value_(ima_t, label_t) label_ima_t;
00112 label_ima_t minima =
00113 mln::labeling::regional_minima(closed_input, nbh, nminima);
00114
00115 typedef mln::complex_higher_neighborhood<D, G> higher_nbh_t;
00116 higher_nbh_t higher_nbh;
00117
00118
00119
00120 mln_niter_(higher_nbh_t) adj_t(higher_nbh, e);
00121 for_all(e)
00122 {
00123 label_t ref_adj_minimum = mln::literal::zero;
00124 for_all(adj_t)
00125 if (minima(adj_t) == mln::literal::zero)
00126 {
00127
00128
00129 ref_adj_minimum = mln::literal::zero;
00130 break;
00131 }
00132 else
00133 {
00134 if (ref_adj_minimum == mln::literal::zero)
00135
00136 ref_adj_minimum = minima(adj_t);
00137 else
00138
00139
00140 mln_assertion(minima(adj_t) == ref_adj_minimum);
00141 }
00142 minima(e) = ref_adj_minimum;
00143 }
00144
00145
00146 mln_niter_(higher_nbh_t) adj_e(higher_nbh, v);
00147 for_all(v)
00148 {
00149 label_t ref_adj_minimum = mln::literal::zero;
00150 for_all(adj_e)
00151 if (minima(adj_e) == mln::literal::zero)
00152 {
00153
00154
00155 ref_adj_minimum = mln::literal::zero;
00156 break;
00157 }
00158 else
00159 {
00160 if (ref_adj_minimum == mln::literal::zero)
00161
00162 ref_adj_minimum = minima(adj_e);
00163 else
00164
00165
00166 mln_assertion(minima(adj_e) == ref_adj_minimum);
00167 }
00168 minima(v) = ref_adj_minimum;
00169 }
00170
00171
00172
00173
00174
00175 typedef mln_ch_value_(ima_t, bool) bin_ima_t;
00176 bin_ima_t surface(minima.domain());
00177 mln::data::fill(surface, true);
00178
00179
00180 mln_piter_(bin_ima_t) f(minima.domain());
00181 for_all(f)
00182 if (minima(f) != mln::literal::zero)
00183 surface(f) = false;
00184
00185
00186
00187
00188
00189 mln::topo::is_simple_cell<bin_ima_t> is_simple_p;
00190
00191
00192
00193
00194
00195
00196
00197
00198 mln::topo::is_n_face<bin_ima_t::dim> constraint_p;
00199 bin_ima_t skel =
00200 mln::topo::skeleton::breadth_first_thinning(surface, nbh,
00201 is_simple_p,
00202 mln::topo::detach<D, G>,
00203 constraint_p);
00204
00205
00206
00207
00208
00209
00210
00211 #if 0
00212 mln::io::off::save(skel | mln::pw::value(skel) == mln::pw::cst(true),
00213 output_filename);
00214 #endif
00215 mln::io::off::save_bin_alt(skel, output_filename);
00216 }