Commit 894282fe02647efd0be97fbbbc14baa2b2afa1b3

Authored by Thiago Franco de Moraes
1 parent d4121f67
Exists in measure

The ClutImagedata is changing the slice lookuptable

invesalius/data/slice_.py
@@ -34,6 +34,11 @@ import utils @@ -34,6 +34,11 @@ import utils
34 from mask import Mask 34 from mask import Mask
35 from project import Project 35 from project import Project
36 36
  37 +OTHER=0
  38 +PLIST=1
  39 +WIDGET=2
  40 +
  41 +
37 class SliceBuffer(object): 42 class SliceBuffer(object):
38 """ 43 """
39 This class is used as buffer that mantains the vtkImageData and numpy array 44 This class is used as buffer that mantains the vtkImageData and numpy array
@@ -66,9 +71,6 @@ class SliceBuffer(object): @@ -66,9 +71,6 @@ class SliceBuffer(object):
66 self.vtk_mask = None 71 self.vtk_mask = None
67 72
68 73
69 -  
70 -  
71 -  
72 class Slice(object): 74 class Slice(object):
73 __metaclass__= utils.Singleton 75 __metaclass__= utils.Singleton
74 # Only one slice will be initialized per time (despite several viewers 76 # Only one slice will be initialized per time (despite several viewers
@@ -94,8 +96,7 @@ class Slice(object): @@ -94,8 +96,7 @@ class Slice(object):
94 self.num_gradient = 0 96 self.num_gradient = 0
95 self.interaction_style = st.StyleStateManager() 97 self.interaction_style = st.StyleStateManager()
96 98
97 - self.from_plist = False  
98 - 99 + self.from_ = OTHER
99 self.__bind_events() 100 self.__bind_events()
100 101
101 def __bind_events(self): 102 def __bind_events(self):
@@ -130,6 +131,9 @@ class Slice(object): @@ -130,6 +131,9 @@ class Slice(object):
130 Publisher.subscribe(self.UpdateColourTableBackgroundPlist,\ 131 Publisher.subscribe(self.UpdateColourTableBackgroundPlist,\
131 'Change colour table from background image from plist') 132 'Change colour table from background image from plist')
132 133
  134 + Publisher.subscribe(self.UpdateColourTableBackgroundWidget,\
  135 + 'Change colour table from background image from widget')
  136 +
133 Publisher.subscribe(self.InputImageWidget, 'Input Image in the widget') 137 Publisher.subscribe(self.InputImageWidget, 'Input Image in the widget')
134 138
135 Publisher.subscribe(self.OnExportMask,'Export mask to file') 139 Publisher.subscribe(self.OnExportMask,'Export mask to file')
@@ -707,7 +711,7 @@ class Slice(object): @@ -707,7 +711,7 @@ class Slice(object):
707 711
708 def UpdateColourTableBackground(self, pubsub_evt): 712 def UpdateColourTableBackground(self, pubsub_evt):
709 values = pubsub_evt.data 713 values = pubsub_evt.data
710 - self.from_plist = False 714 + self.from_= OTHER
711 self.number_of_colours= values[0] 715 self.number_of_colours= values[0]
712 self.saturation_range = values[1] 716 self.saturation_range = values[1]
713 self.hue_range = values[2] 717 self.hue_range = values[2]
@@ -718,7 +722,14 @@ class Slice(object): @@ -718,7 +722,14 @@ class Slice(object):
718 722
719 def UpdateColourTableBackgroundPlist(self, pubsub_evt): 723 def UpdateColourTableBackgroundPlist(self, pubsub_evt):
720 self.values = pubsub_evt.data 724 self.values = pubsub_evt.data
721 - self.from_plist = True 725 + self.from_= PLIST
  726 + for buffer_ in self.buffer_slices.values():
  727 + buffer_.discard_vtk_image()
  728 + Publisher.sendMessage('Reload actual slice')
  729 +
  730 + def UpdateColourTableBackgroundWidget(self, pubsub_evt):
  731 + self.values = pubsub_evt.data
  732 + self.from_= WIDGET
722 for buffer_ in self.buffer_slices.values(): 733 for buffer_ in self.buffer_slices.values():
723 buffer_.discard_vtk_image() 734 buffer_.discard_vtk_image()
724 Publisher.sendMessage('Reload actual slice') 735 Publisher.sendMessage('Reload actual slice')
@@ -829,7 +840,7 @@ class Slice(object): @@ -829,7 +840,7 @@ class Slice(object):
829 Publisher.sendMessage('Update slice viewer') 840 Publisher.sendMessage('Update slice viewer')
830 841
831 def do_ww_wl(self, image): 842 def do_ww_wl(self, image):
832 - if self.from_plist: 843 + if self.from_ == PLIST:
833 lut = vtk.vtkWindowLevelLookupTable() 844 lut = vtk.vtkWindowLevelLookupTable()
834 lut.SetWindow(self.window_width) 845 lut.SetWindow(self.window_width)
835 lut.SetLevel(self.window_level) 846 lut.SetLevel(self.window_level)
@@ -847,6 +858,20 @@ class Slice(object): @@ -847,6 +858,20 @@ class Slice(object):
847 colorer.SetLookupTable(lut) 858 colorer.SetLookupTable(lut)
848 colorer.SetOutputFormatToRGB() 859 colorer.SetOutputFormatToRGB()
849 colorer.Update() 860 colorer.Update()
  861 + elif self.from_ == WIDGET:
  862 + lut = vtk.vtkColorTransferFunction()
  863 +
  864 + for n in self.values:
  865 + r, g, b = n.colour
  866 + lut.AddRGBPoint(n.value, r/255.0, g/255.0, b/255.0)
  867 +
  868 + lut.Build()
  869 +
  870 + colorer = vtk.vtkImageMapToColors()
  871 + colorer.SetLookupTable(lut)
  872 + colorer.SetInput(image)
  873 + colorer.SetOutputFormatToRGB()
  874 + colorer.Update()
