From 516b0f05ceca0b92fd94ea19091e5fc719d753ff Mon Sep 17 00:00:00 2001 From: Thiago Franco de Moraes Date: Fri, 27 Mar 2015 13:11:47 -0300 Subject: [PATCH] Tool to keep the greatest component from the mask --- invesalius/data/slice_.py | 28 ++++++++++++++++++++++++++++ invesalius/gui/widgets/slice_menu.py | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------ 2 files changed, 115 insertions(+), 78 deletions(-) diff --git a/invesalius/data/slice_.py b/invesalius/data/slice_.py index 9f73e5d..86f0cf1 100644 --- a/invesalius/data/slice_.py +++ b/invesalius/data/slice_.py @@ -16,10 +16,13 @@ # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais # detalhes. #-------------------------------------------------------------------------- +import heapq import os import tempfile import numpy +from scipy import ndimage +from scipy.ndimage.measurements import label import vtk from wx.lib.pubsub import pub as Publisher @@ -162,6 +165,8 @@ class Slice(object): Publisher.subscribe(self._do_boolean_op, 'Do boolean operation') + Publisher.subscribe(self._keep_greatest_region, 'Keep greatest component') + Publisher.subscribe(self.OnExportMask,'Export mask to file') Publisher.subscribe(self.OnCloseProject, 'Close project data') @@ -1114,6 +1119,7 @@ class Slice(object): if mask.matrix[n, 0, 0] == 0: m = mask.matrix[n, 1:, 1:] mask.matrix[n, 1:, 1:] = self.do_threshold_to_a_slice(self.matrix[n-1], m, mask.threshold_range) + mask.matrix[n, 0, 0] = 1 mask.matrix.flush() @@ -1261,6 +1267,28 @@ class Slice(object): future_mask.was_edited = True self._add_mask_into_proj(future_mask) + def _keep_greatest_region(self, pubsub_evt): + self.keep_greatest_region(self.current_mask) + + def keep_greatest_region(self, mask): + self.do_threshold_to_all_slices(mask) + mask.matrix[0, :, :] = 1 + mask.matrix[:, 0, :] = 1 + mask.matrix[:, :, 0] = 1 + + m= mask.matrix[1:, 1:, 1:] + m[:] = (m > 128) * 255 + + labeled_array, num_features = label(m) + sizes = ndimage.sum(m,labeled_array,range(1,num_features+1)) + sl = zip(range(1, num_features + 1), sizes) + sl.sort(key=lambda x: x[1]) + tag = sl[-1][0] + m[labeled_array!=tag]=0 + + mask.was_edited = True + self.discard_all_buffers() + def apply_slice_buffer_to_mask(self, orientation): """ Apply the modifications (edition) in mask buffer to mask. diff --git a/invesalius/gui/widgets/slice_menu.py b/invesalius/gui/widgets/slice_menu.py index 0b8656c..e323a23 100644 --- a/invesalius/gui/widgets/slice_menu.py +++ b/invesalius/gui/widgets/slice_menu.py @@ -164,6 +164,11 @@ class SliceMenu(wx.Menu): self.AppendMenu(-1, _("Projection type"), submenu_projection) ###self.AppendMenu(-1, _("Image Tiling"), submenu_image_tiling) + self.kgc_id = new_id = wx.NewId() + item = wx.MenuItem(self, new_id, u"Keep greatest component") + self.AppendItem(item) + + # It doesn't work in Linux self.Bind(wx.EVT_MENU, self.OnPopup) # In Linux the bind must be putted in the submenu @@ -207,86 +212,90 @@ class SliceMenu(wx.Menu): def OnPopup(self, evt): id = evt.GetId() - item = self.ID_TO_TOOL_ITEM[evt.GetId()] - key = item.GetLabel() - if(key in const.WINDOW_LEVEL.keys()): - window, level = const.WINDOW_LEVEL[key] - Publisher.sendMessage('Bright and contrast adjustment image', - (window, level)) - Publisher.sendMessage('Update window level value',\ - (window, level)) - Publisher.sendMessage('Update window and level text',\ - "WL: %d WW: %d"%(level, window)) - Publisher.sendMessage('Update slice viewer') - - #Necessary update the slice plane in the volume case exists - Publisher.sendMessage('Render volume viewer') - - elif(key in const.SLICE_COLOR_TABLE.keys()): - values = const.SLICE_COLOR_TABLE[key] - Publisher.sendMessage('Change colour table from background image', values) - Publisher.sendMessage('Update slice viewer') - - if sys.platform == 'linux2': - for i in self.pseudo_color_items: - it = self.pseudo_color_items[i] - if it.IsChecked(): - it.Toggle() - - item.Toggle() - self.HideClutDialog() - self._gen_event = True - - elif key in self.plist_presets: - values = presets.get_wwwl_preset_colours(self.plist_presets[key]) - Publisher.sendMessage('Change colour table from background image from plist', values) - Publisher.sendMessage('Update slice viewer') - - if sys.platform == 'linux2': - for i in self.pseudo_color_items: - it = self.pseudo_color_items[i] - if it.IsChecked(): - it.Toggle() - - item.Toggle() - self.HideClutDialog() - self._gen_event = True - - elif(key in const.IMAGE_TILING.keys()): - values = const.IMAGE_TILING[key] - Publisher.sendMessage('Set slice viewer layout', values) - Publisher.sendMessage('Update slice viewer') - - elif key in PROJECTIONS_ID: - print 'Key', key - pid = PROJECTIONS_ID[key] - Publisher.sendMessage('Set projection type', pid) - Publisher.sendMessage('Reload actual slice') - elif key == _('Custom'): - if self.cdialog is None: - slc = sl.Slice() - histogram = slc.histogram - init = slc.matrix.min() - end = slc.matrix.max() - nodes = slc.nodes - self.cdialog = ClutImagedataDialog(histogram, init, end, nodes) - self.cdialog.Show() - else: - self.cdialog.Show(self._gen_event) - - if sys.platform == 'linux2': - for i in self.pseudo_color_items: - it = self.pseudo_color_items[i] - if it.IsChecked(): - it.Toggle() - - item.Toggle() + if id == self.kgc_id: + Publisher.sendMessage('Keep greatest component') + Publisher.sendMessage('Reload actual slice') + else: item = self.ID_TO_TOOL_ITEM[evt.GetId()] - item.Check(True) - self._gen_event = False - - evt.Skip() + key = item.GetLabel() + if(key in const.WINDOW_LEVEL.keys()): + window, level = const.WINDOW_LEVEL[key] + Publisher.sendMessage('Bright and contrast adjustment image', + (window, level)) + Publisher.sendMessage('Update window level value',\ + (window, level)) + Publisher.sendMessage('Update window and level text',\ + "WL: %d WW: %d"%(level, window)) + Publisher.sendMessage('Update slice viewer') + + #Necessary update the slice plane in the volume case exists + Publisher.sendMessage('Render volume viewer') + + elif(key in const.SLICE_COLOR_TABLE.keys()): + values = const.SLICE_COLOR_TABLE[key] + Publisher.sendMessage('Change colour table from background image', values) + Publisher.sendMessage('Update slice viewer') + + if sys.platform == 'linux2': + for i in self.pseudo_color_items: + it = self.pseudo_color_items[i] + if it.IsChecked(): + it.Toggle() + + item.Toggle() + self.HideClutDialog() + self._gen_event = True + + elif key in self.plist_presets: + values = presets.get_wwwl_preset_colours(self.plist_presets[key]) + Publisher.sendMessage('Change colour table from background image from plist', values) + Publisher.sendMessage('Update slice viewer') + + if sys.platform == 'linux2': + for i in self.pseudo_color_items: + it = self.pseudo_color_items[i] + if it.IsChecked(): + it.Toggle() + + item.Toggle() + self.HideClutDialog() + self._gen_event = True + + elif(key in const.IMAGE_TILING.keys()): + values = const.IMAGE_TILING[key] + Publisher.sendMessage('Set slice viewer layout', values) + Publisher.sendMessage('Update slice viewer') + + elif key in PROJECTIONS_ID: + print 'Key', key + pid = PROJECTIONS_ID[key] + Publisher.sendMessage('Set projection type', pid) + Publisher.sendMessage('Reload actual slice') + + elif key == _('Custom'): + if self.cdialog is None: + slc = sl.Slice() + histogram = slc.histogram + init = slc.matrix.min() + end = slc.matrix.max() + nodes = slc.nodes + self.cdialog = ClutImagedataDialog(histogram, init, end, nodes) + self.cdialog.Show() + else: + self.cdialog.Show(self._gen_event) + + if sys.platform == 'linux2': + for i in self.pseudo_color_items: + it = self.pseudo_color_items[i] + if it.IsChecked(): + it.Toggle() + + item.Toggle() + item = self.ID_TO_TOOL_ITEM[evt.GetId()] + item.Check(True) + self._gen_event = False + evt.Skip() def HideClutDialog(self): if self.cdialog: -- libgit2 0.21.2