Commit 894282fe02647efd0be97fbbbc14baa2b2afa1b3
1 parent
d4121f67
Exists in
measure
The ClutImagedata is changing the slice lookuptable
Showing
3 changed files
with
73 additions
and
10 deletions
Show diff stats
invesalius/data/slice_.py
| ... | ... | @@ -34,6 +34,11 @@ import utils |
| 34 | 34 | from mask import Mask |
| 35 | 35 | from project import Project |
| 36 | 36 | |
| 37 | +OTHER=0 | |
| 38 | +PLIST=1 | |
| 39 | +WIDGET=2 | |
| 40 | + | |
| 41 | + | |
| 37 | 42 | class SliceBuffer(object): |
| 38 | 43 | """ |
| 39 | 44 | This class is used as buffer that mantains the vtkImageData and numpy array |
| ... | ... | @@ -66,9 +71,6 @@ class SliceBuffer(object): |
| 66 | 71 | self.vtk_mask = None |
| 67 | 72 | |
| 68 | 73 | |
| 69 | - | |
| 70 | - | |
| 71 | - | |
| 72 | 74 | class Slice(object): |
| 73 | 75 | __metaclass__= utils.Singleton |
| 74 | 76 | # Only one slice will be initialized per time (despite several viewers |
| ... | ... | @@ -94,8 +96,7 @@ class Slice(object): |
| 94 | 96 | self.num_gradient = 0 |
| 95 | 97 | self.interaction_style = st.StyleStateManager() |
| 96 | 98 | |
| 97 | - self.from_plist = False | |
| 98 | - | |
| 99 | + self.from_ = OTHER | |
| 99 | 100 | self.__bind_events() |
| 100 | 101 | |
| 101 | 102 | def __bind_events(self): |
| ... | ... | @@ -130,6 +131,9 @@ class Slice(object): |
| 130 | 131 | Publisher.subscribe(self.UpdateColourTableBackgroundPlist,\ |
| 131 | 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 | 137 | Publisher.subscribe(self.InputImageWidget, 'Input Image in the widget') |
| 134 | 138 | |
| 135 | 139 | Publisher.subscribe(self.OnExportMask,'Export mask to file') |
| ... | ... | @@ -707,7 +711,7 @@ class Slice(object): |
| 707 | 711 | |
| 708 | 712 | def UpdateColourTableBackground(self, pubsub_evt): |
| 709 | 713 | values = pubsub_evt.data |
| 710 | - self.from_plist = False | |
| 714 | + self.from_= OTHER | |
| 711 | 715 | self.number_of_colours= values[0] |
| 712 | 716 | self.saturation_range = values[1] |
| 713 | 717 | self.hue_range = values[2] |
| ... | ... | @@ -718,7 +722,14 @@ class Slice(object): |
| 718 | 722 | |
| 719 | 723 | def UpdateColourTableBackgroundPlist(self, pubsub_evt): |
| 720 | 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 | 733 | for buffer_ in self.buffer_slices.values(): |
| 723 | 734 | buffer_.discard_vtk_image() |
| 724 | 735 | Publisher.sendMessage('Reload actual slice') |
| ... | ... | @@ -829,7 +840,7 @@ class Slice(object): |
| 829 | 840 | Publisher.sendMessage('Update slice viewer') |
| 830 | 841 | |
| 831 | 842 | def do_ww_wl(self, image): |
| 832 | - if self.from_plist: | |
| 843 | + if self.from_ == PLIST: | |
| 833 | 844 | lut = vtk.vtkWindowLevelLookupTable() |
| 834 | 845 | lut.SetWindow(self.window_width) |
| 835 | 846 | lut.SetLevel(self.window_level) |
| ... | ... | @@ -847,6 +858,20 @@ class Slice(object): |
| 847 | 858 | colorer.SetLookupTable(lut) |
| 848 | 859 | colorer.SetOutputFormatToRGB() |
| 849 | 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 | 875 | else: |
| 851 | 876 | colorer = vtk.vtkImageMapToWindowLevelColors() |
| 852 | 877 | colorer.SetInput(image) |
| ... | ... | @@ -869,7 +894,7 @@ class Slice(object): |
| 869 | 894 | return m.astype('uint8') |
| 870 | 895 | |
| 871 | 896 | def do_colour_image(self, imagedata): |
| 872 | - if self.from_plist: | |
| 897 | + if self.from_ in (PLIST, WIDGET): | |
| 873 | 898 | return imagedata |
| 874 | 899 | else: |
| 875 | 900 | # map scalar values into colors | ... | ... |
invesalius/gui/dialogs.py
| ... | ... | @@ -34,6 +34,9 @@ import project as proj |
| 34 | 34 | import session as ses |
| 35 | 35 | import utils |
| 36 | 36 | |
| 37 | +from gui.widgets import clut_imagedata | |
| 38 | + | |
| 39 | +import numpy as np | |
| 37 | 40 | |
| 38 | 41 | class MaskEvent(wx.PyCommandEvent): |
| 39 | 42 | def __init__(self , evtType, id, mask_index): |
| ... | ... | @@ -1274,9 +1277,32 @@ class SurfaceMethodPanel(wx.Panel): |
| 1274 | 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 | 26 | import constants as const |
| 27 | 27 | import presets |
| 28 | 28 | |
| 29 | +from gui.dialogs import ClutImagedataDialog | |
| 30 | + | |
| 29 | 31 | class SliceMenu(wx.Menu): |
| 30 | 32 | def __init__(self): |
| 31 | 33 | wx.Menu.__init__(self) |
| ... | ... | @@ -93,6 +95,11 @@ class SliceMenu(wx.Menu): |
| 93 | 95 | color_item = wx.MenuItem(submenu_wl, new_id, name, kind=wx.ITEM_RADIO) |
| 94 | 96 | submenu_pseudo_colours.AppendItem(color_item) |
| 95 | 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 | 104 | flag_tiling = False |
| 98 | 105 | #------------ Sub menu of the image tiling --------------- |
| ... | ... | @@ -180,5 +187,10 @@ class SliceMenu(wx.Menu): |
| 180 | 187 | Publisher.sendMessage('Set slice viewer layout', values) |
| 181 | 188 | Publisher.sendMessage('Update slice viewer') |
| 182 | 189 | |
| 190 | + elif key == _('Custom'): | |
| 191 | + cdialog = ClutImagedataDialog() | |
| 192 | + cdialog.Show() | |
| 193 | + | |
| 194 | + | |
| 183 | 195 | evt.Skip() |
| 184 | 196 | ... | ... |