850 else: 875 else:
851 colorer = vtk.vtkImageMapToWindowLevelColors() 876 colorer = vtk.vtkImageMapToWindowLevelColors()
852 colorer.SetInput(image) 877 colorer.SetInput(image)
@@ -869,7 +894,7 @@ class Slice(object): @@ -869,7 +894,7 @@ class Slice(object):
869 return m.astype('uint8') 894 return m.astype('uint8')
870 895
871 def do_colour_image(self, imagedata): 896 def do_colour_image(self, imagedata):
872 - if self.from_plist: 897 + if self.from_ in (PLIST, WIDGET):
873 return imagedata 898 return imagedata
874 else: 899 else:
875 # map scalar values into colors 900 # map scalar values into colors
invesalius/gui/dialogs.py
@@ -34,6 +34,9 @@ import project as proj @@ -34,6 +34,9 @@ import project as proj
34 import session as ses 34 import session as ses
35 import utils 35 import utils
36 36
  37 +from gui.widgets import clut_imagedata
  38 +
  39 +import numpy as np
37 40
38 class MaskEvent(wx.PyCommandEvent): 41 class MaskEvent(wx.PyCommandEvent):
39 def __init__(self , evtType, id, mask_index): 42 def __init__(self , evtType, id, mask_index):
@@ -1274,9 +1277,32 @@ class SurfaceMethodPanel(wx.Panel): @@ -1274,9 +1277,32 @@ class SurfaceMethodPanel(wx.Panel):
1274 self.method_sizer.Layout() 1277 self.method_sizer.Layout()
1275 1278
1276 1279
  1280 +class ClutImagedataDialog(wx.Dialog):
  1281 + def __init__(self):
  1282 + pre = wx.PreDialog()
  1283 + pre.Create(None, -1, style=wx.DEFAULT_DIALOG_STYLE)
  1284 + self.PostCreate(pre)
1277 1285
  1286 + self._init_gui()
  1287 + self._bind_events_wx()
1278 1288
1279 - 1289 + def _init_gui(self):
  1290 + self.clut_widget = clut_imagedata.CLUTImageDataWidget(self, -1,
  1291 + np.random.randint(0,
  1292 + 1000,
  1293 + (1000,)),
  1294 + -1000, 1000,
  1295 + 230, 255)
  1296 + sizer = wx.BoxSizer(wx.VERTICAL)
  1297 + sizer.Add(self.clut_widget, 1, wx.EXPAND)
  1298 +
  1299 + self.SetSizer(sizer)
  1300 + self.Fit()
1280 1301
  1302 + def _bind_events_wx(self):
  1303 + self.clut_widget.Bind(clut_imagedata.EVT_CLUT_POINT_MOVE, self.OnClutChange)
1281 1304
  1305 + def OnClutChange(self, evt):
  1306 + Publisher.sendMessage('Change colour table from background image from widget',
  1307 + evt.GetNodes())
1282 1308
invesalius/gui/widgets/slice_menu.py
@@ -26,6 +26,8 @@ from wx.lib.pubsub import pub as Publisher @@ -26,6 +26,8 @@ from wx.lib.pubsub import pub as Publisher
26 import constants as const 26 import constants as const
27 import presets 27 import presets
28 28
  29 +from gui.dialogs import ClutImagedataDialog
  30 +
29 class SliceMenu(wx.Menu): 31 class SliceMenu(wx.Menu):
30 def __init__(self): 32 def __init__(self):
31 wx.Menu.__init__(self) 33 wx.Menu.__init__(self)
@@ -93,6 +95,11 @@ class SliceMenu(wx.Menu): @@ -93,6 +95,11 @@ class SliceMenu(wx.Menu):
93 color_item = wx.MenuItem(submenu_wl, new_id, name, kind=wx.ITEM_RADIO) 95 color_item = wx.MenuItem(submenu_wl, new_id, name, kind=wx.ITEM_RADIO)
94 submenu_pseudo_colours.AppendItem(color_item) 96 submenu_pseudo_colours.AppendItem(color_item)
95 self.ID_TO_TOOL_ITEM[new_id] = color_item 97 self.ID_TO_TOOL_ITEM[new_id] = color_item
  98 +
  99 + new_id = wx.NewId()
  100 + color_item = wx.MenuItem(submenu_wl, new_id, _('Custom'), kind=wx.ITEM_RADIO)
  101 + submenu_pseudo_colours.AppendItem(color_item)
  102 + self.ID_TO_TOOL_ITEM[new_id] = color_item
96 103
97 flag_tiling = False 104 flag_tiling = False
98 #------------ Sub menu of the image tiling --------------- 105 #------------ Sub menu of the image tiling ---------------
@@ -180,5 +187,10 @@ class SliceMenu(wx.Menu): @@ -180,5 +187,10 @@ class SliceMenu(wx.Menu):
180 Publisher.sendMessage('Set slice viewer layout', values) 187 Publisher.sendMessage('Set slice viewer layout', values)
181 Publisher.sendMessage('Update slice viewer') 188 Publisher.sendMessage('Update slice viewer')
182 189
  190 + elif key == _('Custom'):
  191 + cdialog = ClutImagedataDialog()
  192 + cdialog.Show()
  193 +
  194 +
183 evt.Skip() 195 evt.Skip()
184 196