Commit 82ac447b61fa6ff4779cc0d311de445face4b146
1 parent
2ae43859
Exists in
ffill_segmentation
Using get_lut_value_255 in floodfill
Showing
2 changed files
with
36 additions
and
7 deletions
Show diff stats
invesalius/data/styles.py
@@ -76,6 +76,16 @@ def get_LUT_value(data, window, level): | @@ -76,6 +76,16 @@ def get_LUT_value(data, window, level): | ||
76 | data.shape = shape | 76 | data.shape = shape |
77 | return data | 77 | return data |
78 | 78 | ||
79 | +def get_LUT_value_255(data, window, level): | ||
80 | + shape = data.shape | ||
81 | + data_ = data.ravel() | ||
82 | + data = np.piecewise(data_, | ||
83 | + [data_ <= (level - 0.5 - (window-1)/2), | ||
84 | + data_ > (level - 0.5 + (window-1)/2)], | ||
85 | + [0, 255, lambda data_: ((data_ - (level - 0.5))/(window-1) + 0.5)*(255)]) | ||
86 | + data.shape = shape | ||
87 | + return data | ||
88 | + | ||
79 | 89 | ||
80 | class BaseImageInteractorStyle(vtk.vtkInteractorStyleImage): | 90 | class BaseImageInteractorStyle(vtk.vtkInteractorStyleImage): |
81 | def __init__(self, viewer): | 91 | def __init__(self, viewer): |
@@ -1849,8 +1859,8 @@ class FFillSegmentationConfig(object): | @@ -1849,8 +1859,8 @@ class FFillSegmentationConfig(object): | ||
1849 | self.con_2d = 4 | 1859 | self.con_2d = 4 |
1850 | self.con_3d = 6 | 1860 | self.con_3d = 6 |
1851 | 1861 | ||
1852 | - self.t0 = 0 | ||
1853 | - self.t1 = 100 | 1862 | + self.t0 = None |
1863 | + self.t1 = None | ||
1854 | 1864 | ||
1855 | self.fill_value = 254 | 1865 | self.fill_value = 254 |
1856 | 1866 | ||
@@ -1876,13 +1886,21 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): | @@ -1876,13 +1886,21 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): | ||
1876 | self.config = FFillSegmentationConfig() | 1886 | self.config = FFillSegmentationConfig() |
1877 | self.dlg_ffill = None | 1887 | self.dlg_ffill = None |
1878 | 1888 | ||
1879 | - self._progr_title = _(u"Fill hole") | ||
1880 | - self._progr_msg = _(u"Filling hole ...") | 1889 | + self._progr_title = _(u"Floodfill segmentation") |
1890 | + self._progr_msg = _(u"Segmenting ...") | ||
1881 | 1891 | ||
1882 | self.AddObserver("LeftButtonPressEvent", self.OnFFClick) | 1892 | self.AddObserver("LeftButtonPressEvent", self.OnFFClick) |
1883 | 1893 | ||
1884 | def SetUp(self): | 1894 | def SetUp(self): |
1885 | if not self.config.dlg_visible: | 1895 | if not self.config.dlg_visible: |
1896 | + | ||
1897 | + if self.config.t0 is None: | ||
1898 | + image = self.viewer.slice_.matrix | ||
1899 | + _min, _max = image.min(), image.max() | ||
1900 | + | ||
1901 | + self.config.t0 = int(_min + (3.0/4.0) * (_max - _min)) | ||
1902 | + self.config.t1 = int(_max) | ||
1903 | + | ||
1886 | self.config.dlg_visible = True | 1904 | self.config.dlg_visible = True |
1887 | self.dlg_ffill = dialogs.FFillSegmentationOptionsDialog(self.config) | 1905 | self.dlg_ffill = dialogs.FFillSegmentationOptionsDialog(self.config) |
1888 | self.dlg_ffill.Show() | 1906 | self.dlg_ffill.Show() |
@@ -1898,6 +1916,7 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): | @@ -1898,6 +1916,7 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): | ||
1898 | return | 1916 | return |
1899 | 1917 | ||
1900 | if self.config.target == "3D": | 1918 | if self.config.target == "3D": |
1919 | + self.do_3d_seg() | ||
1901 | with futures.ThreadPoolExecutor(max_workers=1) as executor: | 1920 | with futures.ThreadPoolExecutor(max_workers=1) as executor: |
1902 | future = executor.submit(self.do_3d_seg) | 1921 | future = executor.submit(self.do_3d_seg) |
1903 | 1922 | ||
@@ -1941,7 +1960,7 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): | @@ -1941,7 +1960,7 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): | ||
1941 | print "Using WW&WL" | 1960 | print "Using WW&WL" |
1942 | ww = self.viewer.slice_.window_width | 1961 | ww = self.viewer.slice_.window_width |
1943 | wl = self.viewer.slice_.window_level | 1962 | wl = self.viewer.slice_.window_level |
1944 | - image = get_LUT_value(image, ww, wl) | 1963 | + image = get_LUT_value_255(image, ww, wl) |
1945 | 1964 | ||
1946 | v = image[y, x] | 1965 | v = image[y, x] |
1947 | 1966 | ||
@@ -1996,7 +2015,7 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): | @@ -1996,7 +2015,7 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): | ||
1996 | print "Using WW&WL" | 2015 | print "Using WW&WL" |
1997 | ww = self.viewer.slice_.window_width | 2016 | ww = self.viewer.slice_.window_width |
1998 | wl = self.viewer.slice_.window_level | 2017 | wl = self.viewer.slice_.window_level |
1999 | - image = get_LUT_value(image, ww, wl) | 2018 | + image = get_LUT_value_255(image, ww, wl) |
2000 | 2019 | ||
2001 | v = image[z, y, x] | 2020 | v = image[z, y, x] |
2002 | 2021 | ||
@@ -2012,7 +2031,16 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): | @@ -2012,7 +2031,16 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): | ||
2012 | self.viewer.slice_.do_threshold_to_all_slices() | 2031 | self.viewer.slice_.do_threshold_to_all_slices() |
2013 | cp_mask = self.viewer.slice_.current_mask.matrix.copy() | 2032 | cp_mask = self.viewer.slice_.current_mask.matrix.copy() |
2014 | 2033 | ||
2015 | - floodfill.floodfill_threshold(image, [[x, y, z]], t0, t1, 1, bstruct, out_mask) | 2034 | + with futures.ThreadPoolExecutor(max_workers=1) as executor: |
2035 | + future = executor.submit(floodfill.floodfill_threshold, image, [[x, y, z]], t0, t1, 1, bstruct, out_mask) | ||
2036 | + | ||
2037 | + dlg = wx.ProgressDialog(self._progr_title, self._progr_msg, parent=None, style=wx.PD_APP_MODAL) | ||
2038 | + while not future.done(): | ||
2039 | + dlg.Pulse() | ||
2040 | + time.sleep(0.1) | ||
2041 | + | ||
2042 | + dlg.Destroy() | ||
2043 | + | ||
2016 | mask[out_mask.astype('bool')] = self.config.fill_value | 2044 | mask[out_mask.astype('bool')] = self.config.fill_value |
2017 | 2045 | ||
2018 | self.viewer.slice_.current_mask.save_history(0, 'VOLUME', self.viewer.slice_.current_mask.matrix.copy(), cp_mask) | 2046 | self.viewer.slice_.current_mask.save_history(0, 'VOLUME', self.viewer.slice_.current_mask.matrix.copy(), cp_mask) |
invesalius/gui/dialogs.py
@@ -2155,6 +2155,7 @@ class FFillSegmentationOptionsDialog(wx.Dialog): | @@ -2155,6 +2155,7 @@ class FFillSegmentationOptionsDialog(wx.Dialog): | ||
2155 | 2155 | ||
2156 | self.Bind(wx.EVT_RADIOBUTTON, self.OnSetRadio) | 2156 | self.Bind(wx.EVT_RADIOBUTTON, self.OnSetRadio) |
2157 | self.Bind(grad.EVT_THRESHOLD_CHANGING, self.OnSlideChanged, self.threshold) | 2157 | self.Bind(grad.EVT_THRESHOLD_CHANGING, self.OnSlideChanged, self.threshold) |
2158 | + self.Bind(grad.EVT_THRESHOLD_CHANGED, self.OnSlideChanged, self.threshold) | ||
2158 | self.use_ww_wl.Bind(wx.EVT_CHECKBOX, self.OnSetUseWWWL) | 2159 | self.use_ww_wl.Bind(wx.EVT_CHECKBOX, self.OnSetUseWWWL) |
2159 | self.deviation_min.Bind(wx.EVT_SPINCTRL, self.OnSetDeviation) | 2160 | self.deviation_min.Bind(wx.EVT_SPINCTRL, self.OnSetDeviation) |
2160 | self.deviation_max.Bind(wx.EVT_SPINCTRL, self.OnSetDeviation) | 2161 | self.deviation_max.Bind(wx.EVT_SPINCTRL, self.OnSetDeviation) |