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
00040 #ifndef OLENA_LRDE_UFMT_FIORIO_1_HH
00041 # define OLENA_LRDE_UFMT_FIORIO_1_HH
00042
00043 # include <algorithm>
00044
00045 # include <oln/core/image2d.hh>
00046 # include <oln/level/fill.hh>
00047
00048 namespace oln
00049 {
00050 namespace lrde
00051 {
00052 namespace ufmt
00053 {
00054
00055
00056 template <typename I>
00057 class fiorio
00058 {
00059 typedef oln_point_type(I) point;
00060 typedef oln_value_type(I) value;
00061 typedef oln_iter_type(I) piter;
00062 typedef typename mute<I, point>::ret parent_type;
00063
00064 public:
00065 fiorio(const abstract::image<I>& ima) :
00066 ima_(ima.exact().clone()), parent_(ima.size())
00067 , n_level_roots_cpt_(ima.npoints())
00068 {
00069
00070 piter p (parent_);
00071 for_all (p)
00072 parent_[p] = p;
00073
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 build_tree_of_line(0);
00143 for (coord i = 1; i < ima_.nrows(); ++i)
00144 {
00145 build_tree_of_line(i);
00146
00147 merge_line(i);
00148 }
00149 }
00150
00151 void build_tree_of_line(coord row)
00152 {
00153
00154
00155 for (coord j = 1; j < ima_.ncols(); ++j)
00156 {
00157 point left = find_level_root(point(row, j - 1));
00158 point this_one = point(row, j);
00159 merge(left, this_one);
00160 }
00161 }
00162
00163 void merge_line(coord row)
00164 {
00165 precondition(row > 0);
00166
00167
00168 {
00169 point p (row, 0);
00170 point upper (row - 1, 0);
00171
00172 merge(p, upper);
00173 }
00174 for (coord col = 1; col < ima_.ncols(); ++col)
00175 {
00176 point p (row, col );
00177 point upper (row - 1, col );
00178
00179
00180
00181
00182 merge(p, upper);
00183 }
00184 }
00185
00186
00187
00189 void merge(const point& p, const point& q)
00190 {
00191 point r = find_level_root(p);
00192 point s = find_level_root(q);
00193
00194
00195 if (r == s)
00196 return;
00197
00198
00199 if (ima_[r] == ima_[s])
00200 --n_level_roots_cpt_;
00201
00202
00203
00204 if (ima_[r] < ima_[s])
00205 std::swap(r, s);
00206
00207 point t = parent_[r];
00208
00209
00210 if (r == t or ima_[s] > ima_[t])
00211 parent_[r] = s;
00212
00213
00214 merge(t, s);
00215 }
00216
00218 bool is_top(const point& p) const
00219 {
00220 return parent_[p] == p;
00221 }
00222
00223 bool is_level_root(const point& p) const
00224 {
00225 return
00226 is_top(p) ||
00227 (ima_[parent_[p]] != ima_[p]);
00228 }
00229
00234 point find_level_root(const point& p)
00235 {
00236
00237 if (not is_top(p))
00238 parent_[p] = find_level_root(parent_[p]);
00239
00240 if (is_level_root(p))
00241 return p;
00242 else
00243 return parent_[p];
00244 }
00245
00246 protected:
00248 I ima_;
00250 parent_type parent_;
00251
00252 unsigned n_level_roots_cpt_;
00253
00254 };
00255
00256 }
00257
00258 }
00259
00260 }
00261
00262 #endif // ! OLENA_LRDE_UFMT_FIORIO_1_HH