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