unionfind.hpp
Go to the documentation of this file.
1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4 //
5 // Copyright (C) 2013-2016, The Regents of The University of Michigan.
6 //
7 // This software was developed in the APRIL Robotics Lab under the
8 // direction of Edwin Olson, ebolson@umich.edu. This software may be
9 // available under alternative licensing terms; contact the address above.
10 //
11 // The views and conclusions contained in the software and documentation are those
12 // of the authors and should not be interpreted as representing official policies,
13 // either expressed or implied, of the Regents of The University of Michigan.
14 #ifndef _OPENCV_UNIONFIND_HPP_
15 #define _OPENCV_UNIONFIND_HPP_
16 
17 #include <stdint.h>
18 #include <stdlib.h>
19 namespace cv {
20 namespace aruco {
21 
22 typedef struct unionfind unionfind_t;
23 struct unionfind{
24  uint32_t maxid;
25  struct ufrec *data;
26 };
27 
28 struct ufrec{
29  // the parent of this node. If a node's parent is its own index,
30  // then it is a root.
31  uint32_t parent;
32 
33  // for the root of a connected component, the number of components
34  // connected to it. For intermediate values, it's not meaningful.
35  uint32_t size;
36 };
37 
38 static inline unionfind_t *unionfind_create(uint32_t maxid){
39  unionfind_t *uf = (unionfind_t*) calloc(1, sizeof(unionfind_t));
40  uf->maxid = maxid;
41  uf->data = (struct ufrec*) malloc((maxid+1) * sizeof(struct ufrec));
42  for (unsigned int i = 0; i <= maxid; i++) {
43  uf->data[i].size = 1;
44  uf->data[i].parent = i;
45  }
46  return uf;
47 }
48 
49 static inline void unionfind_destroy(unionfind_t *uf){
50  free(uf->data);
51  free(uf);
52 }
53 
54 /*
55 static inline uint32_t unionfind_get_representative(unionfind_t *uf, uint32_t id)
56 {
57  // base case: a node is its own parent
58  if (uf->data[id].parent == id)
59  return id;
60 
61  // otherwise, recurse
62  uint32_t root = unionfind_get_representative(uf, uf->data[id].parent);
63 
64  // short circuit the path. [XXX This write prevents tail recursion]
65  uf->data[id].parent = root;
66 
67  return root;
68 }
69  */
70 
71 // this one seems to be every-so-slightly faster than the recursive
72 // version above.
73 static inline uint32_t unionfind_get_representative(unionfind_t *uf, uint32_t id){
74  uint32_t root = id;
75 
76  // chase down the root
77  while (uf->data[root].parent != root) {
78  root = uf->data[root].parent;
79  }
80 
81  // go back and collapse the tree.
82  //
83  // XXX: on some of our workloads that have very shallow trees
84  // (e.g. image segmentation), we are actually faster not doing
85  // this...
86  while (uf->data[id].parent != root) {
87  uint32_t tmp = uf->data[id].parent;
88  uf->data[id].parent = root;
89  id = tmp;
90  }
91 
92  return root;
93 }
94 
95 static inline uint32_t unionfind_get_set_size(unionfind_t *uf, uint32_t id){
96  uint32_t repid = unionfind_get_representative(uf, id);
97  return uf->data[repid].size;
98 }
99 
100 static inline uint32_t unionfind_connect(unionfind_t *uf, uint32_t aid, uint32_t bid){
101  uint32_t aroot = unionfind_get_representative(uf, aid);
102  uint32_t broot = unionfind_get_representative(uf, bid);
103 
104  if (aroot == broot)
105  return aroot;
106 
107  // we don't perform "union by rank", but we perform a similar
108  // operation (but probably without the same asymptotic guarantee):
109  // We join trees based on the number of *elements* (as opposed to
110  // rank) contained within each tree. I.e., we use size as a proxy
111  // for rank. In my testing, it's often *faster* to use size than
112  // rank, perhaps because the rank of the tree isn't that critical
113  // if there are very few nodes in it.
114  uint32_t asize = uf->data[aroot].size;
115  uint32_t bsize = uf->data[broot].size;
116 
117  // optimization idea: We could shortcut some or all of the tree
118  // that is grafted onto the other tree. Pro: those nodes were just
119  // read and so are probably in cache. Con: it might end up being
120  // wasted effort -- the tree might be grafted onto another tree in
121  // a moment!
122  if (asize > bsize) {
123  uf->data[broot].parent = aroot;
124  uf->data[aroot].size += bsize;
125  return aroot;
126  } else {
127  uf->data[aroot].parent = broot;
128  uf->data[broot].size += asize;
129  return broot;
130  }
131 }
132 }}
133 #endif
static uint32_t unionfind_get_set_size(unionfind_t *uf, uint32_t id)
Definition: unionfind.hpp:95
Definition: charuco.hpp:47
static uint32_t unionfind_get_representative(unionfind_t *uf, uint32_t id)
Definition: unionfind.hpp:73
static void unionfind_destroy(unionfind_t *uf)
Definition: unionfind.hpp:49
struct ufrec * data
Definition: unionfind.hpp:25
uint32_t parent
Definition: unionfind.hpp:31
static uint32_t unionfind_connect(unionfind_t *uf, uint32_t aid, uint32_t bid)
Definition: unionfind.hpp:100
static unionfind_t * unionfind_create(uint32_t maxid)
Definition: unionfind.hpp:38


aruco_pose
Author(s): Oleg Kalachev
autogenerated on Mon Feb 28 2022 22:08:24