Commit 3e8484532f5a3e62106871eb97be11e6d970950e
1 parent
ba729de6
Exists in
ff_mask
Using an iter to traverse the voxel neighbourhood
Showing
2 changed files
with
56 additions
and
25 deletions
Show diff stats
invesalius/data/floodfill.pyx
... | ... | @@ -81,7 +81,7 @@ def floodfill(np.ndarray[image_t, ndim=3] data, int i, int j, int k, int v, int |
81 | 81 | @cython.boundscheck(False) # turn of bounds-checking for entire function |
82 | 82 | @cython.wraparound(False) |
83 | 83 | @cython.nonecheck(False) |
84 | -def floodfill_threshold(np.ndarray[image_t, ndim=3] data, list seeds, int t0, int t1, int fill, np.ndarray[mask_t, ndim=3] out): | |
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): | |
85 | 85 | |
86 | 86 | cdef int to_return = 0 |
87 | 87 | if out is None: |
... | ... | @@ -89,6 +89,7 @@ def floodfill_threshold(np.ndarray[image_t, ndim=3] data, list seeds, int t0, in |
89 | 89 | to_return = 1 |
90 | 90 | |
91 | 91 | cdef int x, y, z |
92 | + cdef int xd, yd, zd | |
92 | 93 | cdef int w, h, d |
93 | 94 | cdef int xo, yo, zo |
94 | 95 | |
... | ... | @@ -106,33 +107,38 @@ def floodfill_threshold(np.ndarray[image_t, ndim=3] data, list seeds, int t0, in |
106 | 107 | while stack: |
107 | 108 | x, y, z = stack.pop() |
108 | 109 | |
109 | - xo = x | |
110 | - yo = y | |
111 | - zo = z | |
112 | 110 | |
113 | - 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: | |
114 | - out[zo + 1, yo, xo] = fill | |
115 | - stack.append((x, y, z + 1)) | |
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)) | |
116 | 118 | |
117 | - 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: | |
118 | - out[zo - 1, yo, xo] = fill | |
119 | - stack.append((x, y, z - 1)) | |
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)) | |
120 | 122 | |
121 | - 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: | |
122 | - out[zo, yo + 1, xo] = fill | |
123 | - stack.append((x, y + 1, z)) | |
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)) | |
124 | 126 | |
125 | - 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: | |
126 | - out[zo, yo - 1, xo] = fill | |
127 | - stack.append((x, y - 1, z)) | |
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)) | |
128 | 130 | |
129 | - 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: | |
130 | - out[zo, yo, xo + 1] = fill | |
131 | - stack.append((x + 1, y, z)) | |
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)) | |
132 | 134 | |
133 | - 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: | |
134 | - out[zo, yo, xo - 1] = fill | |
135 | - stack.append((x - 1, y, z)) | |
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)) | |
136 | 142 | |
137 | 143 | if to_return: |
138 | 144 | return out | ... | ... |
invesalius/data/styles.py
... | ... | @@ -1769,7 +1769,6 @@ class FlooFillMaskInteractorStyle(DefaultInteractorStyle): |
1769 | 1769 | if (self.viewer.slice_.buffer_slices[self.orientation].mask is None): |
1770 | 1770 | return |
1771 | 1771 | |
1772 | - | |
1773 | 1772 | viewer = self.viewer |
1774 | 1773 | iren = viewer.interactor |
1775 | 1774 | |
... | ... | @@ -1793,9 +1792,35 @@ class FlooFillMaskInteractorStyle(DefaultInteractorStyle): |
1793 | 1792 | |
1794 | 1793 | cp_mask = mask.copy() |
1795 | 1794 | |
1796 | - floodfill.floodfill_threshold(cp_mask, [[x, y, z]], 0, 1, 254, mask) | |
1795 | + from_3d = True | |
1796 | + if from_3d: | |
1797 | + neighbor_iter = ((-1, 0, 0), | |
1798 | + (1, 0, 0), | |
1799 | + (0, -1, 0), | |
1800 | + (0, 1, 0), | |
1801 | + (0, 0, -1), | |
1802 | + (0, 0, 1)) | |
1803 | + else: | |
1804 | + neighbor_iter = ((-1, 0, 0), | |
1805 | + (1, 0, 0), | |
1806 | + (0, -1, 0), | |
1807 | + (0, 1, 0)) | |
1797 | 1808 | |
1798 | - viewer.OnScrollBar() | |
1809 | + if iren.GetControlKey(): | |
1810 | + floodfill.floodfill_threshold(cp_mask, [[x, y, z]], 254, 255, 1, neighbor_iter, mask) | |
1811 | + else: | |
1812 | + floodfill.floodfill_threshold(cp_mask, [[x, y, z]], 0, 1, 254, neighbor_iter, mask) | |
1813 | + | |
1814 | + self.viewer.slice_.buffer_slices['AXIAL'].discard_mask() | |
1815 | + self.viewer.slice_.buffer_slices['CORONAL'].discard_mask() | |
1816 | + self.viewer.slice_.buffer_slices['SAGITAL'].discard_mask() | |
1817 | + | |
1818 | + self.viewer.slice_.buffer_slices['AXIAL'].discard_vtk_mask() | |
1819 | + self.viewer.slice_.buffer_slices['CORONAL'].discard_vtk_mask() | |
1820 | + self.viewer.slice_.buffer_slices['SAGITAL'].discard_vtk_mask() | |
1821 | + | |
1822 | + self.viewer.slice_.current_mask.was_edited = True | |
1823 | + Publisher.sendMessage('Reload actual slice') | |
1799 | 1824 | |
1800 | 1825 | def get_coordinate_cursor(self): |
1801 | 1826 | # Find position | ... | ... |