Skip to content

Commit b3281b7

Browse files
committed
Cache unionfind structure across detect calls and lazy-initialize size array
1 parent 3057666 commit b3281b7

File tree

4 files changed

+35
-5
lines changed

4 files changed

+35
-5
lines changed

apriltag.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,9 @@ void apriltag_detector_destroy(apriltag_detector_t *td)
411411
apriltag_detector_clear_families(td);
412412

413413
zarray_destroy(td->tag_families);
414+
if (td->cached_uf) {
415+
unionfind_destroy(td->cached_uf);
416+
}
414417
free(td);
415418
}
416419

apriltag.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ extern "C" {
3939
#include "common/workerpool.h"
4040
#include "common/timeprofile.h"
4141
#include "common/pthreads_cross.h"
42+
#include "common/unionfind.h"
4243

4344
#define APRILTAG_TASKS_PER_THREAD_TARGET 10
4445

@@ -188,6 +189,9 @@ struct apriltag_detector
188189

189190
// Used for thread safety.
190191
pthread_mutex_t mutex;
192+
193+
// Cached unionfind structure (reused across detect calls)
194+
unionfind_t *cached_uf;
191195
};
192196

193197
// Represents the detection of a tag. These are returned to the user

apriltag_quad_thresh.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,7 +1511,17 @@ image_u8_t *threshold_bayer(apriltag_detector_t *td, image_u8_t *im)
15111511
}
15121512

15131513
unionfind_t* connected_components(apriltag_detector_t *td, image_u8_t* threshim, int w, int h, int ts) {
1514-
unionfind_t *uf = unionfind_create(w * h);
1514+
uint32_t maxid = w * h;
1515+
if (td->cached_uf) {
1516+
if (td->cached_uf->maxid <= maxid) {
1517+
unionfind_reset(td->cached_uf);
1518+
} else {
1519+
unionfind_resize(td->cached_uf, maxid);
1520+
}
1521+
} else {
1522+
td->cached_uf = unionfind_create(maxid);
1523+
}
1524+
unionfind_t *uf = td->cached_uf;
15151525

15161526
if (td->nthreads <= 1) {
15171527
do_unionfind_first_line(uf, threshim, w, ts);
@@ -2004,8 +2014,6 @@ zarray_t *apriltag_quad_thresh(apriltag_detector_t *td, image_u8_t *im)
20042014

20052015
timeprofile_stamp(td->tp, "fit quads to clusters");
20062016

2007-
unionfind_destroy(uf);
2008-
20092017
for (int i = 0; i < zarray_size(clusters); i++) {
20102018
zarray_t *cluster;
20112019
zarray_get(clusters, i, &cluster);

common/unionfind.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,28 @@ struct unionfind
4444
uint32_t *size;
4545
};
4646

47+
static inline void unionfind_reset(unionfind_t *uf)
48+
{
49+
memset(uf->parent, 0xff, (uf->maxid+1) * sizeof(uint32_t));
50+
// uf->size is lazily initialized in unionfind_get_representative
51+
}
52+
4753
static inline unionfind_t *unionfind_create(uint32_t maxid)
4854
{
4955
unionfind_t *uf = (unionfind_t*) calloc(1, sizeof(unionfind_t));
5056
uf->maxid = maxid;
5157
uf->parent = (uint32_t *) malloc((maxid+1) * sizeof(uint32_t) * 2);
52-
memset(uf->parent, 0xff, (maxid+1) * sizeof(uint32_t));
5358
uf->size = uf->parent + (maxid+1);
54-
memset(uf->size, 0, (maxid+1) * sizeof(uint32_t));
59+
unionfind_reset(uf);
60+
return uf;
61+
}
62+
63+
static inline unionfind_t *unionfind_resize(unionfind_t *uf, uint32_t maxid)
64+
{
65+
uf->maxid = maxid;
66+
uf->parent = (uint32_t *) realloc(uf->parent, (maxid+1) * sizeof(uint32_t) * 2);
67+
uf->size = uf->parent + (maxid+1);
68+
unionfind_reset(uf);
5569
return uf;
5670
}
5771

@@ -85,6 +99,7 @@ static inline uint32_t unionfind_get_representative(unionfind_t *uf, uint32_t id
8599
// unititialized node, so set to self
86100
if (uf->parent[id] == 0xffffffff) {
87101
uf->parent[id] = id;
102+
uf->size[id] = 0;
88103
return id;
89104
}
90105

0 commit comments

Comments
 (0)