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_HDC_MAXTREE_HH
00029 # define OLENA_LRDE_UFMT_HDC_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 hdc_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
00084
00085
00086 hdc_maxtree(const abstract::image<I>& f,
00087 const oln_neighborhood_type(I)& nbh)
00088 :
00089 super(f),
00090 nbh(nbh)
00091 {
00092 }
00093
00094 template <class A>
00095 void go()
00096 {
00097 init();
00098 compute_parent();
00099 extract_maxtree<A>();
00100 }
00101
00102 void init()
00103 {
00104 S = histogram_reverse_sort_i(f.real(), H);
00105 nb = split<I>(nbh, dp_pre_, dp_post_);
00106 dp_pre = to_index(f.real(), dp_pre_);
00107 dp_post = to_index(f.real(), dp_post_);
00108 nnodes = 0;
00109 dpar.memset_0();
00110 }
00111
00112 void compute_parent()
00113 {
00114 int ip = 0;
00115 for (int h = uint_nvalues(f.real()) - 1; h >= 0; --h)
00116 {
00117 int ip_first = ip;
00118 int ip_last = ip + H[h];
00119
00120
00121
00122 for (ip = ip_first; ip < ip_last; ++ip)
00123 {
00124 point p = S[ip];
00125
00126 for (unsigned i = 0; i < nb; ++i)
00127 {
00128 point n = p + dp_pre[i];
00129 if (f[n] >= h)
00130 do_union(n, p, h);
00131 }
00132
00133 for (unsigned i = 0; i < nb; ++i)
00134 {
00135 point n = p + dp_post[i];
00136 if (f[n] > h)
00137 do_union(n, p, h);
00138 }
00139 }
00140
00141
00142
00143 for (int i = ip_last - 1; i >= ip_first; --i)
00144 {
00145 point p = S[i];
00146 if (is_root(p))
00147 ++nnodes;
00148 else
00149 dpar[p] += dpar[p + dpar[p]];
00150 }
00151
00152 }
00153 }
00154
00155
00156 template <class A>
00157 std::vector< node_<A> >
00158 extract_maxtree()
00159 {
00160 std::vector< node_<A> > node(nnodes);
00161 dpar_t& label = dpar;
00162
00163
00164 unsigned cur_l = nnodes - 1;
00165 for (int i = S.size() - 1; i != 0; --i)
00166 {
00167 point p = S[i];
00168 assert(is_level_root(p + dpar[p]));
00169 if (is_level_root(p))
00170 {
00171
00172 point par_p = p + dpar[p];
00173 label[p] = cur_l;
00174 node[cur_l].par = label[par_p];
00175 if (is_root(p))
00176 assert(node[cur_l].par == cur_l);
00177 --cur_l;
00178 }
00179 else
00180
00181 label[p] = label[p + dpar[p]];
00182 }
00183 return node;
00184 }
00185
00186
00187 template <class A>
00188 void compute_attributes(std::vector< node_<A> >& node)
00189
00190 {
00191 dpar_t& label = dpar;
00192 for (int i = S.size() - 1; i != 0; --i)
00193 {
00194 point p = S[i];
00195 if (is_level_root(p))
00196 node[label[p]].init(f, p);
00197 else
00198 node[label[p]].insert(f, p);
00199 }
00200 for (int l = 0; l < nnodes; ++l)
00201 if (node[l].par != l)
00202 node[node[l].par].embrace(node[l]);
00203 }
00204
00205
00206 point find_root(point x, value h)
00207 {
00208 while (not is_root(x))
00209 if (f[x] > h)
00210 x += dpar[x];
00211 else
00212 x = find_level_root(x + dpar[x]);
00213 return x;
00214 }
00215
00216 void do_union(const point& n, const point& p, value h)
00217 {
00218 point r = find_root(n, h);
00219 if (r != p)
00220 dpar[r] = p - r;
00221 }
00222
00223
00224 };
00225
00226
00227
00228 }
00229
00230 }
00231
00232 }
00233
00234
00235 #endif // ! OLENA_LRDE_UFMT_HDC_MAXTREE_HH