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 }