Commit 1237f50167fc5039c36ba2f54804835c68f1771c

Authored by Thiago Franco de Moraes
1 parent ca4ae9a3

Added a gui to confidence

invesalius/data/styles.py
@@ -1983,6 +1983,9 @@ class FFillSegmentationConfig(object): @@ -1983,6 +1983,9 @@ class FFillSegmentationConfig(object):
1983 1983
1984 self.use_ww_wl = True 1984 self.use_ww_wl = True
1985 1985
  1986 + self.confid_mult = 2.5
  1987 + self.confid_iters = 3
  1988 +
1986 1989
1987 class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): 1990 class FloodFillSegmentInteractorStyle(DefaultInteractorStyle):
1988 def __init__(self, viewer): 1991 def __init__(self, viewer):
@@ -2145,7 +2148,15 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): @@ -2145,7 +2148,15 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle):
2145 cp_mask = self.viewer.slice_.current_mask.matrix.copy() 2148 cp_mask = self.viewer.slice_.current_mask.matrix.copy()
2146 2149
2147 if self.config.method == 'confidence': 2150 if self.config.method == 'confidence':
2148 - out_mask = self.do_rg_confidence(image, mask, (x, y, z), bstruct) 2151 + with futures.ThreadPoolExecutor(max_workers=1) as executor:
  2152 + future = executor.submit(self.do_rg_confidence, image, mask, (x, y, z), bstruct)
  2153 +
  2154 + dlg = wx.ProgressDialog(self._progr_title, self._progr_msg, parent=None, style=wx.PD_APP_MODAL)
  2155 + while not future.done():
  2156 + dlg.Pulse()
  2157 + time.sleep(0.1)
  2158 + dlg.Destroy()
  2159 + out_mask = future.result()
2149 else: 2160 else:
2150 out_mask = np.zeros_like(mask) 2161 out_mask = np.zeros_like(mask)
2151 with futures.ThreadPoolExecutor(max_workers=1) as executor: 2162 with futures.ThreadPoolExecutor(max_workers=1) as executor:
@@ -2171,27 +2182,28 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): @@ -2171,27 +2182,28 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle):
2171 image = get_LUT_value_255(image, ww, wl) 2182 image = get_LUT_value_255(image, ww, wl)
2172 bool_mask = np.zeros_like(mask, dtype='bool') 2183 bool_mask = np.zeros_like(mask, dtype='bool')
2173 out_mask = np.zeros_like(mask) 2184 out_mask = np.zeros_like(mask)
2174 - for i in xrange(int(x-1), int(x+2)):  
2175 - if i < 0 or i >= bool_mask.shape[2]: 2185 +
  2186 + for k in xrange(int(z-1), int(z+2)):
  2187 + if k < 0 or k >= bool_mask.shape[0]:
2176 continue 2188 continue
2177 for j in xrange(int(y-1), int(y+2)): 2189 for j in xrange(int(y-1), int(y+2)):
2178 if j < 0 or j >= bool_mask.shape[1]: 2190 if j < 0 or j >= bool_mask.shape[1]:
2179 continue 2191 continue
2180 - for k in xrange(int(z-1), int(z+2)):  
2181 - if k < 0 or k >= bool_mask.shape[0]: 2192 + for i in xrange(int(x-1), int(x+2)):
  2193 + if i < 0 or i >= bool_mask.shape[2]:
2182 continue 2194 continue
2183 bool_mask[k, j, i] = True 2195 bool_mask[k, j, i] = True
2184 2196
2185 -  
2186 - for i in xrange(3): 2197 + for i in xrange(self.config.confid_iters):
2187 var = np.std(image[bool_mask]) 2198 var = np.std(image[bool_mask])
2188 mean = np.mean(image[bool_mask]) 2199 mean = np.mean(image[bool_mask])
2189 2200
2190 - t0 = mean - var * 2.5  
2191 - t1 = mean + var * 2.5  
2192 - print var, mean, t0, t1 2201 + t0 = mean - var * self.config.confid_mult
  2202 + t1 = mean + var * self.config.confid_mult
2193 2203
2194 - floodfill.floodfill_threshold(image, [[x, y, 0]], t0, t1, 1, bstruct, out_mask) 2204 + print self.config.confid_iters, self.config.confid_mult
  2205 +
  2206 + floodfill.floodfill_threshold(image, [[x, y, z]], t0, t1, 1, bstruct, out_mask)
