Commit 75509c1def55c2fdf255c0c1a262d153d3bdb259
1 parent
3e848453
Exists in
ff_mask
Using c++ deque and struct
Showing
1 changed file
with
33 additions
and
38 deletions
Show diff stats
invesalius/data/floodfill.pyx
@@ -6,9 +6,18 @@ from collections import deque | @@ -6,9 +6,18 @@ from collections import deque | ||
6 | 6 | ||
7 | from libc.math cimport floor, ceil | 7 | from libc.math cimport floor, ceil |
8 | from libcpp.deque cimport deque as cdeque | 8 | from libcpp.deque cimport deque as cdeque |
9 | +from libcpp.vector cimport vector | ||
9 | 10 | ||
10 | from cy_my_types cimport image_t, mask_t | 11 | from cy_my_types cimport image_t, mask_t |
11 | 12 | ||
13 | +cdef struct s_coord: | ||
14 | + int x | ||
15 | + int y | ||
16 | + int z | ||
17 | + | ||
18 | +ctypedef s_coord coord | ||
19 | + | ||
20 | + | ||
12 | @cython.boundscheck(False) # turn of bounds-checking for entire function | 21 | @cython.boundscheck(False) # turn of bounds-checking for entire function |
13 | @cython.wraparound(False) | 22 | @cython.wraparound(False) |
14 | @cython.nonecheck(False) | 23 | @cython.nonecheck(False) |
@@ -81,7 +90,7 @@ def floodfill(np.ndarray[image_t, ndim=3] data, int i, int j, int k, int v, int | @@ -81,7 +90,7 @@ def floodfill(np.ndarray[image_t, ndim=3] data, int i, int j, int k, int v, int | ||
81 | @cython.boundscheck(False) # turn of bounds-checking for entire function | 90 | @cython.boundscheck(False) # turn of bounds-checking for entire function |
82 | @cython.wraparound(False) | 91 | @cython.wraparound(False) |
83 | @cython.nonecheck(False) | 92 | @cython.nonecheck(False) |
84 | -def floodfill_threshold(np.ndarray[image_t, ndim=3] data, list seeds, int t0, int t1, int fill, tuple neighbor_iter, np.ndarray[mask_t, ndim=3] out): | 93 | +def floodfill_threshold(np.ndarray[image_t, ndim=3] data, list seeds, int t0, int t1, int fill, vector[vector[int]] neighbor_iter, np.ndarray[mask_t, ndim=3] out): |
85 | 94 | ||
86 | cdef int to_return = 0 | 95 | cdef int to_return = 0 |
87 | if out is None: | 96 | if out is None: |
@@ -92,53 +101,39 @@ def floodfill_threshold(np.ndarray[image_t, ndim=3] data, list seeds, int t0, in | @@ -92,53 +101,39 @@ def floodfill_threshold(np.ndarray[image_t, ndim=3] data, list seeds, int t0, in | ||
92 | cdef int xd, yd, zd | 101 | cdef int xd, yd, zd |
93 | cdef int w, h, d | 102 | cdef int w, h, d |
94 | cdef int xo, yo, zo | 103 | cdef int xo, yo, zo |
104 | + cdef int i | ||
95 | 105 | ||
96 | d = data.shape[0] | 106 | d = data.shape[0] |
97 | h = data.shape[1] | 107 | h = data.shape[1] |
98 | w = data.shape[2] | 108 | w = data.shape[2] |
99 | 109 | ||
100 | - stack = deque() | 110 | + cdef cdeque[coord] stack |
111 | + cdef coord c | ||
101 | 112 | ||
102 | for i, j, k in seeds: | 113 | for i, j, k in seeds: |
103 | if data[k, j, i] >= t0 and data[k, j, i] <= t1: | 114 | if data[k, j, i] >= t0 and data[k, j, i] <= t1: |
104 | - stack.append((i, j, k)) | 115 | + c.x = i |
116 | + c.y = j | ||
117 | + c.z = k | ||
118 | + stack.push_back(c) | ||
105 | out[k, j, i] = fill | 119 | out[k, j, i] = fill |
106 | 120 | ||
107 | - while stack: | ||
108 | - x, y, z = stack.pop() | ||
109 | - | ||
110 | - | ||
111 | - for xd, yd, zd in neighbor_iter: | ||
112 | - xo = x + xd | ||
113 | - yo = y + yd | ||
114 | - zo = z + zd | ||
115 | - if 0 <= (x + xd) < w and 0 <= (y + yd) < h and 0 <= (z + zd) < d and out[zo, yo, xo] != fill and t0 <= data[zo, yo, xo] <= t1: | ||
116 | - out[zo, yo, xo] = fill | ||
117 | - stack.append((xo, yo, zo)) | ||
118 | - | ||
119 | - # if z + 1 < d and data[z + 1, y, x] >= t0 and data[z + 1, y, x] <= t1 and out[zo + 1, yo, xo] != fill: | ||
120 | - # out[zo + 1, yo, xo] = fill | ||
121 | - # stack.append((x, y, z + 1)) | ||
122 | - | ||
123 | - # if z - 1 >= 0 and data[z - 1, y, x] >= t0 and data[z - 1, y, x] <= t1 and out[zo - 1, yo, xo] != fill: | ||
124 | - # out[zo - 1, yo, xo] = fill | ||
125 | - # stack.append((x, y, z - 1)) | ||
126 | - | ||
127 | - # if y + 1 < h and data[z, y + 1, x] >= t0 and data[z, y + 1, x] <= t1 and out[zo, yo + 1, xo] != fill: | ||
128 | - # out[zo, yo + 1, xo] = fill | ||
129 | - # stack.append((x, y + 1, z)) | ||
130 | - | ||
131 | - # if y - 1 >= 0 and data[z, y - 1, x] >= t0 and data[z, y - 1, x] <= t1 and out[zo, yo - 1, xo] != fill: | ||
132 | - # out[zo, yo - 1, xo] = fill | ||
133 | - # stack.append((x, y - 1, z)) | ||
134 | - | ||
135 | - # if x + 1 < w and data[z, y, x + 1] >= t0 and data[z, y, x + 1] <= t1 and out[zo, yo, xo + 1] != fill: | ||
136 | - # out[zo, yo, xo + 1] = fill | ||
137 | - # stack.append((x + 1, y, z)) | ||
138 | - | ||
139 | - # if x - 1 >= 0 and data[z, y, x - 1] >= t0 and data[z, y, x - 1] <= t1 and out[zo, yo, xo - 1] != fill: | ||
140 | - # out[zo, yo, xo - 1] = fill | ||
141 | - # stack.append((x - 1, y, z)) | 121 | + with nogil: |
122 | + while stack.size(): | ||
123 | + c = stack.front() | ||
124 | + stack.pop_front() | ||
125 | + | ||
126 | + for i in xrange(neighbor_iter.size()): | ||
127 | + xo = c.x + neighbor_iter[i][0] | ||
128 | + yo = c.y + neighbor_iter[i][1] | ||
129 | + zo = c.z + neighbor_iter[i][2] | ||
130 | + | ||
131 | + if 0 <= xo < w and 0 <= yo < h and 0 <= zo < d and out[zo, yo, xo] != fill and t0 <= data[zo, yo, xo] <= t1: | ||
132 | + out[zo, yo, xo] = fill | ||
133 | + c.x = xo | ||
134 | + c.y = yo | ||
135 | + c.z = zo | ||
136 | + stack.push_back(c) | ||
142 | 137 | ||
143 | if to_return: | 138 | if to_return: |
144 | return out | 139 | return out |