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_BASIC_NAJMAN_HH
00029 # define OLENA_LRDE_UFMT_BASIC_NAJMAN_HH
00030
00031 # include <list>
00032
00033 # include <oln/level/fill.hh>
00034 # include <oln/lrde/ufmt/utils.hh>
00035 # include <oln/lrde/ufmt/ap_maxtree.hh>
00036
00037
00038 namespace oln
00039 {
00040
00041 namespace lrde
00042 {
00043
00044 namespace ufmt
00045 {
00046
00047 template <class I>
00048 struct basic_najman : public ap_maxtree<I>
00049 {
00050 typedef ap_maxtree<I> super;
00051 using super::f;
00052 using super::nbh;
00053 using super::par;
00054 oln_lrde_ufmt_import_ap_maxtree_typedefs;
00055
00056 struct node {
00057 int level;
00058 int area;
00059 int highest;
00060 std::list<point> children;
00061
00062 void addChildren(const node& n)
00063 {
00064 typename std::list<point>::const_iterator it;
00065 for (it = n.children.begin();
00066 it != n.children.end();
00067 ++it)
00068 children.push_back((*it));
00069 }
00070 void addChild(const point n)
00071 {
00072 children.push_back(n);
00073 }
00074 };
00075
00076 image2d<point> Par_tree;
00077
00078 image2d<int> Rnk_tree;
00079 image2d<int> Rnk_node;
00080 image2d<point> lowestNode;
00081 image2d<node> nodes;
00082 image2d<bool> isproc;
00083 point Root;
00084 std::vector<point> S;
00085
00086
00087
00088 basic_najman(const abstract::image<I>& f,
00089 const oln_neighborhood_type(I)& nbh)
00090 : ap_maxtree<I>(f, nbh),
00091 Par_tree(f.size()),
00092 Rnk_tree(f.size()),
00093 Rnk_node(f.size()),
00094 lowestNode(f.size()),
00095 nodes(f.size()),
00096 isproc(f.size())
00097 {
00098 }
00099
00100 void MakeSet_tree(point x)
00101 {
00102 Par_tree[x] = x;
00103 Rnk_tree[x] = 0;
00104 }
00105
00106 void MakeSet_node(point x)
00107 {
00108 par[x] = x;
00109 Rnk_node[x] = 0;
00110 }
00111
00112 point Find_tree(point x)
00113 {
00114 if (Par_tree[x] != x)
00115 Par_tree[x] = Find_tree(Par_tree[x]);
00116 return Par_tree[x];
00117 }
00118
00119 point Find_node(point x)
00120 {
00121 return find_level_root(x);
00122 }
00123
00124 void go()
00125 {
00126 init();
00127 BuildComponentTree();
00128 }
00129
00130 void init()
00131 {
00132 S = histogram_reverse_sort_p(f);
00133 level::fill(isproc, false);
00134 for (int ip = 0; ip < int(S.size()); ++ip)
00135 {
00136 point p = S[ip];
00137 MakeSet_node(p);
00138 MakeSet_tree(p);
00139
00140 lowestNode[p] = p;
00141
00142 nodes[p] = MakeNode(f[p]);
00143 }
00144 }
00145
00146 void BuildComponentTree()
00147 {
00148 for (int ip = 0; ip < int(S.size()); ++ip)
00149 {
00150 point p = S[ip];
00151 isproc[p] = true;
00152
00153 point curTree = Find_tree(p);
00154 point curNode = Find_node(lowestNode[curTree]);
00155
00156 oln_neighb_type(Nbh) q(nbh, p);
00157 for_all(q)
00158 if (f.hold(q) and isproc[q] and f[q] >= f[p])
00159 {
00160 point adjTree = Find_tree(q);
00161 point adjNode = Find_node(lowestNode[adjTree]);
00162 if (curNode != adjNode)
00163 {
00164 if (nodes[curNode].level == nodes[adjNode].level)
00165 curNode = MergeNode(adjNode, curNode);
00166 else
00167 {
00168
00169 nodes[curNode].addChild(adjNode);
00170
00171 nodes[curNode].area += nodes[adjNode].area;
00172 nodes[curNode].highest += nodes[adjNode].highest;
00173 }
00174 }
00175 curTree = Link_tree(adjTree, curTree);
00176 lowestNode[curTree] = curNode;
00177 }
00178 }
00179 Root = lowestNode[Find_tree(Find_node(point(0, 0)))];
00180
00181
00182
00183
00184
00185
00186 }
00187
00188 point MergeNode(point& node1, point& node2)
00189 {
00190 point tmpNode = Link_node(node1, node2);
00191 point tmpNode2;
00192 if (tmpNode == node2)
00193 {
00194 nodes[node2].addChildren(nodes[node1]);
00195 tmpNode2 = node1;
00196 }
00197 else
00198 {
00199 nodes[node1].addChildren(nodes[node2]);
00200 tmpNode2 = node2;
00201 }
00202 nodes[tmpNode].area += nodes[tmpNode2].area;
00203 nodes[tmpNode].highest += nodes[tmpNode2].highest;
00204 return tmpNode;
00205 }
00206
00207 point Link_tree(point x, point y)
00208 {
00209 if (Rnk_tree[x] > Rnk_tree[y])
00210 swap(x, y);
00211 else
00212 if (Rnk_tree[x] == Rnk_tree[y])
00213 Rnk_tree[y] += 1;
00214 Par_tree[x] = y;
00215 return y;
00216 }
00217
00218 point Link_node(point x, point y)
00219 {
00220 if (Rnk_node[x] > Rnk_node[y])
00221 swap(x, y);
00222 else
00223 if (Rnk_node[x] == Rnk_node[y])
00224 Rnk_node[y] += 1;
00225 par[x] = y;
00226 return y;
00227 }
00228
00229 node MakeNode(int level)
00230 {
00231 node n;
00232 n.level = level;
00233 n.area = 1;
00234 n.highest = level;
00235 return n;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 };
00275
00276 }
00277
00278 }
00279
00280 }
00281
00282
00283 #endif // ! OLENA_LRDE_UFMT_BASIC_NAJMAN_HH