Commit 0052304757e61234439ed9e6bc740135621aad46
1 parent
bd862845
Exists in
ffill_segmentation
Split 2D and 3D segmentation
Showing
1 changed file
with
75 additions
and
44 deletions
Show diff stats
invesalius/data/styles.py
| ... | ... | @@ -1897,6 +1897,23 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): |
| 1897 | 1897 | if (self.viewer.slice_.buffer_slices[self.orientation].mask is None): |
| 1898 | 1898 | return |
| 1899 | 1899 | |
| 1900 | + if self.config.target == "3D": | |
| 1901 | + self.do_3d_seg() | |
| 1902 | + else: | |
| 1903 | + self.do_2d_seg() | |
| 1904 | + | |
| 1905 | + self.viewer.slice_.buffer_slices['AXIAL'].discard_mask() | |
| 1906 | + self.viewer.slice_.buffer_slices['CORONAL'].discard_mask() | |
| 1907 | + self.viewer.slice_.buffer_slices['SAGITAL'].discard_mask() | |
| 1908 | + | |
| 1909 | + self.viewer.slice_.buffer_slices['AXIAL'].discard_vtk_mask() | |
| 1910 | + self.viewer.slice_.buffer_slices['CORONAL'].discard_vtk_mask() | |
| 1911 | + self.viewer.slice_.buffer_slices['SAGITAL'].discard_vtk_mask() | |
| 1912 | + | |
| 1913 | + self.viewer.slice_.current_mask.was_edited = True | |
| 1914 | + Publisher.sendMessage('Reload actual slice') | |
| 1915 | + | |
| 1916 | + def do_2d_seg(self): | |
| 1900 | 1917 | viewer = self.viewer |
| 1901 | 1918 | iren = viewer.interactor |
| 1902 | 1919 | mouse_x, mouse_y = iren.GetEventPosition() |
| ... | ... | @@ -1905,7 +1922,6 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): |
| 1905 | 1922 | mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:] |
| 1906 | 1923 | image = self.viewer.slice_.matrix |
| 1907 | 1924 | |
| 1908 | - | |
| 1909 | 1925 | if self.config.method == 'threshold': |
| 1910 | 1926 | v = image[z, y, x] |
| 1911 | 1927 | t0 = self.config.t0 |
| ... | ... | @@ -1926,59 +1942,74 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): |
| 1926 | 1942 | if image[z, y, x] < t0 or image[z, y, x] > t1: |
| 1927 | 1943 | return |
| 1928 | 1944 | |
| 1929 | - if self.config.target == "3D": | |
| 1930 | - bstruct = np.array(generate_binary_structure(3, CON3D[self.config.con_3d]), dtype='uint8') | |
| 1931 | - self.viewer.slice_.do_threshold_to_all_slices() | |
| 1932 | - cp_mask = self.viewer.slice_.current_mask.matrix.copy() | |
| 1933 | - else: | |
| 1934 | - _bstruct = generate_binary_structure(2, CON2D[self.config.con_2d]) | |
| 1935 | - if self.orientation == 'AXIAL': | |
| 1936 | - bstruct = np.zeros((1, 3, 3), dtype='uint8') | |
| 1937 | - bstruct[0] = _bstruct | |
| 1938 | - elif self.orientation == 'CORONAL': | |
| 1939 | - bstruct = np.zeros((3, 1, 3), dtype='uint8') | |
| 1940 | - bstruct[:, 0, :] = _bstruct | |
| 1941 | - elif self.orientation == 'SAGITAL': | |
| 1942 | - bstruct = np.zeros((3, 3, 1), dtype='uint8') | |
| 1943 | - bstruct[:, :, 0] = _bstruct | |
| 1945 | + _bstruct = generate_binary_structure(2, CON2D[self.config.con_2d]) | |
| 1946 | + if self.orientation == 'AXIAL': | |
| 1947 | + bstruct = np.zeros((1, 3, 3), dtype='uint8') | |
| 1948 | + bstruct[0] = _bstruct | |
| 1949 | + elif self.orientation == 'CORONAL': | |
| 1950 | + bstruct = np.zeros((3, 1, 3), dtype='uint8') | |
| 1951 | + bstruct[:, 0, :] = _bstruct | |
| 1952 | + elif self.orientation == 'SAGITAL': | |
| 1953 | + bstruct = np.zeros((3, 3, 1), dtype='uint8') | |
| 1954 | + bstruct[:, :, 0] = _bstruct | |
| 1944 | 1955 | |
| 1945 | - if self.config.target == '2D': | |
| 1946 | - floodfill.floodfill_threshold(image, [[x, y, z]], t0, t1, self.config.fill_value, bstruct, mask) | |
| 1947 | - b_mask = self.viewer.slice_.buffer_slices[self.orientation].mask | |
| 1948 | - index = self.viewer.slice_.buffer_slices[self.orientation].index | |
| 1956 | + floodfill.floodfill_threshold(image, [[x, y, z]], t0, t1, self.config.fill_value, bstruct, mask) | |
| 1957 | + b_mask = self.viewer.slice_.buffer_slices[self.orientation].mask | |
| 1958 | + index = self.viewer.slice_.buffer_slices[self.orientation].index | |
| 1949 | 1959 | |
| 1950 | - if self.orientation == 'AXIAL': | |
| 1951 | - p_mask = mask[index,:,:].copy() | |
| 1952 | - elif self.orientation == 'CORONAL': | |
| 1953 | - p_mask = mask[:, index, :].copy() | |
| 1954 | - elif self.orientation == 'SAGITAL': | |
| 1955 | - p_mask = mask[:, :, index].copy() | |
| 1960 | + if self.orientation == 'AXIAL': | |
| 1961 | + p_mask = mask[index,:,:].copy() | |
| 1962 | + elif self.orientation == 'CORONAL': | |
| 1963 | + p_mask = mask[:, index, :].copy() | |
| 1964 | + elif self.orientation == 'SAGITAL': | |
| 1965 | + p_mask = mask[:, :, index].copy() | |
| 1956 | 1966 | |
| 1957 | - self.viewer.slice_.current_mask.save_history(index, self.orientation, p_mask, b_mask) | |
| 1958 | - else: | |
| 1959 | - with futures.ThreadPoolExecutor(max_workers=1) as executor: | |
| 1960 | - future = executor.submit(floodfill.floodfill_threshold, image, [[x, y, z]], t0, t1, self.config.fill_value, bstruct, mask) | |
| 1967 | + self.viewer.slice_.current_mask.save_history(index, self.orientation, p_mask, b_mask) | |
| 1961 | 1968 | |
| 1962 | - dlg = wx.ProgressDialog(self._progr_title, self._progr_msg, parent=None, style=wx.PD_APP_MODAL) | |
| 1963 | - while not future.done(): | |
| 1964 | - dlg.Pulse() | |
| 1965 | - time.sleep(0.1) | |
| 1969 | + def do_3d_seg(self): | |
| 1970 | + viewer = self.viewer | |
| 1971 | + iren = viewer.interactor | |
| 1972 | + mouse_x, mouse_y = iren.GetEventPosition() | |
| 1973 | + x, y, z = self.viewer.get_voxel_coord_by_screen_pos(mouse_x, mouse_y, self.picker) | |
| 1966 | 1974 | |
| 1967 | - dlg.Destroy() | |
| 1975 | + mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:] | |
| 1976 | + image = self.viewer.slice_.matrix | |
| 1968 | 1977 | |
| 1969 | - self.viewer.slice_.current_mask.save_history(0, 'VOLUME', self.viewer.slice_.current_mask.matrix.copy(), cp_mask) | |
| 1978 | + if self.config.method == 'threshold': | |
| 1979 | + v = image[z, y, x] | |
| 1980 | + t0 = self.config.t0 | |
| 1981 | + t1 = self.config.t1 | |
| 1970 | 1982 | |
| 1971 | - self.viewer.slice_.buffer_slices['AXIAL'].discard_mask() | |
| 1972 | - self.viewer.slice_.buffer_slices['CORONAL'].discard_mask() | |
| 1973 | - self.viewer.slice_.buffer_slices['SAGITAL'].discard_mask() | |
| 1983 | + elif self.config.method == 'dynamic': | |
| 1984 | + if self.config.use_ww_wl: | |
| 1985 | + print "Using WW&WL" | |
| 1986 | + ww = self.viewer.slice_.window_width | |
| 1987 | + wl = self.viewer.slice_.window_level | |
| 1988 | + image = get_LUT_value(image, ww, wl) | |
| 1974 | 1989 | |
| 1975 | - self.viewer.slice_.buffer_slices['AXIAL'].discard_vtk_mask() | |
| 1976 | - self.viewer.slice_.buffer_slices['CORONAL'].discard_vtk_mask() | |
| 1977 | - self.viewer.slice_.buffer_slices['SAGITAL'].discard_vtk_mask() | |
| 1990 | + v = image[z, y, x] | |
| 1978 | 1991 | |
| 1979 | - self.viewer.slice_.current_mask.was_edited = True | |
| 1980 | - Publisher.sendMessage('Reload actual slice') | |
| 1992 | + t0 = v - self.config.dev_min | |
| 1993 | + t1 = v + self.config.dev_max | |
| 1994 | + | |
| 1995 | + if image[z, y, x] < t0 or image[z, y, x] > t1: | |
| 1996 | + return | |
| 1997 | + | |
| 1998 | + bstruct = np.array(generate_binary_structure(3, CON3D[self.config.con_3d]), dtype='uint8') | |
| 1999 | + self.viewer.slice_.do_threshold_to_all_slices() | |
| 2000 | + cp_mask = self.viewer.slice_.current_mask.matrix.copy() | |
| 2001 | + | |
| 2002 | + with futures.ThreadPoolExecutor(max_workers=1) as executor: | |
| 2003 | + future = executor.submit(floodfill.floodfill_threshold, image, [[x, y, z]], t0, t1, self.config.fill_value, bstruct, mask) | |
| 2004 | + | |
| 2005 | + dlg = wx.ProgressDialog(self._progr_title, self._progr_msg, parent=None, style=wx.PD_APP_MODAL) | |
| 2006 | + while not future.done(): | |
| 2007 | + dlg.Pulse() | |
| 2008 | + time.sleep(0.1) | |
| 2009 | + | |
| 2010 | + dlg.Destroy() | |
| 1981 | 2011 | |
| 2012 | + self.viewer.slice_.current_mask.save_history(0, 'VOLUME', self.viewer.slice_.current_mask.matrix.copy(), cp_mask) | |
| 1982 | 2013 | |
| 1983 | 2014 | def get_style(style): |
| 1984 | 2015 | STYLES = { | ... | ... |