diff --git a/invesalius/data/styles.py b/invesalius/data/styles.py index b916a2c..2666363 100644 --- a/invesalius/data/styles.py +++ b/invesalius/data/styles.py @@ -1983,6 +1983,9 @@ class FFillSegmentationConfig(object): self.use_ww_wl = True + self.confid_mult = 2.5 + self.confid_iters = 3 + class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): def __init__(self, viewer): @@ -2145,7 +2148,15 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): cp_mask = self.viewer.slice_.current_mask.matrix.copy() if self.config.method == 'confidence': - out_mask = self.do_rg_confidence(image, mask, (x, y, z), bstruct) + with futures.ThreadPoolExecutor(max_workers=1) as executor: + future = executor.submit(self.do_rg_confidence, image, mask, (x, y, z), bstruct) + + dlg = wx.ProgressDialog(self._progr_title, self._progr_msg, parent=None, style=wx.PD_APP_MODAL) + while not future.done(): + dlg.Pulse() + time.sleep(0.1) + dlg.Destroy() + out_mask = future.result() else: out_mask = np.zeros_like(mask) with futures.ThreadPoolExecutor(max_workers=1) as executor: @@ -2171,27 +2182,28 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): image = get_LUT_value_255(image, ww, wl) bool_mask = np.zeros_like(mask, dtype='bool') out_mask = np.zeros_like(mask) - for i in xrange(int(x-1), int(x+2)): - if i < 0 or i >= bool_mask.shape[2]: + + for k in xrange(int(z-1), int(z+2)): + if k < 0 or k >= bool_mask.shape[0]: continue for j in xrange(int(y-1), int(y+2)): if j < 0 or j >= bool_mask.shape[1]: continue - for k in xrange(int(z-1), int(z+2)): - if k < 0 or k >= bool_mask.shape[0]: + for i in xrange(int(x-1), int(x+2)): + if i < 0 or i >= bool_mask.shape[2]: continue bool_mask[k, j, i] = True - - for i in xrange(3): + for i in xrange(self.config.confid_iters): var = np.std(image[bool_mask]) mean = np.mean(image[bool_mask]) - t0 = mean - var * 2.5 - t1 = mean + var * 2.5 - print var, mean, t0, t1 + t0 = mean - var * self.config.confid_mult + t1 = mean + var * self.config.confid_mult - floodfill.floodfill_threshold(image, [[x, y, 0]], t0, t1, 1, bstruct, out_mask) + print self.config.confid_iters, self.config.confid_mult + + floodfill.floodfill_threshold(image, [[x, y, z]], t0, t1, 1, bstruct, out_mask) bool_mask[out_mask == 1] = True diff --git a/invesalius/gui/dialogs.py b/invesalius/gui/dialogs.py index c29c6d8..d000e05 100644 --- a/invesalius/gui/dialogs.py +++ b/invesalius/gui/dialogs.py @@ -2031,6 +2031,64 @@ class PanelFFillDynamic(wx.Panel): self.config.dev_min = self.deviation_min.GetValue() +class PanelFFillConfidence(wx.Panel): + def __init__(self, parent, config, ID=-1, style=wx.TAB_TRAVERSAL|wx.NO_BORDER): + wx.Panel.__init__(self, parent, ID, style=style) + + self.config = config + + self._init_gui() + + def _init_gui(self): + self.use_ww_wl = wx.CheckBox(self, -1, _(u"Use WW&WL")) + self.use_ww_wl.SetValue(self.config.use_ww_wl) + + self.spin_mult = floatspin.FloatSpin(self, -1, + value=self.config.confid_mult, + min_val=1.0, max_val=10.0, + increment=0.1, digits=1, + style=wx.TE_PROCESS_TAB|wx.TE_PROCESS_ENTER, + agwStyle=floatspin.FS_RIGHT) + w, h = self.spin_mult.GetTextExtent('M') + self.spin_mult.SetMinSize((w*7, -1)) + + self.spin_iters = wx.SpinCtrl(self, -1, value='%d' % self.config.confid_iters, min=0, max=100) + self.spin_iters.SetMinSize((w*7, -1)) + + sizer = wx.GridBagSizer(5, 5) + + sizer.AddStretchSpacer((0, 0)) + + sizer.Add(self.use_ww_wl, (1, 0), (1, 6), flag=wx.LEFT, border=5) + + sizer.AddStretchSpacer((2, 0)) + + sizer.Add(wx.StaticText(self, -1, _(u"Multiplier")), (3, 0), (1, 3), flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border=5) + sizer.Add(self.spin_mult, (3, 3), (1, 2)) + + sizer.Add(wx.StaticText(self, -1, _(u"Iterations")), (4, 0), (1, 3), flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border=5) + sizer.Add(self.spin_iters, (4, 3), (1, 2)) + + sizer.AddStretchSpacer((5, 0)) + + self.SetSizer(sizer) + sizer.Fit(self) + self.Layout() + + self.use_ww_wl.Bind(wx.EVT_CHECKBOX, self.OnSetUseWWWL) + self.spin_mult.Bind(wx.EVT_SPINCTRL, self.OnSetMult) + self.spin_iters.Bind(wx.EVT_SPINCTRL, self.OnSetIters) + + def OnSetUseWWWL(self, evt): + self.config.use_ww_wl = self.use_ww_wl.GetValue() + + def OnSetMult(self, evt): + self.config.confid_mult = self.spin_mult.GetValue() + + def OnSetIters(self, evt): + self.config.confid_iters = self.spin_iters.GetValue() + + class FFillOptionsDialog(wx.Dialog): def __init__(self, title, config): pre = wx.PreDialog() @@ -2290,6 +2348,10 @@ class FFillSegmentationOptionsDialog(wx.Dialog): self.panel_ffill_dynamic.SetMinSize((250, -1)) self.panel_ffill_dynamic.Hide() + self.panel_ffill_confidence = PanelFFillConfidence(self, self.config, -1, style=border_style|wx.TAB_TRAVERSAL) + self.panel_ffill_confidence.SetMinSize((250, -1)) + self.panel_ffill_confidence.Hide() + self.close_btn = wx.Button(self, wx.ID_CLOSE) # Sizer @@ -2316,8 +2378,8 @@ class FFillSegmentationOptionsDialog(wx.Dialog): sizer.Add(self.panel_ffill_dynamic, (11, 0), (1, 6), flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7) elif self.config.method == 'confidence': self.cmb_method.SetSelection(2) - self.panel_ffill_dynamic.Show() - sizer.Add(self.panel_ffill_dynamic, (11, 0), (1, 6), flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7) + self.panel_ffill_confidence.Show() + sizer.Add(self.panel_ffill_confidence, (11, 0), (1, 6), flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7) else: self.cmb_method.SetSelection(1) self.panel_ffill_threshold.Show() @@ -2363,21 +2425,25 @@ class FFillSegmentationOptionsDialog(wx.Dialog): self.config.con_3d = 26 def OnSetMethod(self, evt): + item_panel = self.GetSizer().FindItemAtPosition((11, 0)).GetWindow() + if self.cmb_method.GetSelection() == 0: self.config.method = 'dynamic' - self.panel_ffill_threshold.Hide() + item_panel.Hide() self.panel_ffill_dynamic.Show() - self.GetSizer().Replace(self.panel_ffill_threshold, self.panel_ffill_dynamic) + self.GetSizer().Replace(item_panel, self.panel_ffill_dynamic) + elif self.cmb_method.GetSelection() == 2: self.config.method = 'confidence' - self.panel_ffill_threshold.Hide() - self.panel_ffill_dynamic.Show() - self.GetSizer().Replace(self.panel_ffill_threshold, self.panel_ffill_dynamic) + item_panel.Hide() + self.panel_ffill_confidence.Show() + self.GetSizer().Replace(item_panel, self.panel_ffill_confidence) + else: self.config.method = 'threshold' - self.panel_ffill_dynamic.Hide() + item_panel.Hide() self.panel_ffill_threshold.Show() - self.GetSizer().Replace(self.panel_ffill_dynamic, self.panel_ffill_threshold) + self.GetSizer().Replace(item_panel, self.panel_ffill_threshold) self.GetSizer().Fit(self) self.Layout() -- libgit2 0.21.2