diff --git a/invesalius/control.py b/invesalius/control.py index a07219f..3f3b7fc 100755 --- a/invesalius/control.py +++ b/invesalius/control.py @@ -27,6 +27,7 @@ import constants as const import data.imagedata_utils as utils import data.mask as msk import data.measures +import data.slice_ as sl import data.surface as srf import data.volume as volume import gui.dialogs as dialog @@ -76,7 +77,6 @@ class Controller(): ps.Publisher().subscribe(self.OnOpenProject, 'Open project') ps.Publisher().subscribe(self.OnOpenRecentProject, 'Open recent project') ps.Publisher().subscribe(self.OnShowAnalyzeFile, 'Show analyze dialog') - def OnCancelImport(self, pubsub_evt): #self.cancel_import = True @@ -466,6 +466,10 @@ class Controller(): tilt_value = -1*tilt_value imagedata = utils.FixGantryTilt(imagedata, tilt_value) + self.matrix, self.filename = utils.dcm2memmap(filelist, size) + self.Slice = sl.Slice() + self.Slice.matrix = self.matrix + self.Slice.spacing = xyspacing[0], xyspacing[1], zspacing return imagedata, dicom def LoadImagedataInfo(self): @@ -524,7 +528,3 @@ class Controller(): preset_name + '.plist') plistlib.writePlist(preset, preset_dir) - - - - diff --git a/invesalius/data/imagedata_utils.py b/invesalius/data/imagedata_utils.py index 4fbd16d..25aa664 100644 --- a/invesalius/data/imagedata_utils.py +++ b/invesalius/data/imagedata_utils.py @@ -478,7 +478,7 @@ def get_numpy_array_type(gdcm_pixel_format): def dcm2memmap(files, slice_size): """ From a list of dicom files it creates memmap file in the temp folder and - returns. + returns it and its related filename. """ temp_file = tempfile.mktemp() shape = len(files), slice_size[0], slice_size[1] @@ -498,3 +498,30 @@ def dcm2memmap(files, slice_size): array = numpy.frombuffer(dcm_array, dtype) array.shape = slice_size matrix[n] = array + + matrix.flush() + return matrix, temp_file + +def to_vtk(n_array, spacing): + dy, dx = n_array.shape + n_array.shape = dx * dy + + v_image = numpy_support.numpy_to_vtk(n_array) + + # Generating the vtkImageData + image = vtk.vtkImageData() + image.SetDimensions(dx, dy, 1) + image.SetOrigin(0, 0, 0) + image.SetSpacing(spacing) + image.SetNumberOfScalarComponents(1) + image.SetExtent(0, dx -1, 0, dy -1, 0, 0) + image.SetScalarType(numpy_support.get_vtk_array_type(n_array.dtype)) + image.AllocateScalars() + image.GetPointData().SetScalars(v_image) + image.Update() + + image_copy = vtk.vtkImageData() + image_copy.DeepCopy(image) + image_copy.Update() + + return image_copy diff --git a/invesalius/data/slice_.py b/invesalius/data/slice_.py index 0d76854..6b8b798 100644 --- a/invesalius/data/slice_.py +++ b/invesalius/data/slice_.py @@ -16,6 +16,7 @@ # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais # detalhes. #-------------------------------------------------------------------------- +import numpy import vtk import wx.lib.pubsub as ps @@ -38,6 +39,7 @@ class Slice(object): self.imagedata = None self.current_mask = None self.blend_filter = None + self.matrix = None self.num_gradient = 0 self.interaction_style = st.StyleStateManager() @@ -234,6 +236,28 @@ class Slice(object): # END PUBSUB_EVT METHODS #--------------------------------------------------------------------------- + def GetSlices(self, orientation, slice_number): + if orientation == 'AXIAL': + n_array = numpy.array(self.matrix[slice_number]) + spacing = self.spacing + elif orientation == 'CORONAL': + n_array = numpy.array(self.matrix[..., slice_number, ...]) + spacing = self.spacing[0], self.spacing[2], self.spacing[1] + elif orientation == 'SAGITAL': + n_array = numpy.array(self.matrix[..., ..., slice_number]) + spacing = self.spacing[1], self.spacing[2], self.spacing[0] + + image = iu.to_vtk(n_array, spacing) + image = self.do_ww_wl(image) + return image + + def GetNumberOfSlices(self, orientation): + if orientation == 'AXIAL': + return self.matrix.shape[0] + elif orientation == 'CORONAL': + return self.matrix.shape[1] + elif orientation == 'SAGITAL': + return self.matrix.shape[2] def SetMaskColour(self, index, colour, update=True): "Set a mask colour given its index and colour (RGB 0-1 values)" @@ -448,8 +472,6 @@ class Slice(object): self.window_level.SetInput(self.imagedata) def __create_background(self, imagedata): - self.imagedata = imagedata - thresh_min, thresh_max = imagedata.GetScalarRange() ps.Publisher().sendMessage('Update threshold limits list', (thresh_min, thresh_max)) @@ -471,21 +493,21 @@ class Slice(object): return img_colours_bg.GetOutput() def UpdateWindowLevelBackground(self, pubsub_evt): + pass + #window, level = pubsub_evt.data + #window_level = self.window_level - window, level = pubsub_evt.data - window_level = self.window_level - - if not((window == window_level.GetWindow()) and\ - (level == window_level.GetLevel())): + #if not((window == window_level.GetWindow()) and\ + #(level == window_level.GetLevel())): - window_level.SetWindow(window) - window_level.SetLevel(level) - window_level.SetOutputFormatToLuminance() - window_level.Update() + #window_level.SetWindow(window) + #window_level.SetLevel(level) + #window_level.SetOutputFormatToLuminance() + #window_level.Update() - thresh_min, thresh_max = window_level.GetOutput().GetScalarRange() - self.lut_bg.SetTableRange(thresh_min, thresh_max) - self.img_colours_bg.SetInput(window_level.GetOutput()) + #thresh_min, thresh_max = window_level.GetOutput().GetScalarRange() + #self.lut_bg.SetTableRange(thresh_min, thresh_max) + #self.img_colours_bg.SetInput(window_level.GetOutput()) def UpdateColourTableBackground(self, pubsub_evt): values = pubsub_evt.data @@ -502,15 +524,16 @@ class Slice(object): def InputImageWidget(self, pubsub_evt): - widget = pubsub_evt.data + #widget = pubsub_evt.data - flip = vtk.vtkImageFlip() - flip.SetInput(self.window_level.GetOutput()) - flip.SetFilteredAxis(1) - flip.FlipAboutOriginOn() - flip.Update() + #flip = vtk.vtkImageFlip() + #flip.SetInput(self.window_level.GetOutput()) + #flip.SetFilteredAxis(1) + #flip.FlipAboutOriginOn() + #flip.Update() - widget.SetInput(flip.GetOutput()) + #widget.SetInput(flip.GetOutput()) + pass def CreateMask(self, imagedata=None, name=None, colour=None, @@ -595,6 +618,16 @@ class Slice(object): ps.Publisher().sendMessage('Change mask selected', mask.index) ps.Publisher().sendMessage('Update slice viewer') + def do_ww_wl(self, image): + colorer = vtk.vtkImageMapToWindowLevelColors() + colorer.SetInput(image) + colorer.SetWindow(255) + colorer.SetLevel(127) + colorer.SetOutputFormatToRGBA() + colorer.Update() + + return colorer.GetOutput() + def __build_mask(self, imagedata, create=True): # create new mask instance and insert it into project if create: diff --git a/invesalius/data/viewer_slice.py b/invesalius/data/viewer_slice.py index 0183457..37e6353 100755 --- a/invesalius/data/viewer_slice.py +++ b/invesalius/data/viewer_slice.py @@ -88,7 +88,7 @@ class Viewer(wx.Panel): self.on_wl = False self.on_text = False # VTK pipeline and actors - #self.__config_interactor() + self.__config_interactor() self.pick = vtk.vtkPropPicker() self.cross_actor = vtk.vtkActor() @@ -102,7 +102,6 @@ class Viewer(wx.Panel): scroll = wx.ScrollBar(self, -1, style=wx.SB_VERTICAL) self.scroll = scroll - sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(interactor, 1, wx.EXPAND|wx.GROW) @@ -164,10 +163,11 @@ class Viewer(wx.Panel): self.SetLayout(layout) def __config_interactor(self): - ren = vtk.vtkRenderer() + style = vtk.vtkInteractorStyleImage() interactor = self.interactor + interactor.SetInteractorStyle(style) interactor.GetRenderWindow().AddRenderer(ren) self.cam = ren.GetActiveCamera() @@ -1056,48 +1056,50 @@ class Viewer(wx.Panel): return cursor def SetInput(self, imagedata, mask_dict): - self.imagedata = imagedata + pass + #self.imagedata = imagedata - #ren = self.ren - interactor = self.interactor + ##ren = self.ren + #interactor = self.interactor - # Slice pipeline, to be inserted into current viewer - slice_ = sl.Slice() - if slice_.imagedata is None: - slice_.SetInput(imagedata, mask_dict) + ## Slice pipeline, to be inserted into current viewer + #slice_ = sl.Slice() + #if slice_.imagedata is None: + #slice_.SetInput(imagedata, mask_dict) - #actor = vtk.vtkImageActor() - #actor.SetInput(slice_.GetOutput()) - self.LoadRenderers(slice_.GetOutput()) - self.__configure_renderers() - ren = self.slice_data_list[0].renderer - actor = self.slice_data_list[0].actor - actor_bound = actor.GetBounds() + actor = vtk.vtkImageActor() + ##actor.SetInput(slice_.GetOutput()) + #self.LoadRenderers(slice_.GetOutput()) + #self.__configure_renderers() + #ren = self.slice_data_list[0].renderer + #actor = self.slice_data_list[0].actor + #actor_bound = actor.GetBounds() self.actor = actor - self.ren = ren - self.cam = ren.GetActiveCamera() + self.ren.AddActor(self.actor) + #self.cam = ren.GetActiveCamera() - for slice_data in self.slice_data_list: - self.__update_camera(slice_data) - self.Reposition(slice_data) + #for slice_data in self.slice_data_list: + #self.__update_camera(slice_data) + #self.Reposition(slice_data) - number_of_slices = self.layout[0] * self.layout[1] - max_slice_number = actor.GetSliceNumberMax() + 1/ \ - number_of_slices + #number_of_slices = self.layout[0] * self.layout[1] + #max_slice_number = actor.GetSliceNumberMax() + 1/ \ + #number_of_slices - if actor.GetSliceNumberMax() % number_of_slices: - max_slice_number += 1 + #if actor.GetSliceNumberMax() % number_of_slices: + #max_slice_number += 1 + max_slice_number = sl.Slice().GetNumberOfSlices(self.orientation) self.scroll.SetScrollbar(wx.SB_VERTICAL, 1, max_slice_number, max_slice_number) - self.set_scroll_position(0) + #self.set_scroll_position(0) - actor_bound = actor.GetBounds() + #actor_bound = actor.GetBounds() - self.EnableText() - # Insert cursor - self.SetInteractorStyle(const.STATE_DEFAULT) + #self.EnableText() + ## Insert cursor + #self.SetInteractorStyle(const.STATE_DEFAULT) - self.__build_cross_lines() + #self.__build_cross_lines() def __build_cross_lines(self): actor = self.slice_data_list[0].actor @@ -1339,15 +1341,21 @@ class Viewer(wx.Panel): def OnScrollBar(self, evt=None): pos = self.scroll.GetThumbPosition() - self.set_slice_number(pos) - #self.UpdateSlice3D(pos) - self.pos = pos + slice_ = sl.Slice() + image = slice_.GetSlices(self.orientation, pos) + self.actor.SetInput(image) + self.ren.ResetCamera() self.interactor.Render() - if evt: - evt.Skip() + print "slice", pos + #self.set_slice_number(pos) + ##self.UpdateSlice3D(pos) + #self.pos = pos + #self.interactor.Render() + #if evt: + #evt.Skip() def OnScrollBarRelease(self, evt): - self.UpdateSlice3D(self.pos) + #self.UpdateSlice3D(self.pos) evt.Skip() def OnKeyDown(self, evt=None, obj=None): -- libgit2 0.21.2