Commit 7c80274f085e948751ea02c174aa811faa07e4b7
1 parent
8d9b272f
Exists in
measure
Reading and applying osirix preset colours
Showing
4 changed files
with
97 additions
and
23 deletions
Show diff stats
invesalius/constants.py
| @@ -295,7 +295,7 @@ WINDOW_LEVEL = {_("Abdomen"):(350,50), | @@ -295,7 +295,7 @@ WINDOW_LEVEL = {_("Abdomen"):(350,50), | ||
| 295 | REDUCE_IMAGEDATA_QUALITY = 0 | 295 | REDUCE_IMAGEDATA_QUALITY = 0 |
| 296 | 296 | ||
| 297 | ICON_DIR = os.path.abspath(os.path.join('..', 'icons')) | 297 | ICON_DIR = os.path.abspath(os.path.join('..', 'icons')) |
| 298 | -SAMPLE_DIR = os.path.abspath(os.path.join('..', 'samples')) | 298 | +SAMPLE_DIR = "/usr/share/doc/invesalius-examples/examples/" |
| 299 | DOC_DIR = os.path.abspath(os.path.join('..', 'docs')) | 299 | DOC_DIR = os.path.abspath(os.path.join('..', 'docs')) |
| 300 | 300 | ||
| 301 | 301 |
invesalius/data/slice_.py
| @@ -94,6 +94,8 @@ class Slice(object): | @@ -94,6 +94,8 @@ class Slice(object): | ||
| 94 | self.num_gradient = 0 | 94 | self.num_gradient = 0 |
| 95 | self.interaction_style = st.StyleStateManager() | 95 | self.interaction_style = st.StyleStateManager() |
| 96 | 96 | ||
| 97 | + self.from_plist = False | ||
| 98 | + | ||
| 97 | self.__bind_events() | 99 | self.__bind_events() |
| 98 | 100 | ||
| 99 | def __bind_events(self): | 101 | def __bind_events(self): |
| @@ -125,6 +127,9 @@ class Slice(object): | @@ -125,6 +127,9 @@ class Slice(object): | ||
| 125 | Publisher.subscribe(self.UpdateColourTableBackground,\ | 127 | Publisher.subscribe(self.UpdateColourTableBackground,\ |
| 126 | 'Change colour table from background image') | 128 | 'Change colour table from background image') |
| 127 | 129 | ||
| 130 | + Publisher.subscribe(self.UpdateColourTableBackgroundPlist,\ | ||
| 131 | + 'Change colour table from background image from plist') | ||
| 132 | + | ||
| 128 | Publisher.subscribe(self.InputImageWidget, 'Input Image in the widget') | 133 | Publisher.subscribe(self.InputImageWidget, 'Input Image in the widget') |
| 129 | 134 | ||
| 130 | Publisher.subscribe(self.OnExportMask,'Export mask to file') | 135 | Publisher.subscribe(self.OnExportMask,'Export mask to file') |
| @@ -702,6 +707,7 @@ class Slice(object): | @@ -702,6 +707,7 @@ class Slice(object): | ||
| 702 | 707 | ||
| 703 | def UpdateColourTableBackground(self, pubsub_evt): | 708 | def UpdateColourTableBackground(self, pubsub_evt): |
| 704 | values = pubsub_evt.data | 709 | values = pubsub_evt.data |
| 710 | + self.from_plist = False | ||
| 705 | self.number_of_colours= values[0] | 711 | self.number_of_colours= values[0] |
| 706 | self.saturation_range = values[1] | 712 | self.saturation_range = values[1] |
| 707 | self.hue_range = values[2] | 713 | self.hue_range = values[2] |
| @@ -710,6 +716,13 @@ class Slice(object): | @@ -710,6 +716,13 @@ class Slice(object): | ||
| 710 | buffer_.discard_vtk_image() | 716 | buffer_.discard_vtk_image() |
| 711 | Publisher.sendMessage('Reload actual slice') | 717 | Publisher.sendMessage('Reload actual slice') |
| 712 | 718 | ||
| 719 | + def UpdateColourTableBackgroundPlist(self, pubsub_evt): | ||
| 720 | + self.values = pubsub_evt.data | ||
| 721 | + self.from_plist = True | ||
| 722 | + for buffer_ in self.buffer_slices.values(): | ||
| 723 | + buffer_.discard_vtk_image() | ||
| 724 | + Publisher.sendMessage('Reload actual slice') | ||
| 725 | + | ||
| 713 | def InputImageWidget(self, pubsub_evt): | 726 | def InputImageWidget(self, pubsub_evt): |
| 714 | widget, orientation = pubsub_evt.data | 727 | widget, orientation = pubsub_evt.data |
| 715 | 728 | ||
| @@ -816,12 +829,31 @@ class Slice(object): | @@ -816,12 +829,31 @@ class Slice(object): | ||
| 816 | Publisher.sendMessage('Update slice viewer') | 829 | Publisher.sendMessage('Update slice viewer') |
| 817 | 830 | ||
| 818 | def do_ww_wl(self, image): | 831 | def do_ww_wl(self, image): |
| 819 | - colorer = vtk.vtkImageMapToWindowLevelColors() | ||
| 820 | - colorer.SetInput(image) | ||
| 821 | - colorer.SetWindow(self.window_width) | ||
| 822 | - colorer.SetLevel(self.window_level) | ||
| 823 | - colorer.SetOutputFormatToRGB() | ||
| 824 | - colorer.Update() | 832 | + if self.from_plist: |
| 833 | + lut = vtk.vtkWindowLevelLookupTable() | ||
| 834 | + lut.SetWindow(self.window_width) | ||
| 835 | + lut.SetLevel(self.window_level) | ||
| 836 | + lut.Build() | ||
| 837 | + | ||
| 838 | + i = 0 | ||
| 839 | + for r, g, b in self.values: | ||
| 840 | + lut.SetTableValue(i, r/255.0, g/255.0, b/255.0, 1.0) | ||
| 841 | + i += 1 | ||
| 842 | + | ||
| 843 | + print i, r, g, b | ||
| 844 | + | ||
| 845 | + colorer = vtk.vtkImageMapToColors() | ||
| 846 | + colorer.SetInput(image) | ||
| 847 | + colorer.SetLookupTable(lut) | ||
| 848 | + colorer.SetOutputFormatToRGB() | ||
| 849 | + colorer.Update() | ||
| 850 | + else: | ||
| 851 | + colorer = vtk.vtkImageMapToWindowLevelColors() | ||
| 852 | + colorer.SetInput(image) | ||
| 853 | + colorer.SetWindow(self.window_width) | ||
| 854 | + colorer.SetLevel(self.window_level) | ||
| 855 | + colorer.SetOutputFormatToRGB() | ||
| 856 | + colorer.Update() | ||
| 825 | 857 | ||
| 826 | return colorer.GetOutput() | 858 | return colorer.GetOutput() |
| 827 | 859 | ||
| @@ -837,22 +869,25 @@ class Slice(object): | @@ -837,22 +869,25 @@ class Slice(object): | ||
| 837 | return m.astype('uint8') | 869 | return m.astype('uint8') |
| 838 | 870 | ||
| 839 | def do_colour_image(self, imagedata): | 871 | def do_colour_image(self, imagedata): |
| 840 | - # map scalar values into colors | ||
| 841 | - lut_bg = vtk.vtkLookupTable() | ||
| 842 | - lut_bg.SetTableRange(imagedata.GetScalarRange()) | ||
| 843 | - lut_bg.SetSaturationRange(self.saturation_range) | ||
| 844 | - lut_bg.SetHueRange(self.hue_range) | ||
| 845 | - lut_bg.SetValueRange(self.value_range) | ||
| 846 | - lut_bg.Build() | ||
| 847 | - | ||
| 848 | - # map the input image through a lookup table | ||
| 849 | - img_colours_bg = vtk.vtkImageMapToColors() | ||
| 850 | - img_colours_bg.SetOutputFormatToRGB() | ||
| 851 | - img_colours_bg.SetLookupTable(lut_bg) | ||
| 852 | - img_colours_bg.SetInput(imagedata) | ||
| 853 | - img_colours_bg.Update() | ||
| 854 | - | ||
| 855 | - return img_colours_bg.GetOutput() | 872 | + if self.from_plist: |
| 873 | + return imagedata | ||
| 874 | + else: | ||
| 875 | + # map scalar values into colors | ||
| 876 | + lut_bg = vtk.vtkLookupTable() | ||
| 877 | + lut_bg.SetTableRange(imagedata.GetScalarRange()) | ||
| 878 | + lut_bg.SetSaturationRange(self.saturation_range) | ||
| 879 | + lut_bg.SetHueRange(self.hue_range) | ||
| 880 | + lut_bg.SetValueRange(self.value_range) | ||
| 881 | + lut_bg.Build() | ||
| 882 | + | ||
| 883 | + # map the input image through a lookup table | ||
| 884 | + img_colours_bg = vtk.vtkImageMapToColors() | ||
| 885 | + img_colours_bg.SetOutputFormatToRGB() | ||
| 886 | + img_colours_bg.SetLookupTable(lut_bg) | ||
| 887 | + img_colours_bg.SetInput(imagedata) | ||
| 888 | + img_colours_bg.Update() | ||
| 889 | + | ||
| 890 | + return img_colours_bg.GetOutput() | ||
| 856 | 891 | ||
| 857 | def do_colour_mask(self, imagedata): | 892 | def do_colour_mask(self, imagedata): |
| 858 | scalar_range = int(imagedata.GetScalarRange()[1]) | 893 | scalar_range = int(imagedata.GetScalarRange()[1]) |
invesalius/gui/widgets/slice_menu.py
| @@ -24,6 +24,7 @@ import sys | @@ -24,6 +24,7 @@ import sys | ||
| 24 | import wx | 24 | import wx |
| 25 | from wx.lib.pubsub import pub as Publisher | 25 | from wx.lib.pubsub import pub as Publisher |
| 26 | import constants as const | 26 | import constants as const |
| 27 | +import presets | ||
| 27 | 28 | ||
| 28 | class SliceMenu(wx.Menu): | 29 | class SliceMenu(wx.Menu): |
| 29 | def __init__(self): | 30 | def __init__(self): |
| @@ -56,6 +57,7 @@ class SliceMenu(wx.Menu): | @@ -56,6 +57,7 @@ class SliceMenu(wx.Menu): | ||
| 56 | self.ID_TO_TOOL_ITEM[new_id] = wl_item | 57 | self.ID_TO_TOOL_ITEM[new_id] = wl_item |
| 57 | 58 | ||
| 58 | 59 | ||
| 60 | + | ||
| 59 | #----------- Sub menu of the save and load options --------- | 61 | #----------- Sub menu of the save and load options --------- |
| 60 | #submenu_wl.AppendSeparator() | 62 | #submenu_wl.AppendSeparator() |
| 61 | #options = [_("Save current values"), | 63 | #options = [_("Save current values"), |
| @@ -84,6 +86,13 @@ class SliceMenu(wx.Menu): | @@ -84,6 +86,13 @@ class SliceMenu(wx.Menu): | ||
| 84 | name, kind=wx.ITEM_RADIO) | 86 | name, kind=wx.ITEM_RADIO) |
| 85 | submenu_pseudo_colours.AppendItem(color_item) | 87 | submenu_pseudo_colours.AppendItem(color_item) |
| 86 | self.ID_TO_TOOL_ITEM[new_id] = color_item | 88 | self.ID_TO_TOOL_ITEM[new_id] = color_item |
| 89 | + | ||
| 90 | + self.plist_presets = presets.get_wwwl_presets() | ||
| 91 | + for name in sorted(self.plist_presets): | ||
| 92 | + new_id = wx.NewId() | ||
| 93 | + color_item = wx.MenuItem(submenu_wl, new_id, name, kind=wx.ITEM_RADIO) | ||
| 94 | + submenu_pseudo_colours.AppendItem(color_item) | ||
| 95 | + self.ID_TO_TOOL_ITEM[new_id] = color_item | ||
| 87 | 96 | ||
| 88 | flag_tiling = False | 97 | flag_tiling = False |
| 89 | #------------ Sub menu of the image tiling --------------- | 98 | #------------ Sub menu of the image tiling --------------- |
| @@ -160,6 +169,11 @@ class SliceMenu(wx.Menu): | @@ -160,6 +169,11 @@ class SliceMenu(wx.Menu): | ||
| 160 | Publisher.sendMessage('Change colour table from background image', values) | 169 | Publisher.sendMessage('Change colour table from background image', values) |
| 161 | Publisher.sendMessage('Update slice viewer') | 170 | Publisher.sendMessage('Update slice viewer') |
| 162 | 171 | ||
| 172 | + elif key in self.plist_presets: | ||
| 173 | + values = presets.get_wwwl_preset_colours(self.plist_presets[key]) | ||
| 174 | + Publisher.sendMessage('Change colour table from background image from plist', values) | ||
| 175 | + Publisher.sendMessage('Update slice viewer') | ||
| 176 | + | ||
| 163 | elif(key in const.IMAGE_TILING.keys()): | 177 | elif(key in const.IMAGE_TILING.keys()): |
| 164 | print "c" | 178 | print "c" |
| 165 | values = const.IMAGE_TILING[key] | 179 | values = const.IMAGE_TILING[key] |
invesalius/presets.py
| @@ -16,9 +16,12 @@ | @@ -16,9 +16,12 @@ | ||
| 16 | # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | 16 | # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais |
| 17 | # detalhes. | 17 | # detalhes. |
| 18 | #-------------------------------------------------------------------------- | 18 | #-------------------------------------------------------------------------- |
| 19 | +import glob | ||
| 19 | import os | 20 | import os |
| 20 | import plistlib | 21 | import plistlib |
| 21 | 22 | ||
| 23 | +import constants as const | ||
| 24 | + | ||
| 22 | from wx.lib.pubsub import pub as Publisher | 25 | from wx.lib.pubsub import pub as Publisher |
| 23 | 26 | ||
| 24 | from utils import TwoWaysDictionary | 27 | from utils import TwoWaysDictionary |
| @@ -164,3 +167,25 @@ class Presets(): | @@ -164,3 +167,25 @@ class Presets(): | ||
| 164 | self.thresh_ct = TwoWaysDictionary(thresh_ct_new) | 167 | self.thresh_ct = TwoWaysDictionary(thresh_ct_new) |
| 165 | 168 | ||
| 166 | 169 | ||
| 170 | + | ||
| 171 | +def get_wwwl_presets(): | ||
| 172 | + files = glob.glob(os.path.join('..', 'presets', 'raycasting', 'color_list', '*.plist')) | ||
| 173 | + presets = {} | ||
| 174 | + for f in files: | ||
| 175 | + p = os.path.splitext(os.path.basename(f))[0] | ||
| 176 | + presets[p] = f | ||
| 177 | + return presets | ||
| 178 | + | ||
| 179 | + | ||
| 180 | +def get_wwwl_preset_colours(pfile): | ||
| 181 | + preset = plistlib.readPlist(pfile) | ||
| 182 | + ncolours = len(preset['Blue']) | ||
| 183 | + colours = [] | ||
| 184 | + for i in xrange(ncolours): | ||
| 185 | + r = preset['Red'][i] | ||
| 186 | + g = preset['Green'][i] | ||
| 187 | + b = preset['Blue'][i] | ||
| 188 | + | ||
| 189 | + colours.append((r, g, b)) | ||
| 190 | + | ||
| 191 | + return colours |