Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 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 // Attach the work image to IS_SIMPLE. 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 // Populate SET with candidate simple points. 00101 mln_piter(I) p_(output.domain()); 00102 for_all(p_) 00103 { 00104 /* CONSTRAINTS and IS_SIMPLE are site-to-boolean (p2b) 00105 predicate functors; passing an iterator as argument might 00106 not be possible (C++ cannot resolve template routines if 00107 an implicit conversion of the argument is needed). Help 00108 the compiler and pass an actual, explicit psite. */ 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 /* FIXME: Using the following code does not work (it does 00119 compiles, but does not behave like the code using a 00120 hand-made loop). There must be a bug somewhere in 00121 p_set or p_indexed_psite. */ 00122 # if 0 00123 mln_piter(set_t) ps(set); 00124 for_all(ps); 00125 { 00126 // Same remark as above. 00127 psite p = p_; 00128 # endif 00129 for (unsigned i = 0; i < set.nsites(); ++i) 00130 { 00131 psite p = set[i]; 00132 00133 /* FIXME: We compute the cell and attachment of P twice: 00134 during the call to is_simple() and within detach(). 00135 How could we reuse this elegantly, without breaking 00136 the genericity of the skeleton algorithm? */ 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 } // end of namespace mln::topo::skeleton 00156 00157 } // end of namespace mln::topo 00158 00159 } // end of namespace mln 00160 00161 #endif // ! MLN_TOPO_SKELETON_BREADTH_FIRST_THINNING_HH