2195 2207
2196 bool_mask[out_mask == 1] = True 2208 bool_mask[out_mask == 1] = True
2197 2209
invesalius/gui/dialogs.py
@@ -2031,6 +2031,64 @@ class PanelFFillDynamic(wx.Panel): @@ -2031,6 +2031,64 @@ class PanelFFillDynamic(wx.Panel):
2031 self.config.dev_min = self.deviation_min.GetValue() 2031 self.config.dev_min = self.deviation_min.GetValue()
2032 2032
2033 2033
  2034 +class PanelFFillConfidence(wx.Panel):
  2035 + def __init__(self, parent, config, ID=-1, style=wx.TAB_TRAVERSAL|wx.NO_BORDER):
  2036 + wx.Panel.__init__(self, parent, ID, style=style)
  2037 +
  2038 + self.config = config
  2039 +
  2040 + self._init_gui()
  2041 +
  2042 + def _init_gui(self):
  2043 + self.use_ww_wl = wx.CheckBox(self, -1, _(u"Use WW&WL"))
  2044 + self.use_ww_wl.SetValue(self.config.use_ww_wl)
  2045 +
  2046 + self.spin_mult = floatspin.FloatSpin(self, -1,
  2047 + value=self.config.confid_mult,
  2048 + min_val=1.0, max_val=10.0,
  2049 + increment=0.1, digits=1,
  2050 + style=wx.TE_PROCESS_TAB|wx.TE_PROCESS_ENTER,
  2051 + agwStyle=floatspin.FS_RIGHT)
  2052 + w, h = self.spin_mult.GetTextExtent('M')
  2053 + self.spin_mult.SetMinSize((w*7, -1))
  2054 +
  2055 + self.spin_iters = wx.SpinCtrl(self, -1, value='%d' % self.config.confid_iters, min=0, max=100)
  2056 + self.spin_iters.SetMinSize((w*7, -1))
  2057 +
  2058 + sizer = wx.GridBagSizer(5, 5)
  2059 +
  2060 + sizer.AddStretchSpacer((0, 0))
  2061 +
  2062 + sizer.Add(self.use_ww_wl, (1, 0), (1, 6), flag=wx.LEFT, border=5)
  2063 +
  2064 + sizer.AddStretchSpacer((2, 0))
  2065 +
  2066 + sizer.Add(wx.StaticText(self, -1, _(u"Multiplier")), (3, 0), (1, 3), flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border=5)
  2067 + sizer.Add(self.spin_mult, (3, 3), (1, 2))
  2068 +
  2069 + sizer.Add(wx.StaticText(self, -1, _(u"Iterations")), (4, 0), (1, 3), flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border=5)
  2070 + sizer.Add(self.spin_iters, (4, 3), (1, 2))
  2071 +
  2072 + sizer.AddStretchSpacer((5, 0))
  2073 +
  2074 + self.SetSizer(sizer)
  2075 + sizer.Fit(self)
  2076 + self.Layout()
  2077 +
  2078 + self.use_ww_wl.Bind(wx.EVT_CHECKBOX, self.OnSetUseWWWL)
  2079 + self.spin_mult.Bind(wx.EVT_SPINCTRL, self.OnSetMult)
  2080 + self.spin_iters.Bind(wx.EVT_SPINCTRL, self.OnSetIters)
  2081 +
  2082 + def OnSetUseWWWL(self, evt):
  2083 + self.config.use_ww_wl = self.use_ww_wl.GetValue()
  2084 +
  2085 + def OnSetMult(self, evt):
  2086 + self.config.confid_mult = self.spin_mult.GetValue()
  2087 +
  2088 + def OnSetIters(self, evt):
  2089 + self.config.confid_iters = self.spin_iters.GetValue()
  2090 +
  2091 +
