27 #ifndef MLN_MORPHO_WATERSHED_TOPOLOGICAL_HH
28 # define MLN_MORPHO_WATERSHED_TOPOLOGICAL_HH
46 # include <mln/core/site_set/p_set.hh>
47 # include <mln/core/site_set/p_priority.hh>
48 # include <mln/core/site_set/p_queue_fast.hh>
50 # include <mln/util/ord.hh>
52 # include <mln/data/sort_psites.hh>
53 # include <mln/data/fill.hh>
70 const I& ima =
exact(ima_);
72 if (components.is_empty())
77 mln_psite(I)
min = components[0];
80 if (ima(it) < ima(
min))
87 mln_psite(I)
max(
p_set<mln_psite(I)>& components)
89 if (components.is_empty())
94 mln_psite(I)
max = components[0];
97 if (ima(it) > ima(
max))
105 template <
class I,
class N>
121 typedef mln_psite(I)
psite;
124 std::vector<psite> children;
126 void addChildren(
const node& n)
133 for (
unsigned i=0; i < n.children.size(); ++i)
134 children.push_back(n.children[i]);
137 void addChild(
const psite
p)
140 children.push_back(p);
157 void MakeSet_tree(
psite x);
158 void MakeSet_node(
psite x);
161 void BuildComponentTree();
165 node MakeNode(
int level);
168 mln_ch_value(I,
bool) isproc;
197 std::map<
psite,
int, mln::util::ord<psite> > pos;
203 void compute_ctree_size (psite
p);
204 void build_euler_tour_rec(psite p,
int &position,
int d);
205 void build_euler_tour();
207 void removeOneSonNodes(psite *p, mln_ch_value(I, psite) &newPar_node);
218 # ifndef MLN_INCLUDE_ONLY
221 template <
class I,
class N>
235 template <
class I,
class N>
242 template <
class I,
class N>
243 void topo_wst<I, N>::MakeSet_node(psite x)
249 template <
class I,
class N>
250 typename topo_wst<I, N>::psite topo_wst<I, N>::Find_tree(psite x)
252 if (Par_tree(x) != x)
253 Par_tree(x) = Find_tree(Par_tree(x));
257 template <
class I,
class N>
258 typename topo_wst<I, N>::psite topo_wst<I, N>::Find_node(psite x)
260 if (Par_node(x) != x)
261 Par_node(x) = Find_node(Par_node(x));
265 template <
class I,
class N>
268 BuildComponentTree();
275 template <
class I,
class N>
276 void topo_wst<I, N>::BuildComponentTree()
281 p_array<mln_psite(I)> S;
286 for (
int ip = 0; ip < int(S.nsites()); ++ip)
294 nodes(p) = MakeNode(ima(p));
299 typename p_array<mln_psite(I)>::fwd_piter ip(S);
304 psite curCanonicalElt = Find_tree(p);
305 psite curNode = Find_node(subtreeRoot(curCanonicalElt));
308 mln_niter(N) q(nbh, ip);
310 if (ima.has(q) and isproc(q) and ima(q) <= ima(p))
312 psite adjCanonicalElt = Find_tree(q);
313 psite adjNode = Find_node(subtreeRoot(adjCanonicalElt));
314 if (curNode != adjNode)
316 if (nodes(curNode).level == nodes(adjNode).level)
317 curNode = MergeNode(adjNode, curNode);
320 nodes(curNode).addChild(adjNode);
321 nodes(curNode).area += nodes(adjNode).area;
322 nodes(curNode).highest += nodes(adjNode).highest;
326 curCanonicalElt = Link_tree(adjCanonicalElt, curCanonicalElt);
327 subtreeRoot(curCanonicalElt) = curNode;
338 mln_piter(I) r(Par_node.domain());
340 Par_node(r) = Find_node(r);
344 mln_fwd_piter(I) rp(Par_node.domain());;
347 Root = subtreeRoot(Find_tree(Find_node(rp)));
351 template <class I, class N>
352 typename topo_wst<I, N>::psite topo_wst<I, N>::MergeNode(psite& node1,
355 psite tmpNode = Link_node(node1, node2);
357 if (tmpNode == node2)
359 nodes(node2).addChildren(nodes(node1));
364 nodes(node1).addChildren(nodes(node2));
367 nodes(tmpNode).area += nodes(tmpNode2).area;
368 nodes(tmpNode).highest += nodes(tmpNode2).highest;
372 template <
class I,
class N>
373 typename topo_wst<I, N>::psite topo_wst<I, N>::Link_tree(psite x, psite y)
375 if (Rnk_tree(x) > Rnk_tree(y))
378 if (Rnk_tree(x) == Rnk_tree(y))
384 template <
class I,
class N>
385 typename topo_wst<I, N>::psite topo_wst<I, N>::Link_node(psite x, psite y)
387 if (Rnk_node(x) > Rnk_node(y))
390 if (Rnk_node(x) == Rnk_node(y))
396 template <
class I,
class N>
397 typename topo_wst<I, N>::node topo_wst<I, N>::MakeNode(
int level)
407 template <
class I,
class N>
408 bool topo_wst<I, N>::highest_fork (p_set<psite>& components, psite &r)
410 if (components.nsites() == 0)
412 std::cerr <<
"highest fork : empty set" << std::endl;
420 typename p_set<psite>::fwd_piter it(components);
424 if (it.to_psite() == m)
427 psite c = lca(hfork, it.to_psite());
428 if (c != it.to_psite())
432 if (nodes(m).level == nodes(hfork).level)
439 template <
class I,
class N>
440 bool topo_wst<I, N>::highest_fork (p_set<psite>& components) {
442 return highest_fork(components, i);
445 template <
class I,
class N>
446 void topo_wst<I, N>::compute_ctree_size (psite p)
455 for (
unsigned i=0; i < n.children.size(); ++i)
456 compute_ctree_size(n.children[i]);
460 template <
class I,
class N>
461 void topo_wst<I, N>::build_euler_tour_rec(psite p,
int &position,
int d)
463 if (pos.find(p) == pos.end())
468 euler[position] = pos[
p];
482 for (
unsigned i=0; i < n.children.size(); ++i)
484 build_euler_tour_rec(n.children[i], position, d+1);
486 euler[position] = pos[
p];
493 template <
class I,
class N>
494 void topo_wst<I, N>::build_euler_tour ()
497 compute_ctree_size(Root);
499 int size = 2 * ctree_size - 1;
502 euler =
new int[size];
503 depth =
new int[size];
504 repr =
new psite[size];
507 build_euler_tour_rec(Root, position, 0);
511 template <
class I,
class N>
512 void topo_wst<I, N>::build_minim ()
515 int size = 2 * ctree_size - 1;
516 int logn = (int)(ceil(
log((
double)(size))/
log(2.0)));
518 minim =
new int [logn * size];
519 Minim =
new int* [logn];
524 for (
int i = 0; i < size - 1; ++i)
525 if (depth[euler[i]] < depth[euler[i+1]]) {
534 for (
int j = 1; j < logn; j++) {
536 Minim[j] = &minim[j * size];
537 for (
int i = 0; i < size; i++) {
538 if ((i + (k << 1)) >= size) {
542 if (depth[euler[Minim[j - 1][i]]]
543 <= depth[euler[Minim[j - 1][i + k]]])
544 Minim[j][i] = Minim[j - 1][i];
546 Minim[j][i] = Minim[j - 1][i + k];
554 template <
class I,
class N>
572 k = (int)(
log((
double)(n - m))/
log(2.));
574 if (depth[euler[Minim[k][m]]] < depth[euler[Minim[k][n - (1 << k)]]]) {
575 return repr[euler[Minim[k][m]]];
577 return repr[euler[Minim[k][n - (1 << k)]]];
582 template <
class I,
class N>
583 void topo_wst<I, N>::removeOneSonNodes(psite *p,
584 mln_ch_value(I, psite) &newPar_node)
588 if (n.children.size() == 1)
591 newPar_node(*p) = n.children[0];
593 removeOneSonNodes(p, newPar_node);
597 for (
unsigned i = 0; i < n.children.size(); ++i)
598 removeOneSonNodes(&(n.children[i]), newPar_node);
603 template <
class I,
class N>
604 void topo_wst<I, N>::compressTree()
606 mln_ch_value(I, psite) newPar_node;
610 removeOneSonNodes(&Root, newPar_node);
613 mln_piter(I) p(Par_node.domain());
615 while (nodes(Par_node(p)).
area == -1)
616 Par_node(p) = newPar_node(Par_node(p));
620 bool w_constructible(
T &tree, typename
T::psite p, typename
T::psite &r)
623 typedef typename T::image_t I;
624 typedef typename T::neighborhood_t N;
626 const I &ima =
exact(tree.ima);
627 const N &nbh =
exact(tree.nbh);
630 mln_niter(N) q(nbh, p);
631 p_set<mln_psite(I)> v;
636 if (ima.domain().has(q) && ima(q) < ima(p))
637 v.insert(tree.Par_node(q));
648 mln_psite(I) c =
min(ima, v);
649 mln_psite(I) cmin = c;
651 typename p_set<mln_psite(I)>::
fwd_piter it(v);
658 mln_psite(I) c1 = tree.lca(c, it);
664 if (tree.nodes(c).level >= ima(p))
672 bool w_constructible(
T &tree, typename
T::psite p) {
674 return w_constructible(tree, p, r);
683 typedef typename T::image_t I;
684 typedef typename T::neighborhood_t N;
686 I ima =
exact(tree.ima);
687 const N &nbh =
exact(tree.nbh);
690 mln_ch_value(I,
bool) cmax;
694 mln_ch_value(I,
bool) enqueued;
697 p_priority< mln_value(I), p_queue_fast<mln_psite(I)> > l;
699 std::queue<mln_psite(I)> m;
705 mln_piter(I) it(tree.Par_node.domain());
708 if (tree.nodes(tree.Par_node(it)).children.size() == 0)
717 mln_niter(N) q(nbh, m.front());
721 if (cmax.domain().has(q) && !cmax(q) && !enqueued(q))
724 l.push(mln_max(mln_value(I)) - ima(q), q);
731 while (!l.is_empty())
733 mln_psite(I) x = l.front();
738 bool is_w = w_constructible(tree, x, c);
742 ima(x) = tree.nodes(c).level;
743 tree.Par_node(x) = c;
746 if (tree.nodes(c).children.size() == 0)
750 if (tree.nodes(c).children.size() == 1)
751 std::cerr <<
"ERREUR COMPOSANTE BRANCHE "
752 << tree.nodes(c).children.size() << std::endl;
756 mln_niter(N) q(nbh, x);
760 if (ima.domain().has(q) && !cmax(q) && !enqueued(q))
763 l.push(mln_max(mln_value(I)) - ima(q), q);
773 ima(it) = tree.nodes(tree.Par_node(it)).level;
778 # endif // MLN_INCLUDE_ONLY
787 #endif // ! MLN_MORPHO_WATERSHED_TOPOLOGICAL_HH