Commit 82ac447b61fa6ff4779cc0d311de445face4b146

Authored by Thiago Franco de Moraes
1 parent 2ae43859
Exists in ffill_segmentation

Using get_lut_value_255 in floodfill

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)