-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.pyx
140 lines (117 loc) · 6.1 KB
/
utils.pyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# distutils: define_macros=CYTHON_TRACE_NOGIL=1
# cython: language_level=3, boundscheck=False, wraparound=False, nonecheck=False, cdivision=True, embedsignature=True
import numpy as np
cimport numpy as np
ctypedef fused label_types:
np.uint8_t
np.uint16_t
np.uint32_t
def calc_bounds(labels, components_num=None):
if components_num is None:
components_num = np.max(labels)
return {
2: calc_bounds2,
3: calc_bounds3,
4: calc_bounds4,
5: calc_bounds5,
}[labels.ndim](labels, components_num)
def calc_bounds5(np.ndarray[label_types, ndim=5] labels, components_num=None):
cdef Py_ssize_t x, y, z, t, s
cdef Py_ssize_t x_max = labels.shape[4]
cdef Py_ssize_t y_max = labels.shape[3]
cdef Py_ssize_t z_max = labels.shape[2]
cdef Py_ssize_t t_max = labels.shape[1]
cdef Py_ssize_t s_max = labels.shape[0]
cdef label_types label_val
if components_num is None:
components_num = np.max(labels)
cdef np.ndarray[np.int16_t, ndim=2] min_bound = np.full((components_num + 1, 5), max(x_max, y_max, z_max, t_max, s_max) + 5, dtype=np.int16)
cdef np.ndarray[np.int16_t, ndim=2] max_bound = np.full((components_num + 1, 5), -1, dtype=np.int16)
for s in range(0, s_max):
for t in range(0, t_max):
for z in range(0, z_max):
for y in range(0,y_max):
for x in range(0,x_max):
label_val = labels[s, t, z, y, x]
if label_val == 0:
continue
min_bound[label_val, 0] = min(min_bound[label_val, 0], s)
min_bound[label_val, 1] = min(min_bound[label_val, 1], t)
min_bound[label_val, 2] = min(min_bound[label_val, 2], z)
min_bound[label_val, 3] = min(min_bound[label_val, 3], y)
min_bound[label_val, 4] = min(min_bound[label_val, 4], x)
max_bound[label_val, 0] = max(max_bound[label_val, 0], s)
max_bound[label_val, 1] = max(max_bound[label_val, 1], t)
max_bound[label_val, 2] = max(max_bound[label_val, 2], z)
max_bound[label_val, 3] = max(max_bound[label_val, 3], y)
max_bound[label_val, 4] = max(max_bound[label_val, 4], x)
return min_bound, max_bound
def calc_bounds4(np.ndarray[label_types, ndim=4] labels, components_num=None):
cdef Py_ssize_t x, y, z, t
cdef Py_ssize_t x_max = labels.shape[3]
cdef Py_ssize_t y_max = labels.shape[2]
cdef Py_ssize_t z_max = labels.shape[1]
cdef Py_ssize_t t_max = labels.shape[0]
cdef label_types label_val
if components_num is None:
components_num = np.max(labels)
cdef np.ndarray[np.int16_t, ndim=2] min_bound = np.full((components_num + 1, 4), max(x_max, y_max, z_max, t_max) + 5, dtype=np.int16)
cdef np.ndarray[np.int16_t, ndim=2] max_bound = np.full((components_num + 1, 4), -1, dtype=np.int16)
for t in range(0, t_max):
for z in range(0, z_max):
for y in range(0,y_max):
for x in range(0,x_max):
label_val = labels[t, z, y, x]
if label_val == 0:
continue
min_bound[label_val, 0] = min(min_bound[label_val, 0], t)
min_bound[label_val, 1] = min(min_bound[label_val, 1], z)
min_bound[label_val, 2] = min(min_bound[label_val, 2], y)
min_bound[label_val, 3] = min(min_bound[label_val, 3], x)
max_bound[label_val, 0] = max(max_bound[label_val, 0], t)
max_bound[label_val, 1] = max(max_bound[label_val, 1], z)
max_bound[label_val, 2] = max(max_bound[label_val, 2], y)
max_bound[label_val, 3] = max(max_bound[label_val, 3], x)
return min_bound, max_bound
def calc_bounds3(np.ndarray[label_types, ndim=3] labels, components_num=None):
cdef Py_ssize_t x, y, z
cdef Py_ssize_t x_max = labels.shape[2]
cdef Py_ssize_t y_max = labels.shape[1]
cdef Py_ssize_t z_max = labels.shape[0]
cdef label_types label_val
if components_num is None:
components_num = np.max(labels)
cdef np.ndarray[np.int16_t, ndim=2] min_bound = np.full((components_num + 1, 3), max(x_max, y_max, z_max) + 5, dtype=np.int16)
cdef np.ndarray[np.int16_t, ndim=2] max_bound = np.full((components_num + 1, 3), -1, dtype=np.int16)
for z in range(0, z_max):
for y in range(0,y_max):
for x in range(0,x_max):
label_val = labels[z, y, x]
if label_val == 0:
continue
min_bound[label_val, 0] = min(min_bound[label_val, 0], z)
min_bound[label_val, 1] = min(min_bound[label_val, 1], y)
min_bound[label_val, 2] = min(min_bound[label_val, 2], x)
max_bound[label_val, 0] = max(max_bound[label_val, 0], z)
max_bound[label_val, 1] = max(max_bound[label_val, 1], y)
max_bound[label_val, 2] = max(max_bound[label_val, 2], x)
return min_bound, max_bound
def calc_bounds2(np.ndarray[label_types, ndim=2] labels, components_num=None):
cdef Py_ssize_t x, y
cdef Py_ssize_t x_max = labels.shape[1]
cdef Py_ssize_t y_max = labels.shape[0]
cdef label_types label_val
if components_num is None:
components_num = np.max(labels)
cdef np.ndarray[np.int16_t, ndim=2] min_bound = np.full((components_num + 1, 2), max(x_max, y_max) + 5, dtype=np.int16)
cdef np.ndarray[np.int16_t, ndim=2] max_bound = np.full((components_num + 1, 2), -1, dtype=np.int16)
for y in range(0,y_max):
for x in range(0,x_max):
label_val = labels[y, x]
if label_val == 0:
continue
min_bound[label_val, 0] = min(min_bound[label_val, 0], y)
min_bound[label_val, 1] = min(min_bound[label_val, 1], x)
max_bound[label_val, 0] = max(max_bound[label_val, 0], y)
max_bound[label_val, 1] = max(max_bound[label_val, 1], x)
return min_bound, max_bound