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 #ifndef MLN_TOPO_SKELETON_BREADTH_FIRST_THINNING_HH
00027 # define MLN_TOPO_SKELETON_BREADTH_FIRST_THINNING_HH
00028 
00032 
00033 # include <algorithm>
00034 
00035 # include <mln/core/routine/duplicate.hh>
00036 
00037 # include <mln/core/concept/image.hh>
00038 # include <mln/core/concept/neighborhood.hh>
00039 
00040 # include <mln/core/site_set/p_set.hh>
00041 
00042 # include <mln/fun/p2b/tautology.hh>
00043 
00044 namespace mln
00045 {
00046 
00047   namespace topo
00048   {
00049 
00050     namespace skeleton
00051     {
00052 
00067       template <typename I, typename N, typename F, typename G, typename H>
00068       mln_concrete(I)
00069       breadth_first_thinning(const Image<I>& input,
00070                              const Neighborhood<N>& nbh,
00071                              Function_v2b<F>& is_simple,
00072                              G detach,
00073                              const Function_v2b<H>& constraint =
00074                                fun::p2b::tautology());
00075 
00076 
00077 # ifndef MLN_INCLUDE_ONLY
00078 
00079       template <typename I, typename N, typename F, typename G, typename H>
00080       inline
00081       mln_concrete(I)
00082       breadth_first_thinning(const Image<I>& input_,
00083                              const Neighborhood<N>& nbh_,
00084                              Function_v2b<F>& is_simple_,
00085                              G detach,
00086                              const Function_v2b<H>& constraint_)
00087       {
00088         const I& input = exact(input_);
00089         const N& nbh = exact(nbh_);
00090         F& is_simple = exact(is_simple_);
00091         const H& constraint = exact(constraint_);
00092 
00093         I output = duplicate(input);
00094         
00095         is_simple.set_image(output);
00096 
00097         typedef mln_psite(I) psite;
00098         typedef p_set<psite> set_t;
00099         set_t set;
00100         
00101         mln_piter(I) p_(output.domain());
00102         for_all(p_)
00103         {
00104           
00105 
00106 
00107 
00108 
00109           psite p = p_;
00110           if (output(p) && constraint(p) && is_simple(p))
00111             set.insert(p);
00112         }
00113 
00114         while (!set.is_empty())
00115           {
00116             set_t next_set;
00117 
00118             
00119 
00120 
00121 
00122 # if 0
00123             mln_piter(set_t) ps(set);
00124             for_all(ps);
00125             {
00126               
00127               psite p = p_;
00128 # endif
00129             for (unsigned i = 0; i < set.nsites(); ++i)
00130               {
00131                 psite p = set[i];
00132 
00133                 
00134 
00135 
00136 
00137                 if (constraint(p) && is_simple(p))
00138                   {
00139                     detach(p, output);
00140                     mln_niter(N) n(nbh, p);
00141                     for_all(n)
00142                       if (output.domain().has(n)
00143                           && output(n) && constraint(p) && is_simple(n))
00144                         next_set.insert(n);
00145                   }
00146               }
00147             set.clear();
00148             std::swap(set, next_set);
00149           }
00150         return output;
00151       }
00152 
00153 # endif // MLN_INCLUDE_ONLY
00154 
00155     } 
00156 
00157   } 
00158 
00159 } 
00160 
00161 #endif // ! MLN_TOPO_SKELETON_BREADTH_FIRST_THINNING_HH