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 |