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
00041 #ifndef OLENA_LRDE_UFMT_FIORIO_3_HH
00042 # define OLENA_LRDE_UFMT_FIORIO_3_HH
00043
00044 # include <algorithm>
00045
00046 # include <oln/core/image2d.hh>
00047 # include <oln/level/fill.hh>
00048
00049 namespace oln
00050 {
00051 namespace lrde
00052 {
00053 namespace ufmt
00054 {
00055
00056
00057 template <typename I>
00058 class fiorio
00059 {
00060 typedef oln_point_type(I) point;
00061 typedef oln_value_type(I) value;
00062 typedef oln_iter_type(I) piter;
00063 typedef typename mute<I, point>::ret parent_type;
00064
00065 public:
00066 fiorio(const abstract::image<I>& ima) :
00067 ima_(ima.exact().clone()), parent_(ima.size()),
00068 n_level_roots_cpt_(ima.npoints())
00069 {
00070
00071 piter p (parent_);
00072 for_all (p)
00073 parent_[p] = p;
00074 }
00075
00077 void go()
00078 {
00079 scan_line();
00080 }
00081
00082
00085 public:
00086 const I& ima() const
00087 {
00088 return ima_;
00089 }
00090
00091 const parent_type& parent() const
00092 {
00093 return parent_;
00094 }
00096
00097
00102 unsigned n_level_roots1() const
00103 {
00104 return n_level_roots_cpt_;
00105 }
00106
00109 unsigned n_level_roots2() const
00110 {
00111 unsigned n_level_roots = 0;
00112 oln_iter_type(parent_type) p(parent_);
00113 for_all (p)
00114 if (is_level_root(p))
00115 ++n_level_roots;
00116 return n_level_roots;
00117 }
00118
00120 typedef typename mute<parent_type, bool>::ret level_roots_image_type;
00121
00125 level_roots_image_type level_roots() const
00126 {
00127
00128 level_roots_image_type level_roots (ima_.size());
00129 oln_iter_type(parent_type) p(ima_);
00130 for_all (p)
00131 level_roots[p] = is_level_root(p);
00132 return level_roots;
00133 }
00135
00136
00137 protected:
00138
00139 void scan_line()
00140 {
00141
00142 for (coord i = 0; i < ima_.nrows(); ++i)
00143 build_tree_of_line(i);
00144
00145 for (coord j = 0; j < ima_.ncols(); ++j)
00146 for (coord i = 0; i < ima_.nrows() - 1; ++i)
00147 merge(point(i, j), point(i + 1, j));
00148 }
00149
00150 void build_tree_of_line(coord row)
00151 {
00152
00153
00154 for (coord j = 1; j < ima_.ncols(); ++j)
00155 {
00156 point left = find_level_root(point(row, j - 1));
00157 point this_one = point(row, j);
00158 insert(this_one, left);
00159 }
00160 }
00161
00163 void insert(const point& p, const point& n)
00164 {
00165 point r = find_ancestor(n, ima_[p]);
00166 if (ima_[r] <= ima_[p])
00167 {
00168 parent_[p] = r;
00169 if (ima_[r] == ima_[p])
00170
00171 --n_level_roots_cpt_;
00172 }
00173 else
00174 {
00175 if (not is_top(r))
00176 parent_[p] = parent_[r];
00177 parent_[r] = p;
00178 }
00179 }
00180
00183 void merge(const point& p, const point& q)
00184 {
00185
00186
00187 if (ima_[p] >= ima_[q])
00188 merge_(p, q);
00189 else
00190 merge_(q, p);
00191 }
00192
00193
00194 void merge_(const point& p, const point& q)
00195 {
00196 precondition (p != q);
00197 precondition (ima_[p] >= ima_[q]);
00198
00199 point r = find_ancestor(p, ima_[q]);
00200 point s = find_level_root(q);
00201
00202
00203
00204 if (r == s)
00205 return;
00206
00207 point t = parent_[s];
00208
00209 if (ima_[s] == ima_[r])
00210 {
00211 parent_[s] = r;
00212
00213 --n_level_roots_cpt_;
00214 }
00215 else
00216 {
00217 if (not is_top(r))
00218 parent_[s] = parent_[r];
00219 parent_[r] = s;
00220 }
00221 merge_(r, t);
00222 }
00223
00225 bool is_top(const point& p) const
00226 {
00227 return parent_[p] == p;
00228 }
00229
00230 point find_top(point p) const
00231 {
00232 while (not is_top(p))
00233 p = parent_[p];
00234 return p;
00235 }
00236
00237 bool is_level_root(const point& p) const
00238 {
00239 return
00240 is_top(p) ||
00241 (ima_[parent_[p]] != ima_[p]);
00242 }
00243
00246 point find_level_root(const point& p)
00247 {
00248
00249 if (is_level_root(p))
00250 return p;
00251 else
00252
00253 return parent_[p] = find_level_root(parent_[p]);
00254 }
00255
00258 point find_ancestor(point p, const value& level)
00259 {
00260 while (not is_top(p) and ima_[parent_[p]] >= level)
00261 p = find_level_root(parent_[p]);
00262 return p;
00263 }
00264
00265 protected:
00267 I ima_;
00269 parent_type parent_;
00270
00271 unsigned n_level_roots_cpt_;
00272
00273 };
00274
00275 }
00276
00277 }
00278
00279 }
00280
00281 #endif // ! OLENA_LRDE_UFMT_FIORIO_3_HH