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
00028 #ifndef OLENA_LEVEL_CC_HH
00029 # define OLENA_LEVEL_CC_HH
00030
00031
00032
00033
00034
00035 # include <oln/arith/ops.hh>
00036 # include <oln/core/image.hh>
00037 # include <oln/level/fill.hh>
00038
00039 # include <set>
00040
00041 namespace oln {
00042
00045 namespace level {
00046
00047
00048 struct update_label;
00049
00094 template <class DestType, class I, class E>
00095 typename mute<I, DestType>::ret
00096 frontp_connected_component(const abstract::binary_image<I>& input,
00097 const abstract::neighborhood<E>& se,
00098 unsigned& nb_label)
00099 {
00100 typename mute<I, DestType>::ret output(input.size());
00101 level::fill(output, 0);
00102
00103 typedef std::set<oln_point_type(I),
00104 oln::internal::default_less<oln_point_type(I) > >
00105 points_set;
00106
00107 I is_processed(input.size());
00108 level::fill(is_processed, false);
00109 DestType cur_label = 1;
00110 oln_iter_type(I) p(input);
00111 for_all(p) if ((input[p] == true)&& (is_processed[p] == false))
00112 {
00113
00114 points_set component;
00115 component.insert(p.cur());
00116 points_set points_to_process;
00117 points_to_process.insert(p.cur());
00118 while (!points_to_process.empty())
00119 {
00120
00121 points_set next;
00122 for (typename points_set::const_iterator i =
00123 points_to_process.begin();
00124 i != points_to_process.end();
00125 ++i)
00126 {
00127 component.insert(*i);
00128 oln_neighb_type(E) p_prime(se, *i);
00129 for_all (p_prime) if(input.hold(p_prime) &&
00130 (input[p_prime] == true))
00131 next.insert(p_prime.cur());
00132 }
00133 points_to_process.clear();
00134 set_difference(next.begin(), next.end(),
00135 component.begin(), component.end(),
00136 inserter(points_to_process,
00137 points_to_process.begin()),
00138 oln::internal::default_less<oln_point_type(I) >());
00139 }
00140 for (typename points_set::const_iterator i = component.begin();
00141 i != component.end();
00142 ++i)
00143 {
00144 output[*i] = cur_label;
00145 is_processed[*i] = true;
00146 }
00147 cur_label++;
00148 }
00149 nb_label = cur_label;
00150 return output;
00151 }
00152
00153 template <class DestType, class I, class E>
00154 typename mute<I, DestType>::ret
00155 frontp_connected_component(const abstract::image<I>& input,
00156 const abstract::neighborhood<E>& se)
00157 {
00158 unsigned dummy;
00159 return frontp_connected_component(input, se, dummy);
00160 }
00161
00162 template <class I>
00163 typename mute<I, ntg::bin>::ret
00164 extract_i_cc(const abstract::image<I>& input,
00165 oln_value_type(I) i)
00166 {
00167
00168 typename mute<I, ntg::bin>::ret output(input.size());
00169 level::fill(output, false);
00170 oln_iter_type(I) p(input);
00171 for_all(p)
00172 if (input[p] == i)
00173 output[p] = true;
00174 return output;
00175 }
00176
00177 template <class I>
00178 oln_value_type(I) get_n_cc(const abstract::image<I>& input)
00179 {
00180 return fold(arith::default_f_max<oln_value_type(I)>(), input);
00181 }
00182
00183 }
00184
00185 }
00186
00187 #endif // ! OLENA_LEVEL_CC_HH