Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: trying out bbdt for 2D boolean case #42

Draft
wants to merge 24 commits into
base: master
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
fd65a38
wip: trying out bbdt for 2D boolean case
william-silversmith Sep 6, 2020
0c3297d
wip: can run bbdt but it segfaults
william-silversmith Sep 6, 2020
28c475d
fix: bbdt appears to be working though it needs tuning
william-silversmith Sep 7, 2020
ee232f4
wip: trying a more traditional approach
william-silversmith Sep 7, 2020
c61003f
perf: skip some checks given we know X is ok
william-silversmith Sep 7, 2020
ce6914b
wip: may have fixed issue with pieces not being unified
william-silversmith Sep 7, 2020
c5af4ff
perf: replace function calls with macros
william-silversmith Sep 30, 2020
021dda2
test: save test configuration
william-silversmith Sep 30, 2020
db36a72
fix: incorrect references
william-silversmith Oct 2, 2020
8f972b0
Merge branch 'master' into wms_bbdt
william-silversmith Oct 3, 2020
5852d79
perf: skip unification if unnecessary
william-silversmith Oct 3, 2020
aa0e7dd
fix+perf: errors in decision tree and unnecessary unifies
william-silversmith Oct 3, 2020
27e847e
perf: skip unnecessary check of B
william-silversmith Oct 3, 2020
8edf301
refactor: whitespace change
william-silversmith Oct 3, 2020
e2ce90a
wip: not working but closer in concept to the was bbdt should work
william-silversmith Dec 25, 2020
8f7915e
fix: several errors in bbdt implementation
william-silversmith Dec 25, 2020
089e851
fix: oA computed wrong
william-silversmith Dec 25, 2020
604602f
perf: faster relabel loop
william-silversmith Dec 26, 2020
1e73adb
fix: make comparison more robust
william-silversmith Dec 26, 2020
fcf6602
fix: make the comparison more robust in relabel
william-silversmith Dec 26, 2020
80b9a9e
fix: loc was not computed correctly for odd sizes
william-silversmith Dec 26, 2020
47ac1ca
fix: missing join of A
william-silversmith Dec 26, 2020
0df79d7
perf: faster relabel loop
william-silversmith Dec 26, 2020
fb35532
fix: np.bool doesn't work anymore
william-silversmith Jul 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
perf: replace function calls with macros
william-silversmith committed Sep 30, 2020
commit c5af4ff829549ad2281270a8e3d62134d1ca1ecc
276 changes: 138 additions & 138 deletions cc3d.hpp
Original file line number Diff line number Diff line change
@@ -756,12 +756,11 @@ OUT* connected_components2d_8(
template <typename T, typename OUT = uint32_t>
OUT* connected_components2d_8_bbdt(
T* in_labels,
const int64_t sx, const int64_t sy, const int64_t sz = 1,
const int64_t sx, const int64_t sy,
size_t max_labels = 10000000000000000, OUT *out_labels = NULL
) {

const int64_t sxy = sx * sy;
const int64_t voxels = sx * sy * sz;
const int64_t voxels = sx * sy;

max_labels = std::max(std::min(max_labels, static_cast<size_t>(voxels)), static_cast<size_t>(1L)); // can't allocate 0 arrays
max_labels = std::min(max_labels, static_cast<size_t>(std::numeric_limits<OUT>::max()));
@@ -796,183 +795,184 @@ OUT* connected_components2d_8_bbdt(
int64_t loc = 0;
OUT next_label = 0;

std::function<void(int64_t,int64_t,int64_t,OUT)> assignY = [X,Y,Z,W,sx,sy,out_labels,in_labels](int64_t x, int64_t y, int64_t loc, OUT value) {
out_labels[loc + Y] = value;
if (x < sx - 1) {
out_labels[loc + Z] = (in_labels[loc + Z] > 0) * value;
}
if (y < sy - 1) {
out_labels[loc + X] = (in_labels[loc + X] > 0) * value;
}
if (x < sx - 1 && y < sy - 1) {
out_labels[loc + W] = (in_labels[loc + W] > 0) * value;
}
};
#define ASSIGN_Y(value) \
out_labels[loc + Y] = (value); \
if (x < sx - 1 && in_labels[loc + Z]) { \
out_labels[loc + Z] = (value); \
} \
if (y < sy - 1 && in_labels[loc + X]) { \
out_labels[loc + X] = (value); \
} \
if (x < sx - 1 && y < sy - 1 && in_labels[loc + W]) { \
out_labels[loc + W] = (value); \
}

std::function<void(int64_t,int64_t,int64_t,OUT)> assignZ = [X,Z,W,sy,out_labels,in_labels](int64_t x, int64_t y, int64_t loc, OUT value) {
out_labels[loc + Z] = value;
if (y < sy - 1) {
out_labels[loc + X] = (in_labels[loc + X] > 0) * value;
out_labels[loc + W] = (in_labels[loc + W] > 0) * value;
#define ASSIGN_Z(value) \
out_labels[loc + Z] = (value); \
if (y < sy - 1 && in_labels[loc + X]) { \
out_labels[loc + X] = (value); \
} \
if (y < sy - 1 && in_labels[loc +W]) { \
out_labels[loc + W] = (value); \
}
};

std::function<void(int64_t,int64_t,int64_t,OUT)> assignX = [X,W,sx,out_labels,in_labels](int64_t x, int64_t y, int64_t loc, OUT value) {
out_labels[loc + X] = value;
if (x < sx - 1) {
out_labels[loc + W] = (in_labels[loc + W] > 0) * value;
}
};
#define ASSIGN_X(value) \
out_labels[loc + X] = (value); \
if (x < sx - 1 && in_labels[loc + W]) { \
out_labels[loc + W] = (value); \
}

// Raster Scan 1: Set temporary labels and
// record equivalences in a disjoint set.
for (int64_t z = 0; z < sz; z++) {
for (int64_t y = 0; y < sy; y += 2) {
for (int64_t x = 0; x < sx; x += 2) {
loc = x + sx * y + sxy * z;

if (in_labels[loc + Y]) {
if (y > 0 && in_labels[loc + D]) {
assignY(x, y, loc, out_labels[loc + D]);
if (x < sx - 2 && in_labels[loc + Z] && in_labels[loc + F]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + F]);
}
for (int64_t y = 0; y < sy; y += 2) {
for (int64_t x = 0; x < sx; x += 2) {
loc = x + sx * y;

if (in_labels[loc + Y]) {
if (y > 0 && in_labels[loc + D]) {
ASSIGN_Y(out_labels[loc + D]);
if (x < sx - 2 && in_labels[loc + Z] && in_labels[loc + F]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + F]);
}
else if (y > 0 && x < sx - 1 && in_labels[loc + E]) {
assignY(x, y, loc, out_labels[loc + E]);
if (x < sx - 2 && in_labels[loc + Z] && in_labels[loc + F]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + F]);
}
if (x > 0 && y > 0 && in_labels[loc + C]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + C]);
if (y < sy - 1 && !in_labels[loc + B] && in_labels[loc + A]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + A]);
}
}
else if (x > 0 && in_labels[loc + B]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + B]);
}
else if (x > 0 && y < sy - 1 && in_labels[loc + A]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + A]);
}
}
else if (y > 0 && x < sx - 1 && in_labels[loc + E]) {
ASSIGN_Y(out_labels[loc + E]);
if (x < sx - 2 && in_labels[loc + Z] && in_labels[loc + F]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + F]);
}
else if (x > 0 && y > 0 && in_labels[loc + C]) {
assignY(x, y, loc, out_labels[loc + C]);
if (x > 0 && y > 0 && in_labels[loc + C]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + C]);
if (y < sy - 1 && !in_labels[loc + B] && in_labels[loc + A]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + A]);
}
if (x < sx - 2 && in_labels[loc + Z] && in_labels[loc + F]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + F]);
}
}
else if (x > 0 && in_labels[loc + B]) {
assignY(x, y, loc, out_labels[loc + B]);
if (x < sx - 2 && in_labels[loc + Z] && in_labels[loc + F]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + F]);
}
}
else if (x > 0 && y < sx - 1 && in_labels[loc + A]) {
assignY(x, y, loc, out_labels[loc + A]);
if (x < sx - 2 && in_labels[loc + Z] && in_labels[loc + F]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + F]);
}
equivalences.unify(out_labels[loc + Y], out_labels[loc + B]);
}
else if (x < sx - 2 && y > 0 && in_labels[loc + Z] && in_labels[loc + F]) {
assignY(x, y, loc, out_labels[loc + F]);
else if (x > 0 && y < sy - 1 && in_labels[loc + A]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + A]);
}
else {
next_label++;
assignY(x, y, loc, next_label);
equivalences.add(next_label);
}
else if (x > 0 && y > 0 && in_labels[loc + C]) {
ASSIGN_Y(out_labels[loc + C]);
if (y < sy - 1 && !in_labels[loc + B] && in_labels[loc + A]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + A]);
}
if (x < sx - 2 && in_labels[loc + Z] && in_labels[loc + F]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + F]);
}
}
else if (x < sx - 1 && in_labels[loc + Z]) {
if (y > 0 && in_labels[loc + D]) {
assignZ(x, y, loc, out_labels[loc + D]);
if (x < sx - 2 && in_labels[loc + F]) {
equivalences.unify(out_labels[loc + Z], out_labels[loc + F]);
}
if (x > 0 && y < sy - 1 && in_labels[loc + X]) {
if (in_labels[loc + B]) {
equivalences.unify(out_labels[loc + Z], out_labels[loc + B]);
}
else if (in_labels[loc + A]) {
equivalences.unify(out_labels[loc + Z], out_labels[loc + A]);
}
}
else if (x > 0 && in_labels[loc + B]) {
ASSIGN_Y(out_labels[loc + B]);
if (x < sx - 2 && in_labels[loc + Z] && in_labels[loc + F]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + F]);
}
}
else if (x > 0 && y < sx - 1 && in_labels[loc + A]) {
ASSIGN_Y(out_labels[loc + A]);
if (x < sx - 2 && in_labels[loc + Z] && in_labels[loc + F]) {
equivalences.unify(out_labels[loc + Y], out_labels[loc + F]);
}
}
else if (x < sx - 2 && y > 0 && in_labels[loc + Z] && in_labels[loc + F]) {
ASSIGN_Y(out_labels[loc + F]);
}
else {
next_label++;
ASSIGN_Y(next_label);
equivalences.add(next_label);
}
}
else if (x < sx - 1 && in_labels[loc + Z]) {
if (y > 0 && in_labels[loc + D]) {
ASSIGN_Z(out_labels[loc + D]);
if (x < sx - 2 && in_labels[loc + F]) {
equivalences.unify(out_labels[loc + Z], out_labels[loc + F]);
}
else if (y > 0 && in_labels[loc + E]) {
assignZ(x, y, loc, out_labels[loc + E]);
if (x < sx - 2 && in_labels[loc + F]) {
equivalences.unify(out_labels[loc + Z], out_labels[loc + F]);
if (x > 0 && y < sy - 1 && in_labels[loc + X]) {
if (in_labels[loc + B]) {
equivalences.unify(out_labels[loc + Z], out_labels[loc + B]);
}
else if (in_labels[loc + A]) {
equivalences.unify(out_labels[loc + Z], out_labels[loc + A]);
}
if (x > 0 && y < sy - 1 && in_labels[loc + X]) {
if (in_labels[loc + B]) {
equivalences.unify(out_labels[loc + X], out_labels[loc + B]);
}
else if (in_labels[loc + A]) {
equivalences.unify(out_labels[loc + X], out_labels[loc + A]);
}
}
}
else if (x < sx - 2 && y > 0 && in_labels[loc + F]) {
assignZ(x, y, loc, out_labels[loc + F]);
if (x > 0 && y < sy - 1 && in_labels[loc + X]) {
if (in_labels[loc + B]) {
equivalences.unify(out_labels[loc + X], out_labels[loc + B]);
}
else if (in_labels[loc + A]) {
equivalences.unify(out_labels[loc + X], out_labels[loc + A]);
}
}
}
else if (y > 0 && in_labels[loc + E]) {
ASSIGN_Z(out_labels[loc + E]);
if (x < sx - 2 && in_labels[loc + F]) {
equivalences.unify(out_labels[loc + Z], out_labels[loc + F]);
}
else if (x > 0 && y < sy - 1 && in_labels[loc + X]) {
if (x > 0 && y < sy - 1 && in_labels[loc + X]) {
if (in_labels[loc + B]) {
out_labels[loc + Z] = out_labels[loc + B];
assignX(x, y, loc, out_labels[loc + B]);
equivalences.unify(out_labels[loc + X], out_labels[loc + B]);
}
else if (in_labels[loc + A]) {
out_labels[loc + Z] = out_labels[loc + A];
assignX(x, y, loc, out_labels[loc + A]);
equivalences.unify(out_labels[loc + X], out_labels[loc + A]);
}
else {
next_label++;
out_labels[loc + Z] = next_label;
assignX(x, y, loc, next_label);
equivalences.add(next_label);
}
}
else if (x < sx - 2 && y > 0 && in_labels[loc + F]) {
ASSIGN_Z(out_labels[loc + F]);
if (x > 0 && y < sy - 1 && in_labels[loc + X]) {
if (in_labels[loc + B]) {
equivalences.unify(out_labels[loc + X], out_labels[loc + B]);
}
}
else { // ZW
next_label++;
out_labels[loc + Z] = next_label;
if (y < sy - 1 && in_labels[loc + W]) {
out_labels[loc + W] = next_label;
else if (in_labels[loc + A]) {
equivalences.unify(out_labels[loc + X], out_labels[loc + A]);
}
equivalences.add(next_label);
}
}
}
else if (x > 0 && y < sy - 1 && in_labels[loc + X]) {
if (in_labels[loc + B]) {
assignX(x, y, loc, out_labels[loc + B]);
out_labels[loc + Z] = out_labels[loc + B];
ASSIGN_X(out_labels[loc + B]);
}
else if (in_labels[loc + A]) {
assignX(x, y, loc, out_labels[loc + A]);
}
out_labels[loc + Z] = out_labels[loc + A];
ASSIGN_X(out_labels[loc + A]);
}
else {
next_label++;
assignX(x, y, loc, next_label);
out_labels[loc + Z] = next_label;
ASSIGN_X(next_label);
equivalences.add(next_label);
}
}
}
else if (x < sx - 1 && y < sy - 1 && in_labels[loc + W]) {
else { // ZW
next_label++;
out_labels[loc + W] = next_label;
equivalences.add(next_label);
out_labels[loc + Z] = next_label;
if (y < sy - 1 && in_labels[loc + W]) {
out_labels[loc + W] = next_label;
}
equivalences.add(next_label);
}
}
else if (x > 0 && y < sy - 1 && in_labels[loc + X]) {
if (in_labels[loc + B]) {
ASSIGN_X(out_labels[loc + B]);
}
else if (in_labels[loc + A]) {
ASSIGN_X(out_labels[loc + A]);
}
else {
next_label++;
ASSIGN_X(next_label);
equivalences.add(next_label);
}
}
else if (x < sx - 1 && y < sy - 1 && in_labels[loc + W]) {
next_label++;
out_labels[loc + W] = next_label;
equivalences.add(next_label);
}
}
}

#undef ASSIGN_X
#undef ASSIGN_Y
#undef ASSIGN_Z

return relabel<OUT>(out_labels, voxels, next_label, equivalences);
}