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_LRDE_UFMT_HDX_MAXTREE_HH
00029 # define OLENA_LRDE_UFMT_HDX_MAXTREE_HH
00030
00031 # include <oln/level/fill.hh>
00032 # include <oln/lrde/ufmt/utils.hh>
00033 # include <oln/lrde/ufmt/ad_maxtree.hh>
00034 # include <oln/lrde/ufmt/attributes.hh>
00035
00036
00037
00038 namespace oln
00039 {
00040
00041 namespace lrde
00042 {
00043
00044 namespace ufmt
00045 {
00046
00047
00048
00049
00050 template <class T>
00051 std::vector<int> to_index(const image2d<T>& input,
00052 const std::vector<dpoint2d>& dp_)
00053 {
00054 std::vector<int> dp(dp_.size());
00055 for (unsigned i = 0; i < dp_.size(); ++i)
00056 dp[i] = dp_[i].row() * (input.ncols() + 2 * input.border()) + dp_[i].col();
00057 return dp;
00058 }
00059
00060
00061
00062
00063
00064
00065 template <class I>
00066 struct hdx_maxtree : public ad_maxtree<I>
00067 {
00068 typedef ad_maxtree<I> super;
00069 using super::f;
00070 using super::dpar;
00071 oln_lrde_ufmt_import_ad_maxtree_typedefs;
00072
00073 const oln_neighborhood_type(I)& nbh;
00074
00075
00076 std::vector<int> S;
00077 std::vector<size_t> H;
00078 std::vector<oln_dpoint_type(I)> dp_pre_, dp_post_;
00079 std::vector<int> dp_pre, dp_post;
00080 unsigned nb;
00081 unsigned nnodes;
00082
00083 dparent_t c_dpar_;
00084 dpar_t c_dpar;
00085
00086
00087
00088 hdx_maxtree(const abstract::image<I>& f,
00089 const oln_neighborhood_type(I)& nbh)
00090 :
00091 super(f),
00092 nbh(nbh),
00093 c_dpar_(f.size())
00094 {
00095 c_dpar.init(c_dpar_);
00096 c_dpar.memset_0();
00097 }
00098
00099 void go()
00100 {
00101 init();
00102 compute_parent();
00103
00104 }
00105
00106 void init()
00107 {
00108 S = histogram_reverse_sort_i(f.real(), H);
00109 nb = split<I>(nbh, dp_pre_, dp_post_);
00110 dp_pre = to_index(f.real(), dp_pre_);
00111 dp_post = to_index(f.real(), dp_post_);
00112 nnodes = 1;
00113 dpar.memset_0();
00114 }
00115
00116 void compute_parent()
00117 {
00118 int ip = 0;
00119 for (int h = uint_nvalues(f.real()) - 1; h >= 0; --h)
00120 {
00121 int ip_first = ip;
00122 int ip_last = ip + H[h];
00123
00124
00125
00126 for (ip = ip_first; ip < ip_last; ++ip)
00127 {
00128 point p = S[ip];
00129
00130 for (unsigned i = 0; i < nb; ++i)
00131 {
00132 point n = p + dp_pre[i];
00133 if (f[n] >= h)
00134 do_adv_union(n, p);
00135 }
00136
00137 for (unsigned i = 0; i < nb; ++i)
00138 {
00139 point n = p + dp_post[i];
00140 if (f[n] > h)
00141 do_adv_union(n, p);
00142 }
00143 }
00144
00145
00146
00147 for (int i = ip_last - 1; i >= ip_first; --i)
00148 {
00149 point p = S[i];
00150
00151
00152
00153 c_dpar[p] += c_dpar[p + c_dpar[p]];
00154 }
00155
00156 }
00157 }
00158
00159
00160 point find_adv_root(point x)
00161 {
00162 if (is_root(x))
00163 return x;
00164 else
00165 {
00166 point lr = find_adv_root(x + c_dpar[x]);
00167 c_dpar[x] = lr - x;
00168 return lr;
00169 }
00170 }
00171
00172 void do_adv_union(const point& n, const point& p)
00173 {
00174 point r = find_adv_root(n);
00175 if (r != p)
00176 {
00177 dpar[r] = p - r;
00178 c_dpar[r] = p - r;
00179 if (f[p] < f[r])
00180 ++nnodes;
00181 }
00182 }
00183
00184 template <class A>
00185 std::vector< node_<A> >
00186 extract_maxtree()
00187 {
00188 std::vector< node_<A> > node(nnodes);
00189 dpar_t& label = dpar;
00190
00191
00192 unsigned cur_l = nnodes - 1;
00193 for (int i = S.size() - 1; i != 0; --i)
00194 {
00195 point p = S[i];
00196 assert(is_level_root(p + dpar[p]));
00197 if (is_level_root(p))
00198 {
00199
00200 point par_p = p + dpar[p];
00201 label[p] = cur_l;
00202 node[cur_l].par = label[par_p];
00203 if (is_root(p))
00204 assert(node[cur_l].par == cur_l);
00205 --cur_l;
00206 }
00207 else
00208
00209 label[p] = label[p + dpar[p]];
00210 }
00211 return node;
00212 }
00213
00214
00215 template <class A>
00216 void compute_attributes(std::vector< node_<A> >& node)
00217
00218 {
00219 dpar_t& label = dpar;
00220 for (int i = S.size() - 1; i != 0; --i)
00221 {
00222 point p = S[i];
00223 if (is_level_root(p))
00224 node[label[p]].init(f, p);
00225 else
00226 node[label[p]].insert(f, p);
00227 }
00228 for (int l = 0; l < nnodes; ++l)
00229 if (node[l].par != l)
00230 node[node[l].par].embrace(node[l]);
00231 }
00232
00233
00234
00235 };
00236
00237
00238
00239 }
00240
00241 }
00242
00243 }
00244
00245
00246 #endif // ! OLENA_LRDE_UFMT_HDX_MAXTREE_HH