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 = { | ... | ... |