2034 class FFillOptionsDialog(wx.Dialog): 2092 class FFillOptionsDialog(wx.Dialog):
2035 def __init__(self, title, config): 2093 def __init__(self, title, config):
2036 pre = wx.PreDialog() 2094 pre = wx.PreDialog()
@@ -2290,6 +2348,10 @@ class FFillSegmentationOptionsDialog(wx.Dialog): @@ -2290,6 +2348,10 @@ class FFillSegmentationOptionsDialog(wx.Dialog):
2290 self.panel_ffill_dynamic.SetMinSize((250, -1)) 2348 self.panel_ffill_dynamic.SetMinSize((250, -1))
2291 self.panel_ffill_dynamic.Hide() 2349 self.panel_ffill_dynamic.Hide()
2292 2350
  2351 + self.panel_ffill_confidence = PanelFFillConfidence(self, self.config, -1, style=border_style|wx.TAB_TRAVERSAL)
  2352 + self.panel_ffill_confidence.SetMinSize((250, -1))
  2353 + self.panel_ffill_confidence.Hide()
  2354 +
2293 self.close_btn = wx.Button(self, wx.ID_CLOSE) 2355 self.close_btn = wx.Button(self, wx.ID_CLOSE)
2294 2356
2295 # Sizer 2357 # Sizer
@@ -2316,8 +2378,8 @@ class FFillSegmentationOptionsDialog(wx.Dialog): @@ -2316,8 +2378,8 @@ class FFillSegmentationOptionsDialog(wx.Dialog):
2316 sizer.Add(self.panel_ffill_dynamic, (11, 0), (1, 6), flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7) 2378 sizer.Add(self.panel_ffill_dynamic, (11, 0), (1, 6), flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7)
2317 elif self.config.method == 'confidence': 2379 elif self.config.method == 'confidence':
2318 self.cmb_method.SetSelection(2) 2380 self.cmb_method.SetSelection(2)
2319 - self.panel_ffill_dynamic.Show()  
2320 - sizer.Add(self.panel_ffill_dynamic, (11, 0), (1, 6), flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7) 2381 + self.panel_ffill_confidence.Show()
  2382 + sizer.Add(self.panel_ffill_confidence, (11, 0), (1, 6), flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7)
2321 else: 2383 else:
2322 self.cmb_method.SetSelection(1) 2384 self.cmb_method.SetSelection(1)
2323 self.panel_ffill_threshold.Show() 2385 self.panel_ffill_threshold.Show()
@@ -2363,21 +2425,25 @@ class FFillSegmentationOptionsDialog(wx.Dialog): @@ -2363,21 +2425,25 @@ class FFillSegmentationOptionsDialog(wx.Dialog):
2363 self.config.con_3d = 26 2425 self.config.con_3d = 26
2364 2426
2365 def OnSetMethod(self, evt): 2427 def OnSetMethod(self, evt):
  2428 + item_panel = self.GetSizer().FindItemAtPosition((11, 0)).GetWindow()
  2429 +
2366 if self.cmb_method.GetSelection() == 0: 2430 if self.cmb_method.GetSelection() == 0:
2367 self.config.method = 'dynamic' 2431 self.config.method = 'dynamic'
2368 - self.panel_ffill_threshold.Hide() 2432 + item_panel.Hide()
2369 self.panel_ffill_dynamic.Show() 2433 self.panel_ffill_dynamic.Show()
2370 - self.GetSizer().Replace(self.panel_ffill_threshold, self.panel_ffill_dynamic) 2434 + self.GetSizer().Replace(item_panel, self.panel_ffill_dynamic)
  2435 +
2371 elif self.cmb_method.GetSelection() == 2: 2436 elif self.cmb_method.GetSelection() == 2:
2372 self.config.method = 'confidence' 2437 self.config.method = 'confidence'
2373 - self.panel_ffill_threshold.Hide()  
2374 - self.panel_ffill_dynamic.Show()  
2375 - self.GetSizer().Replace(self.panel_ffill_threshold, self.panel_ffill_dynamic) 2438 + item_panel.Hide()
  2439 + self.panel_ffill_confidence.Show()
  2440 + self.GetSizer().Replace(item_panel, self.panel_ffill_confidence)
  2441 +
2376 else: 2442 else:
2377 self.config.method = 'threshold' 2443 self.config.method = 'threshold'
2378 - self.panel_ffill_dynamic.Hide() 2444 + item_panel.Hide()
2379 self.panel_ffill_threshold.Show() 2445 self.panel_ffill_threshold.Show()
2380 - self.GetSizer().Replace(self.panel_ffill_dynamic, self.panel_ffill_threshold) 2446 + self.GetSizer().Replace(item_panel, self.panel_ffill_threshold)
2381 2447
2382 self.GetSizer().Fit(self) 2448 self.GetSizer().Fit(self)
2383 self.Layout() 2449 self.Layout()