From c00a783831e9e39f2d8e3a4b0fa9a7d4c5df5b92 Mon Sep 17 00:00:00 2001 From: ruppert Date: Thu, 23 Dec 2010 18:31:03 +0000 Subject: [PATCH] Added image processing tools (with ift library) --- .gitattributes | 14 ++++++++++++++ invesalius/constants.py | 12 +++++++++++- invesalius/control.py | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- invesalius/gui/dialogs.py | 28 ++++++++++++++++++++++++++++ invesalius/gui/frame.py | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- invesalius/gui/task_importer.py | 27 +++++++++++++++++++++++++-- invesalius/libc/__init__.py | 18 ++++++++++++++++++ invesalius/libc/libalign/__init__.py | 18 ++++++++++++++++++ invesalius/libc/libalign/libalign.py | 19 +++++++++++++++++++ invesalius/libc/libift/Makefile | 25 +++++++++++++++++++++++++ invesalius/libc/libift/__init__.py | 18 ++++++++++++++++++ invesalius/libc/libift/libift.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ invesalius/libc/libift/libift.i | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ invesalius/libc/libift/makefile.vc | 37 +++++++++++++++++++++++++++++++++++++ invesalius/libc/libscnvtk/Makefile | 24 ++++++++++++++++++++++++ invesalius/libc/libscnvtk/__init__.py | 18 ++++++++++++++++++ invesalius/libc/libscnvtk/libscnvtk.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ invesalius/libc/libscnvtk/makefile.vc | 36 ++++++++++++++++++++++++++++++++++++ invesalius/libc/libscnvtk/scnvtk.cxx | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ invesalius/libc/libscnvtk/scnvtk.i | 33 +++++++++++++++++++++++++++++++++ 20 files changed, 1032 insertions(+), 18 deletions(-) create mode 100644 invesalius/libc/__init__.py create mode 100644 invesalius/libc/libalign/__init__.py create mode 100644 invesalius/libc/libalign/libalign.py create mode 100644 invesalius/libc/libift/Makefile create mode 100644 invesalius/libc/libift/__init__.py create mode 100644 invesalius/libc/libift/libift.c create mode 100644 invesalius/libc/libift/libift.i create mode 100644 invesalius/libc/libift/makefile.vc create mode 100644 invesalius/libc/libscnvtk/Makefile create mode 100644 invesalius/libc/libscnvtk/__init__.py create mode 100644 invesalius/libc/libscnvtk/libscnvtk.py create mode 100644 invesalius/libc/libscnvtk/makefile.vc create mode 100644 invesalius/libc/libscnvtk/scnvtk.cxx create mode 100644 invesalius/libc/libscnvtk/scnvtk.i diff --git a/.gitattributes b/.gitattributes index 9a59e4e..0ba1fd0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -154,6 +154,20 @@ icons/zh_TW.bmp -text invesalius/.svnignore -text invesalius/data/bases.py -text invesalius/data/co_registration.py -text +invesalius/libc/__init__.py -text +invesalius/libc/libalign/__init__.py -text +invesalius/libc/libalign/libalign.py -text +invesalius/libc/libift/Makefile -text +invesalius/libc/libift/__init__.py -text +invesalius/libc/libift/libift.c -text +invesalius/libc/libift/libift.i -text +invesalius/libc/libift/makefile.vc -text +invesalius/libc/libscnvtk/Makefile -text +invesalius/libc/libscnvtk/__init__.py -text +invesalius/libc/libscnvtk/libscnvtk.py -text +invesalius/libc/libscnvtk/makefile.vc -text +invesalius/libc/libscnvtk/scnvtk.cxx -text +invesalius/libc/libscnvtk/scnvtk.i -text locale/de/LC_MESSAGES/invesalius.mo -text locale/el/LC_MESSAGES/invesalius.mo -text locale/en/LC_MESSAGES/invesalius.mo -text diff --git a/invesalius/constants.py b/invesalius/constants.py index a613600..a199634 100644 --- a/invesalius/constants.py +++ b/invesalius/constants.py @@ -430,7 +430,16 @@ VTK_WARNING = 0 [ID_DICOM_IMPORT, ID_PROJECT_OPEN, ID_PROJECT_SAVE_AS, ID_PROJECT_SAVE, ID_PROJECT_CLOSE, ID_PROJECT_INFO, ID_SAVE_SCREENSHOT, ID_DICOM_LOAD_NET, -ID_PRINT_SCREENSHOT, ID_EXIT, ID_IMPORT_OTHERS_FILES, ID_ANALYZE_IMPORT] = [wx.NewId() for number in range(12)] +ID_ALIGN, ID_PRINT_SCREENSHOT, ID_EXIT, ID_IMPORT_OTHERS_FILES, ID_EXPORT_OTHERS_FILES, ID_ANALYZE_IMPORT, ID_ANALYZE_EXPORT] = [wx.NewId() for number in range(15)] + +ID_GAUSSIAN = wx.NewId() +ID_MEDIAN = wx.NewId() +ID_MODE = wx.NewId() +ID_SOBEL = wx.NewId() +ID_HISTEQ = wx.NewId() +ID_INTERP = wx.NewId() +ID_ERASEBG = wx.NewId() +ID_ERASESUP = wx.NewId() [ID_EDIT_UNDO, ID_EDIT_REDO, ID_EDIT_LIST] =\ @@ -493,3 +502,4 @@ STYLE_LEVEL = {SLICE_STATE_EDITOR: 1, STATE_ZOOM_SL: 2, STATE_PAN:2, VOLUME_STATE_SEED:1} + diff --git a/invesalius/control.py b/invesalius/control.py index a07219f..44354c5 100755 --- a/invesalius/control.py +++ b/invesalius/control.py @@ -35,6 +35,9 @@ import reader.analyze_reader as analyze import reader.dicom_grouper as dg import reader.dicom_reader as dcm import session as ses +import libc.libalign.libalign as libalign +import libc.libift.libift as libift +import libc.libscnvtk.libscnvtk as libscnvtk from utils import debug @@ -63,6 +66,16 @@ class Controller(): ps.Publisher().subscribe(self.OnShowDialogSaveProject, 'Show save dialog') + ps.Publisher().subscribe(self.OnAlignVolume, 'Align volume') + ps.Publisher().subscribe(self.Tools_Gaussian, 'Tools gaussian') + ps.Publisher().subscribe(self.Tools_Median, 'Tools median') + ps.Publisher().subscribe(self.Tools_Mode, 'Tools mode') + ps.Publisher().subscribe(self.Tools_Sobel, 'Tools sobel') + ps.Publisher().subscribe(self.Tools_EraseBackground, 'Tools erase background') + ps.Publisher().subscribe(self.Tools_EraseSupport, 'Tools erase support') + ps.Publisher().subscribe(self.Tools_HistogramEqualization, 'Tools histogram equalization') + ps.Publisher().subscribe(self.Tools_Interpolation, 'Tools interpolation') + ps.Publisher().subscribe(self.LoadRaycastingPreset, 'Load raycasting preset') ps.Publisher().subscribe(self.SaveRaycastingPreset, @@ -75,7 +88,8 @@ class Controller(): ps.Publisher().subscribe(self.OnShowDialogCloseProject, 'Close Project') ps.Publisher().subscribe(self.OnOpenProject, 'Open project') ps.Publisher().subscribe(self.OnOpenRecentProject, 'Open recent project') - ps.Publisher().subscribe(self.OnShowAnalyzeFile, 'Show analyze dialog') + ps.Publisher().subscribe(self.OnShowImportAnalyzeFile, 'Show analyze import dialog') + ps.Publisher().subscribe(self.OnShowExportAnalyzeFile, 'Show analyze export dialog') def OnCancelImport(self, pubsub_evt): @@ -84,11 +98,146 @@ class Controller(): ########################### + + def OnAlignVolume(self, pubsub_evt): + #bi = wx.BusyInfo("Working, please wait...", self) + proj = prj.Project() + newimg = libalign.VolumeAlign(proj.imagedata) + #bi.Destroy() + self.CloseProject() + self.CreateAnalyzeProject(newimg) + self.LoadProject() + ps.Publisher().sendMessage("Enable state project", True) + + +########################### + + def Tools_Gaussian(self, pubsub_evt): + print "Running gaussian smoothing..." + adj=libift.Spheric(2) + kernel = libift.GaussianKernel3(adj,2) + kernel2 = libift.NormalizeKernel3(kernel) + scn = libscnvtk.VtkImageDataToScene(prj.Project().imagedata) + flag=libift.ShiftScene(scn) + scn2 = libift.LinearFilter3(scn,kernel2) + libift.NewDestroyScene(scn) + libift.UnShiftScene(scn2,flag) + newimg = libscnvtk.SceneToVtkImageData(scn2) + libift.NewDestroyScene(scn2) + self.CloseProject() + self.CreateAnalyzeProject(newimg) + self.LoadProject() + ps.Publisher().sendMessage("Enable state project", True) + + def Tools_Median(self, pubsub_evt): + print "Running median filter..." + adj=libift.Spheric(2) + scn = libscnvtk.VtkImageDataToScene(prj.Project().imagedata) + flag=libift.ShiftScene(scn) + scn2 = libift.MedianFilter3(scn,adj) + libift.NewDestroyScene(scn) + libift.UnShiftScene(scn2,flag) + newimg = libscnvtk.SceneToVtkImageData(scn2) + libift.NewDestroyScene(scn2) + self.CloseProject() + self.CreateAnalyzeProject(newimg) + self.LoadProject() + ps.Publisher().sendMessage("Enable state project", True) + + def Tools_Mode(self, pubsub_evt): + print "Running mode filter..." + adj=libift.Spheric(2) + scn = libscnvtk.VtkImageDataToScene(prj.Project().imagedata) + flag=libift.ShiftScene(scn) + scn2 = libift.ModeFilter3(scn,adj) + libift.NewDestroyScene(scn) + libift.UnShiftScene(scn2,flag) + newimg = libscnvtk.SceneToVtkImageData(scn2) + libift.NewDestroyScene(scn2) + self.CloseProject() + self.CreateAnalyzeProject(newimg) + self.LoadProject() + ps.Publisher().sendMessage("Enable state project", True) + + def Tools_Sobel(self, pubsub_evt): + print "Running sobel filter..." + scn = libscnvtk.VtkImageDataToScene(prj.Project().imagedata) + flag=libift.ShiftScene(scn) + scn2 = libift.SobelFilter3(scn) + libift.NewDestroyScene(scn) + libift.UnShiftScene(scn2,flag) + newimg = libscnvtk.SceneToVtkImageData(scn2) + libift.NewDestroyScene(scn2) + self.CloseProject() + self.CreateAnalyzeProject(newimg) + self.LoadProject() + ps.Publisher().sendMessage("Enable state project", True) + + def Tools_EraseBackground(self, pubsub_evt): + print "Running erase background..." + scn = libscnvtk.VtkImageDataToScene(prj.Project().imagedata) + flag=libift.ShiftScene(scn) + scn2 = libift.EraseBackground(scn) + libift.NewDestroyScene(scn) + libift.UnShiftScene(scn2,flag) + newimg = libscnvtk.SceneToVtkImageData(scn2) + libift.NewDestroyScene(scn2) + self.CloseProject() + self.CreateAnalyzeProject(newimg) + self.LoadProject() + ps.Publisher().sendMessage("Enable state project", True) + + def Tools_EraseSupport(self, pubsub_evt): + print "Running erase support..." + scn = libscnvtk.VtkImageDataToScene(prj.Project().imagedata) + flag=libift.ShiftScene(scn) + scn2 = libift.EraseSupport(scn) + libift.NewDestroyScene(scn) + libift.UnShiftScene(scn2,flag) + newimg = libscnvtk.SceneToVtkImageData(scn2) + libift.NewDestroyScene(scn2) + self.CloseProject() + self.CreateAnalyzeProject(newimg) + self.LoadProject() + ps.Publisher().sendMessage("Enable state project", True) + + def Tools_HistogramEqualization(self, pubsub_evt): + print "Running histogram equalization..." + scn = libscnvtk.VtkImageDataToScene(prj.Project().imagedata) + flag=libift.ShiftScene(scn) + scn2 = libift.Equalize3(scn,4095) + libift.NewDestroyScene(scn) + libift.UnShiftScene(scn2,flag) + newimg = libscnvtk.SceneToVtkImageData(scn2) + libift.NewDestroyScene(scn2) + self.CloseProject() + self.CreateAnalyzeProject(newimg) + self.LoadProject() + ps.Publisher().sendMessage("Enable state project", True) + + def Tools_Interpolation(self, pubsub_evt): + print "Running histogram equalization..." + scn = libscnvtk.VtkImageDataToScene(prj.Project().imagedata) + scn2 = libift.LinearInterp(scn,0,0,0) + libift.NewDestroyScene(scn) + newimg = libscnvtk.SceneToVtkImageData(scn2) + libift.NewDestroyScene(scn2) + self.CloseProject() + self.CreateAnalyzeProject(newimg) + self.LoadProject() + ps.Publisher().sendMessage("Enable state project", True) + + + +########################### ########################### def OnShowDialogImportDirectory(self, pubsub_evt): self.ShowDialogImportDirectory() + # def OnShowDialogImportAnalyze(self, pubsub_evt): + # self.ShowDialogImportAnalyze() + def OnShowDialogOpenProject(self, pubsub_evt): self.ShowDialogOpenProject() @@ -99,15 +248,24 @@ class Controller(): def OnShowDialogCloseProject(self, pubsub_evt): self.ShowDialogCloseProject() - def OnShowAnalyzeFile(self, pubsub_evt): + def OnShowImportAnalyzeFile(self, pubsub_evt): dirpath = dialog.ShowOpenAnalyzeDialog() imagedata = analyze.ReadAnalyze(dirpath) if imagedata: self.CreateAnalyzeProject(imagedata) - self.LoadProject() ps.Publisher().sendMessage("Enable state project", True) + def OnShowExportAnalyzeFile(self, pubsub_evt): + dirpath = dialog.ShowSaveAnalyzeDialog() + proj = prj.Project() + name=dirpath.encode('utf-8') + libalign.libscnvtk.WriteVtkImageData(proj.imagedata,name) + wx.MessageBox(_("Written successfully!"), 'Info') + + + + ########################### @@ -127,7 +285,8 @@ class Controller(): dialog.ImportEmptyDirectory(dirpath) elif dirpath: self.StartImportPanel(dirpath) - ps.Publisher().sendMessage("Load data to import panel", dirpath) + #ps.Publisher().sendMessage("Load data to import panel", dirpath) + def ShowDialogOpenProject(self): # Offer to save current project if necessary diff --git a/invesalius/gui/dialogs.py b/invesalius/gui/dialogs.py index a7eed07..56046b6 100644 --- a/invesalius/gui/dialogs.py +++ b/invesalius/gui/dialogs.py @@ -192,6 +192,34 @@ def ShowOpenAnalyzeDialog(): os.chdir(current_dir) return filepath +def ShowSaveAnalyzeDialog(): + # Default system path + current_dir = os.path.abspath(".") + dlg = wx.FileDialog(None, message=_("Export Analyze File..."), + defaultDir="", + defaultFile="", wildcard=WILDCARD_ANALYZE, + style=wx.SAVE|wx.CHANGE_DIR) + + # inv3 filter is default + dlg.SetFilterIndex(0) + + # Show the dialog and retrieve the user response. If it is the OK response, + # process the data. + filepath = None + try: + if dlg.ShowModal() == wx.ID_OK: + # This returns a Python list of files that were selected. + filepath = dlg.GetPath() + except(wx._core.PyAssertionError): #FIX: win64 + filepath = dlg.GetPath() + + # Destroy the dialog. Don't do this until you are done with it! + # BAD things can happen otherwise! + dlg.Destroy() + os.chdir(current_dir) + return filepath + + def ShowImportDirDialog(): current_dir = os.path.abspath(".") diff --git a/invesalius/gui/frame.py b/invesalius/gui/frame.py index 8e1e2e8..486d319 100755 --- a/invesalius/gui/frame.py +++ b/invesalius/gui/frame.py @@ -145,11 +145,13 @@ class Frame(wx.Frame): t2 = LayoutToolBar(self) t3 = ObjectToolBar(self) t4 = SliceToolBar(self) + t5 = ImageProcessingToolBar(self) else: - t4 = ProjectToolBar(self) - t3 = LayoutToolBar(self) - t2 = ObjectToolBar(self) - t1 = SliceToolBar(self) + t5 = ProjectToolBar(self) + t4 = LayoutToolBar(self) + t3 = ObjectToolBar(self) + t2 = SliceToolBar(self) + t1 = ImageProcessingToolBar(self) aui_manager.AddPane(t1, wx.aui.AuiPaneInfo(). Name("General Features Toolbar"). @@ -171,6 +173,11 @@ class Frame(wx.Frame): ToolbarPane().Top().Floatable(False). LeftDockable(False).RightDockable(False)) + aui_manager.AddPane(t5, wx.aui.AuiPaneInfo(). + Name("Image Processing Toolbar"). + ToolbarPane().Top().Floatable(False). + LeftDockable(False).RightDockable(False)) + aui_manager.Update() self.aui_manager = aui_manager @@ -296,12 +303,32 @@ class Frame(wx.Frame): self.ShowOpenProject() elif id == const.ID_ANALYZE_IMPORT: self.ShowAnalyzeImporter() + elif id == const.ID_ANALYZE_EXPORT: + self.ShowAnalyzeExporter() elif id == const.ID_PROJECT_SAVE: session = ses.Session() if session.temp_item: self.ShowSaveAsProject() else: self.SaveProject() + elif id == const.ID_ALIGN: + self.AlignVolume() + elif id == const.ID_GAUSSIAN: + self.Tools_Gaussian() + elif id == const.ID_MEDIAN: + self.Tools_Median() + elif id == const.ID_MODE: + self.Tools_Mode() + elif id == const.ID_SOBEL: + self.Tools_Sobel() + elif id == const.ID_ERASEBG: + self.Tools_EraseBackground() + elif id == const.ID_ERASESUP: + self.Tools_EraseSupport() + elif id == const.ID_HISTEQ: + self.Tools_HistogramEqualization() + elif id == const.ID_INTERP: + self.Tools_Interpolation() elif id == const.ID_PROJECT_SAVE_AS: self.ShowSaveAsProject() elif id == const.ID_PROJECT_CLOSE: @@ -326,6 +353,60 @@ class Frame(wx.Frame): """ dlg.ShowAboutDialog(self) + def AlignVolume(self): + """ + Align the image. + """ + ps.Publisher().sendMessage('Align volume') + + def Tools_Gaussian(self): + """ + Gaussian Smoothing. + """ + ps.Publisher().sendMessage('Tools gaussian') + + def Tools_Median(self): + """ + Median Filter + """ + ps.Publisher().sendMessage('Tools median') + + def Tools_Mode(self): + """ + Mode Filter + """ + ps.Publisher().sendMessage('Tools mode') + + def Tools_Sobel(self): + """ + Sobel Filter + """ + ps.Publisher().sendMessage('Tools sobel') + + def Tools_EraseBackground(self): + """ + Erase background + """ + ps.Publisher().sendMessage('Tools erase background') + + def Tools_EraseSupport(self): + """ + Erase support + """ + ps.Publisher().sendMessage('Tools erase support') + + def Tools_HistogramEqualization(self): + """ + Histogram Equalization + """ + ps.Publisher().sendMessage('Tools histogram equalization') + + def Tools_Interpolation(self): + """ + Interpolation + """ + ps.Publisher().sendMessage('Tools interpolation') + def SaveProject(self): """ Save project. @@ -362,7 +443,13 @@ class Frame(wx.Frame): """ Show save as dialog. """ - ps.Publisher().sendMessage('Show analyze dialog', True) + ps.Publisher().sendMessage('Show analyze import dialog', True) + + def ShowAnalyzeExporter(self): + """ + Show save as dialog. + """ + ps.Publisher().sendMessage('Show analyze export dialog', True) # ------------------------------------------------------------------ # ------------------------------------------------------------------ @@ -406,14 +493,19 @@ class MenuBar(wx.MenuBar): # TODO: This definetely needs improvements... ;) #Import Others Files - others_file_menu = wx.Menu() - others_file_menu.Append(const.ID_ANALYZE_IMPORT, "Analyze") + others_import_file_menu = wx.Menu() + others_import_file_menu.Append(const.ID_ANALYZE_IMPORT, "Analyze") + + #Import Others Files + others_export_file_menu = wx.Menu() + others_export_file_menu.Append(const.ID_ANALYZE_EXPORT, "Analyze") # FILE file_menu = wx.Menu() app = file_menu.Append app(const.ID_DICOM_IMPORT, _("Import DICOM...\tCtrl+I")) - file_menu.AppendMenu(const.ID_IMPORT_OTHERS_FILES, _("Import Others Files"), others_file_menu) + file_menu.AppendMenu(const.ID_IMPORT_OTHERS_FILES, _("Import Other Files"), others_import_file_menu) + file_menu.AppendMenu(const.ID_EXPORT_OTHERS_FILES, _("Export Other Files"), others_export_file_menu) app(const.ID_PROJECT_OPEN, _("Open Project...\tCtrl+O")) app(const.ID_PROJECT_SAVE, _("Save Project\tCtrl+S")) app(const.ID_PROJECT_SAVE_AS, _("Save Project As...")) @@ -461,7 +553,16 @@ class MenuBar(wx.MenuBar): #app(const.ID_VIEW_3D_BACKGROUND, "3D Background Colour") # TOOLS - #tools_menu = wx.Menu() + tools_menu = wx.Menu() + tools_menu.Append(const.ID_ALIGN, _("Symmetry Alignment")) + tools_menu.Append(const.ID_GAUSSIAN, _("Gaussian Smoothing")) + tools_menu.Append(const.ID_MEDIAN, _("Median Filter")) + tools_menu.Append(const.ID_MODE, _("Mode Filter")) + tools_menu.Append(const.ID_SOBEL, _("Sobel Filter")) + tools_menu.Append(const.ID_HISTEQ, _("Histogram Equalization")) + tools_menu.Append(const.ID_INTERP, _("Isotropic Interpolation")) + tools_menu.Append(const.ID_ERASEBG, _("Erase Background")) + tools_menu.Append(const.ID_ERASESUP, _("Erase Head Support")) # OPTIONS #options_menu = wx.Menu() @@ -491,7 +592,7 @@ class MenuBar(wx.MenuBar): self.Append(file_menu, _("File")) #self.Append(file_edit, "Edit") #self.Append(view_menu, "View") - #self.Append(tools_menu, "Tools") + self.Append(tools_menu, "Tools") #self.Append(options_menu, "Options") self.Append(help_menu, _("Help")) @@ -644,6 +745,8 @@ class TaskBarIcon(wx.TaskBarIcon): def OnTaskBarActivate(self, evt): pass + + # ------------------------------------------------------------------ # ------------------------------------------------------------------ # ------------------------------------------------------------------ @@ -771,11 +874,11 @@ class ProjectToolBar(wx.ToolBar): self.EnableTool(tool, True) - # ------------------------------------------------------------------ # ------------------------------------------------------------------ # ------------------------------------------------------------------ + class ObjectToolBar(wx.ToolBar): """ Toolbar related to general object operations, including: zoom @@ -1307,3 +1410,87 @@ class LayoutToolBar(wx.ToolBar): ps.Publisher().sendMessage('Update AUI') self.ontool_text = True +# ------------------------------------------------------------------ +# ------------------------------------------------------------------ +# ------------------------------------------------------------------ + +class ImageProcessingToolBar(wx.ToolBar): + """ + Toolbar related to general project operations, including: import, + open, save and saveas, among others. + """ + def __init__(self, parent): + style = wx.TB_FLAT|wx.TB_NODIVIDER| wx.TB_DOCKABLE + wx.ToolBar.__init__(self, parent, -1, wx.DefaultPosition, + wx.DefaultSize, + style) + self.SetToolBitmapSize(wx.Size(32,32)) + + self.parent = parent + + # Used to enable/disable menu items if project is opened or + # not. Eg. save should only be available if a project is open + self.enable_items = [const.ID_ALIGN] + + self.__init_items() + self.__bind_events() + + self.Realize() + self.SetStateProjectClose() + + def __bind_events(self): + """ + Bind events related to pubsub. + """ + sub = ps.Publisher().subscribe + sub(self._EnableState, "Enable state project") + + def __init_items(self): + """ + Add tools into toolbar. + """ + # Load bitmaps + d = const.ICON_DIR + if sys.platform == 'darwin': + path = os.path.join(d, "ip_align_original.png") + BMP_SAVE = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) + else: + path = os.path.join(d, "ip_align.png") + BMP_SAVE = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) + + # Create tool items based on bitmaps + self.AddLabelTool(const.ID_ALIGN, + "", + shortHelp = _("Symmetry Alignment"), + bitmap=BMP_SAVE) + + + def _EnableState(self, pubsub_evt): + """ + Based on given state, enable or disable menu items which + depend if project is open or not. + """ + state = pubsub_evt.data + if state: + self.SetStateProjectOpen() + else: + self.SetStateProjectClose() + + def SetStateProjectClose(self): + """ + Disable menu items (e.g. save) when project is closed. + """ + for tool in self.enable_items: + self.EnableTool(tool, False) + + def SetStateProjectOpen(self): + """ + Enable menu items (e.g. save) when project is opened. + """ + for tool in self.enable_items: + self.EnableTool(tool, True) + + +# ------------------------------------------------------------------ +# ------------------------------------------------------------------ +# ------------------------------------------------------------------ diff --git a/invesalius/gui/task_importer.py b/invesalius/gui/task_importer.py index 089092e..0436a11 100644 --- a/invesalius/gui/task_importer.py +++ b/invesalius/gui/task_importer.py @@ -28,6 +28,7 @@ import constants as const import gui.dialogs as dlg BTN_IMPORT_LOCAL = wx.NewId() +#BTN_IMPORT_ANA = wx.NewId() BTN_IMPORT_PACS = wx.NewId() BTN_OPEN_PROJECT = wx.NewId() @@ -61,8 +62,8 @@ class InnerTaskPanel(wx.Panel): self.float_hyper_list = [] # Fixed hyperlink items - tooltip = wx.ToolTip(_("Select DICOM or Analyze files to be reconstructed")) - link_import_local = hl.HyperLinkCtrl(self, -1, _("Import medical images...")) + tooltip = wx.ToolTip(_("Select DICOM to be reconstructed")) + link_import_local = hl.HyperLinkCtrl(self, -1, _("Import DICOM image...")) link_import_local.SetUnderlines(False, False, False) link_import_local.SetColours("BLACK", "BLACK", "BLACK") link_import_local.SetToolTip(tooltip) @@ -70,6 +71,15 @@ class InnerTaskPanel(wx.Panel): link_import_local.UpdateLink() link_import_local.Bind(hl.EVT_HYPERLINK_LEFT, self.OnLinkImport) + #tooltip = wx.ToolTip(_("Select Analyze file to be reconstructed")) + #link_import_ana = hl.HyperLinkCtrl(self, -1, _("Import Analyze image...")) + #link_import_ana.SetUnderlines(False, False, False) + #link_import_ana.SetColours("BLACK", "BLACK", "BLACK") + #link_import_ana.SetToolTip(tooltip) + #link_import_ana.AutoBrowse(False) + #link_import_ana.UpdateLink() + #link_import_ana.Bind(hl.EVT_HYPERLINK_LEFT, self.OnLinkImportAnalyze) + #tooltip = wx.ToolTip("Import DICOM files from PACS server") #link_import_pacs = hl.HyperLinkCtrl(self, -1,"Load from PACS server...") #link_import_pacs.SetUnderlines(False, False, False) @@ -105,6 +115,8 @@ class InnerTaskPanel(wx.Panel): # style=button_style) button_import_local = pbtn.PlateButton(self, BTN_IMPORT_LOCAL, "", BMP_IMPORT, style=button_style) + #button_import_ana = pbtn.PlateButton(self, BTN_IMPORT_ANA, "", + # BMP_IMPORT, style=button_style) button_open_proj = pbtn.PlateButton(self, BTN_OPEN_PROJECT, "", BMP_OPEN_PROJECT, style=button_style) @@ -122,6 +134,8 @@ class InnerTaskPanel(wx.Panel): #(button_import_pacs, 0, flag_button), (link_import_local, 1, flag_link, 3), (button_import_local, 0, flag_button), + #(link_import_ana, 1, flag_link, 3), + #(button_import_ana, 0, flag_button), (link_open_proj, 1, flag_link, 3), (button_open_proj, 0, flag_button) ]) @@ -202,6 +216,10 @@ class InnerTaskPanel(wx.Panel): self.ImportDicom() event.Skip() + def OnLinkImportAnalyze(self, event): + self.ImportAnalyze() + event.Skip() + def OnLinkImportPACS(self, event): self.ImportPACS() event.Skip() @@ -219,6 +237,9 @@ class InnerTaskPanel(wx.Panel): def ImportDicom(self): ps.Publisher().sendMessage('Show import directory dialog') + def ImportAnalyze(self): + ps.Publisher().sendMessage('Show import analyze dialog') + def OpenProject(self, path=None): if path: ps.Publisher().sendMessage('Open recent project', path) @@ -240,6 +261,8 @@ class InnerTaskPanel(wx.Panel): if id == BTN_IMPORT_LOCAL: self.ImportDicom() + #elif id == BTN_IMPORT_ANA: + # self.ImportAnalyze() elif id == BTN_IMPORT_PACS: self.ImportPACS() else: #elif id == BTN_OPEN_PROJECT: diff --git a/invesalius/libc/__init__.py b/invesalius/libc/__init__.py new file mode 100644 index 0000000..0b52a02 --- /dev/null +++ b/invesalius/libc/__init__.py @@ -0,0 +1,18 @@ +#-------------------------------------------------------------------------- +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer +# Homepage: http://www.softwarepublico.gov.br +# Contact: invesalius@cti.gov.br +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) +#-------------------------------------------------------------------------- +# Este programa e software livre; voce pode redistribui-lo e/ou +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme +# publicada pela Free Software Foundation; de acordo com a versao 2 +# da Licenca. +# +# Este programa eh distribuido na expectativa de ser util, mas SEM +# QUALQUER GARANTIA; sem mesmo a garantia implicita de +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais +# detalhes. +#-------------------------------------------------------------------------- diff --git a/invesalius/libc/libalign/__init__.py b/invesalius/libc/libalign/__init__.py new file mode 100644 index 0000000..0b52a02 --- /dev/null +++ b/invesalius/libc/libalign/__init__.py @@ -0,0 +1,18 @@ +#-------------------------------------------------------------------------- +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer +# Homepage: http://www.softwarepublico.gov.br +# Contact: invesalius@cti.gov.br +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) +#-------------------------------------------------------------------------- +# Este programa e software livre; voce pode redistribui-lo e/ou +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme +# publicada pela Free Software Foundation; de acordo com a versao 2 +# da Licenca. +# +# Este programa eh distribuido na expectativa de ser util, mas SEM +# QUALQUER GARANTIA; sem mesmo a garantia implicita de +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais +# detalhes. +#-------------------------------------------------------------------------- diff --git a/invesalius/libc/libalign/libalign.py b/invesalius/libc/libalign/libalign.py new file mode 100644 index 0000000..5f9a9fd --- /dev/null +++ b/invesalius/libc/libalign/libalign.py @@ -0,0 +1,19 @@ + + +from ..libift import libift as libift +from ..libscnvtk import libscnvtk as libscnvtk + + +def VolumeAlign(img): + scn = libscnvtk.VtkImageDataToScene(img) + print "VolumeAlign()" + scn2 = libift.MSP_Align(scn,None,0,1) + return libscnvtk.SceneToVtkImageData(scn2) + + + +def Interp(img): + scn = libscnvtk.VtkImageDataToScene(img) + scn2=libift.LinearInterp(scn,0,0,0) + return libscnvtk.SceneToVtkImageData(scn2) + diff --git a/invesalius/libc/libift/Makefile b/invesalius/libc/libift/Makefile new file mode 100644 index 0000000..f2681ad --- /dev/null +++ b/invesalius/libc/libift/Makefile @@ -0,0 +1,25 @@ + + +PROG=libift +#IFT_DIR=~/ift +#VTK_DIR=/hd2/lib/VTK + + +all: _${PROG}.so + +_${PROG}.so: ${PROG}.i ${PROG}.c + @echo "Generating wrappers..." + @swig -python ${PROG}.i + @echo "Compiling..." + @gcc -c ${PROG}.c ${PROG}_wrap.c -I/usr/include/python2.6 -I${OPF_DIR}/include -I${IFT_DIR}/include -L${IFT_DIR}/lib/ -lift -Wno-deprecated + @echo "Linking..." + @gcc -shared ${PROG}.o ${PROG}_wrap.o -o _${PROG}.so -L${IFT_DIR}/lib/ -lift + @echo "Done." + + +clean: + rm ${PROG}.o ${PROG}.py ${PROG}_wrap.c ${PROG}_wrap.o ${PROG}.py _${PROG}.so *.pyc *.obj *.pyd *.exp *.lib *~ + + + + diff --git a/invesalius/libc/libift/__init__.py b/invesalius/libc/libift/__init__.py new file mode 100644 index 0000000..0b52a02 --- /dev/null +++ b/invesalius/libc/libift/__init__.py @@ -0,0 +1,18 @@ +#-------------------------------------------------------------------------- +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer +# Homepage: http://www.softwarepublico.gov.br +# Contact: invesalius@cti.gov.br +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) +#-------------------------------------------------------------------------- +# Este programa e software livre; voce pode redistribui-lo e/ou +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme +# publicada pela Free Software Foundation; de acordo com a versao 2 +# da Licenca. +# +# Este programa eh distribuido na expectativa de ser util, mas SEM +# QUALQUER GARANTIA; sem mesmo a garantia implicita de +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais +# detalhes. +#-------------------------------------------------------------------------- diff --git a/invesalius/libc/libift/libift.c b/invesalius/libc/libift/libift.c new file mode 100644 index 0000000..256a5ca --- /dev/null +++ b/invesalius/libc/libift/libift.c @@ -0,0 +1,115 @@ + + +//extern "C" { + #include "ift.h" +//} + + + + + +// Prototypes + +void NewDestroyScene(Scene *scn); + + + + +void NewDestroyScene(Scene *scn) +{ + if(scn != NULL){ + if (scn->data != NULL) free(scn->data); + if (scn->tby != NULL) free(scn->tby); + if (scn->tbz != NULL) free(scn->tbz); + free(scn); + } +} + + +Scene* EraseBackground(Scene *scn) +{ + int otsu = (int)(Otsu3(scn)*0.8); // Get 80% of Otsu's threshold + int i,n = scn->xsize*scn->ysize*scn->zsize; + Scene *out = CopyScene(scn); + for (i=0; i < n; i++) { + if (out->data[i]data[i]=0; + } + return out; +} + +Scene* EraseSupport(Scene *scn) +{ + // Check if RemoveBackground was already ran (workaround) + int c=0,i,n = scn->xsize*scn->ysize*scn->zsize; + Scene *scn2; + Scene *labels,*bin; + AdjRel3 *A; + int total[2000],p; + Voxel v; + int max; + Scene *out; + + for (i=0; i < n; i++) { + if (scn->data[i]==0) c++; // count zero voxels + } + if (c<(n*0.15)) + scn2 = EraseBackground(scn); + else + scn2 = CopyScene(scn); + + // Get max connected component + A=Spheric(1.5); + bin = Threshold3(scn2,1,50000); + labels = LabelBinComp3(bin,A); + DestroyAdjRel3(&A); + // Count labels + for (i=0;i<2000;i++) total[i]=0; + for (v.z=0; v.z < scn->zsize; v.z++) + for (v.y=0; v.y < scn->ysize; v.y++) + for (v.x=0; v.x < scn->xsize; v.x++) { + p = labels->tbz[v.z] + labels->tby[v.y] + v.x; + if (labels->data[p]<2000) total[labels->data[p]]++; + if (bin->data[p]==0) total[labels->data[p]]=0; // exclude background + } + DestroyScene(&bin); + max=0; + for (i=0;i<2000;i++) + if (total[i]>total[max]) max=i; + + // copy the maxcc to out + n = scn->xsize*scn->ysize*scn->zsize; + out = CreateScene(scn->xsize,scn->ysize,scn->zsize); + out->dx=scn->dx; + out->dy=scn->dy; + out->dz=scn->dz; + for (i=0; i < n; i++) { + if (labels->data[i]==max) out->data[i]=scn2->data[i]; + } + DestroyScene(&labels); + DestroyScene(&scn2); + return out; +} + + + +int ShiftScene(Scene *scn) +{ + int n,i, min = MinimumValue3(scn); + if (min<0) { + n = scn->xsize*scn->ysize*scn->zsize; + for (i=0; i < n; i++) + scn->data[i] += 1024; + return 1; + } + return 0; +} + +void UnShiftScene(Scene *scn, int flag) +{ + int i,n; + if (flag!=0) { + n = scn->xsize*scn->ysize*scn->zsize; + for (i=0; i < n; i++) + scn->data[i] -= 1024; + } +} diff --git a/invesalius/libc/libift/libift.i b/invesalius/libc/libift/libift.i new file mode 100644 index 0000000..16b3911 --- /dev/null +++ b/invesalius/libc/libift/libift.i @@ -0,0 +1,83 @@ + + +/* example.i */ +%module libift + +%{ +/* Put header files here or function declarations like below */ + +#include "ift.h" + +extern void NewDestroyScene(Scene *scn); +extern Scene* EraseBackground(Scene *scn); +extern Scene* EraseSupport(Scene *scn); +extern int ShiftScene(Scene *scn); +extern void UnShiftScene(Scene *scn, int flag); + +/* From ift library */ +extern float GetDx(Scene *scn); +extern float GetDy(Scene *scn); +extern float GetDz(Scene *scn); +extern int GetXSize(Scene *scn); +extern int GetYSize(Scene *scn); +extern int GetZSize(Scene *scn); +extern Scene *CreateScene(int xsize,int ysize,int zsize); +extern void SetDx(Scene *scn, float dx); +extern void SetDy(Scene *scn, float dy); +extern void SetDz(Scene *scn, float dz); +extern Scene* ReadScene(char *filename); +extern void WriteScene(Scene *scn, char *filename); +extern Scene* MSP_Align(Scene *in, Scene *mask, int input_ori, int quality); +extern Scene *LinearInterp(Scene *scn,float dx,float dy,float dz); +extern Kernel3 *NormalizeKernel3(Kernel3 *K); +extern Kernel3 *GaussianKernel3(AdjRel3 *A, float stddev); +extern Kernel3 *LaplacianKernel3(AdjRel3 *A, float stddev); +extern void DestroyKernel3(Kernel3 **K); +extern Scene *LinearFilter3(Scene *scn, Kernel3 *K); +extern Scene *SobelFilter3(Scene *scn); +extern Scene *MedianFilter3(Scene *scn, AdjRel3 *A); +extern Scene *ModeFilter3(Scene *scn, AdjRel3 *A); +extern AdjRel3 *Spheric(float r); +extern Scene *Equalize3(Scene *scn, int Imax); +extern int Otsu3(Scene *scn); + + + +%} + + + +#include "ift.h" + +extern void NewDestroyScene(Scene *scn); +extern Scene* EraseBackground(Scene *scn); +extern Scene* EraseSupport(Scene *scn); +extern int ShiftScene(Scene *scn); +extern void UnShiftScene(Scene *scn, int flag); + +/* From ift library */ +extern float GetDx(Scene *scn); +extern float GetDy(Scene *scn); +extern float GetDz(Scene *scn); +extern int GetXSize(Scene *scn); +extern int GetYSize(Scene *scn); +extern int GetZSize(Scene *scn); +extern Scene *CreateScene(int xsize,int ysize,int zsize); +extern void SetDx(Scene *scn, float dx); +extern void SetDy(Scene *scn, float dy); +extern void SetDz(Scene *scn, float dz); +extern Scene* ReadScene(char *filename); +extern void WriteScene(Scene *scn, char *filename); +extern Scene* MSP_Align(Scene *in, Scene *mask, int input_ori, int quality); +extern Scene *LinearInterp(Scene *scn,float dx,float dy,float dz); +extern Kernel3 *NormalizeKernel3(Kernel3 *K); +extern Kernel3 *GaussianKernel3(AdjRel3 *A, float stddev); +extern Kernel3 *LaplacianKernel3(AdjRel3 *A, float stddev); +extern void DestroyKernel3(Kernel3 **K); +extern Scene *LinearFilter3(Scene *scn, Kernel3 *K); +extern Scene *SobelFilter3(Scene *scn); +extern Scene *MedianFilter3(Scene *scn, AdjRel3 *A); +extern Scene *ModeFilter3(Scene *scn, AdjRel3 *A); +extern AdjRel3 *Spheric(float r); +extern Scene *Equalize3(Scene *scn, int Imax); + diff --git a/invesalius/libc/libift/makefile.vc b/invesalius/libc/libift/makefile.vc new file mode 100644 index 0000000..d61ef37 --- /dev/null +++ b/invesalius/libc/libift/makefile.vc @@ -0,0 +1,37 @@ + +#---------------------------------------------------------------------- +# This is the Makefile to compile lib-ift with MS Visual C++ (cl.exe) +# using the GNU make or NMAKE. +# +# Instruction: Open the "Visual Studio Command Prompt" and type +# "C:\ift> make -f makefile.vc" or +# "C:\ift> nmake -f makefile.vc" +# +#---------------------------------------------------------------------- + +# Set these variables first +IFT_DIR="C:\ift" +PY_INC="C:\Python26\include" +PY_LIB="C:\Python26\libs\python26.lib" + + +PROG=libift + +all: _$(PROG).pyd + +_$(PROG).pyd: $(PROG).i $(PROG).c + @echo Generating wrappers... + @swig -python $(PROG).i + @echo Compiling... + @cl.exe /nologo -c $(PROG).c $(PROG)_wrap.c -I $(PY_INC) -I $(IFT_DIR)\include + @echo Linking... + @link.exe /nologo -dll $(PROG).obj $(PROG)_wrap.obj $(PY_LIB) $(IFT_DIR)\lib\libift.lib -out:_$(PROG).pyd + @echo Done. + + +clean: + del $(PROG).o $(PROG).py $(PROG)_wrap.c $(PROG)_wrap.o $(PROG).py _$(PROG).so *.pyc *.obj *.pyd *.exp *.lib *~ + + + + diff --git a/invesalius/libc/libscnvtk/Makefile b/invesalius/libc/libscnvtk/Makefile new file mode 100644 index 0000000..b05d452 --- /dev/null +++ b/invesalius/libc/libscnvtk/Makefile @@ -0,0 +1,24 @@ + + +PROG=scnvtk +#IFT_DIR=~/ift +#VTK_DIR=/hd2/lib/VTK + + +all: _${PROG}.so + +_${PROG}.so: ${PROG}.i ${PROG}.cxx + @echo "Generating wrappers..." + @swig -c++ -python ${PROG}.i + @echo "Compiling..." + @c++ -c ${PROG}.cxx ${PROG}_wrap.cxx -I/usr/include/python2.6 -I${OPF_DIR}/include -I${IFT_DIR}/include -L${IFT_DIR}/lib/ -lift -I${VTK_DIR} -I${VTK_DIR}/Common -I${VTK_DIR}/Utilities -I${VTK_DIR}/VolumeRendering -I${VTK_DIR}/Rendering -I${VTK_DIR}/Utilities/vtkalglib -I${VTK_DIR}/Infovis -I${VTK_DIR}/Geovis -I${VTK_DIR}/Views -I${VTK_DIR}/Hybrid -I${VTK_DIR}/Widgets -I${VTK_DIR}/Rendering/Testing/Cxx -I${VTK_DIR}/IO -I${VTK_DIR}/Imaging -I${VTK_DIR}/Graphics -I${VTK_DIR}/GenericFiltering -I${VTK_DIR}/Filtering -I${VTK_DIR}/Common/Testing/Cxx -I${VTK_DIR}/Utilities/vtklibproj4 -I${VTK_DIR}/Utilities/DICOMParser -I${VTK_DIR}/Utilities/vtkfreetype/include -I${VTK_DIR}/Utilities/vtknetcdf -I${VTK_DIR}/Utilities/vtkexodus2/include -I${VTK_DIR}/Utilities/MaterialLibrary -I${VTK_DIR}/Utilities/verdict -I/usr/include/tcl8.4 -Wno-deprecated + @echo "Linking..." + @c++ -shared ${PROG}.o ${PROG}_wrap.o -o _${PROG}.so -L${IFT_DIR}/lib/ -lift #-L${VTK_DIR}/bin -lvtkRendering -lift -lvtkGraphics -lvtkverdict -lvtkImaging -lvtkIO -lvtkFiltering -lvtkCommon -lpthread -lm -lvtkDICOMParser -lvtkNetCDF -lvtkmetaio -lvtksqlite -lvtkpng -lvtktiff -lvtkzlib -lvtkjpeg -lvtkexpat -lvtksys -ldl -lvtkftgl -lvtkfreetype -lGL -lOSMesa -lXt -lSM -lICE -lX11 -lXext + @echo "Done." + +clean: + rm ${PROG}.o ${PROG}.py ${PROG}_wrap.cxx ${PROG}_wrap.o ${PROG}.py _${PROG}.so *.pyc *.obj *.exp *.pyd *.lib *~ + + + + diff --git a/invesalius/libc/libscnvtk/__init__.py b/invesalius/libc/libscnvtk/__init__.py new file mode 100644 index 0000000..0b52a02 --- /dev/null +++ b/invesalius/libc/libscnvtk/__init__.py @@ -0,0 +1,18 @@ +#-------------------------------------------------------------------------- +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer +# Homepage: http://www.softwarepublico.gov.br +# Contact: invesalius@cti.gov.br +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) +#-------------------------------------------------------------------------- +# Este programa e software livre; voce pode redistribui-lo e/ou +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme +# publicada pela Free Software Foundation; de acordo com a versao 2 +# da Licenca. +# +# Este programa eh distribuido na expectativa de ser util, mas SEM +# QUALQUER GARANTIA; sem mesmo a garantia implicita de +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais +# detalhes. +#-------------------------------------------------------------------------- diff --git a/invesalius/libc/libscnvtk/libscnvtk.py b/invesalius/libc/libscnvtk/libscnvtk.py new file mode 100644 index 0000000..b3e0e33 --- /dev/null +++ b/invesalius/libc/libscnvtk/libscnvtk.py @@ -0,0 +1,63 @@ + + + +import scnvtk +import vtk +from ..libift import libift as libift + + + +def Interp(img): + scn = VtkImageDataToScene(img) + scn2=libift.LinearInterp(scn,0,0,0) + libift.NewDestroyScene(scn) + return SceneToVtkImageData(scn2) + + +def SceneToVtkImageData(scn): + dx = libift.GetDx(scn) + dy = libift.GetDy(scn) + dz = libift.GetDz(scn) + xsize = libift.GetXSize(scn) + ysize = libift.GetYSize(scn) + zsize = libift.GetZSize(scn) + img = vtk.vtkImageData() + img.SetSpacing(dx,dy,dz) + img.SetOrigin(0,0,0) + img.SetDimensions(xsize,ysize,zsize) + img.SetScalarTypeToUnsignedShort() + img.SetNumberOfScalarComponents(1) + img.AllocateScalars() + scnvtk.CopyImageBufferScnToVtk(img.GetScalarPointer(),scn) + return img + +def VtkImageDataToScene(img): + d = img.GetSpacing() + dx=d[0] + dy=d[1] + dz=d[2] + d = img.GetDimensions() + xsize=d[0] + ysize=d[1] + zsize=d[2] + scn=libift.CreateScene(xsize,ysize,zsize) + libift.SetDx(scn,dx) + libift.SetDy(scn,dy) + libift.SetDz(scn,dz) + scnvtk.CopyImageBufferVtkToScn(scn,img.GetScalarPointer()) + return scn + + + +def WriteVtkImageData(img,filename): + scn = VtkImageDataToScene(img) + libift.WriteScene(scn,filename) + libift.NewDestroyScene(scn) + +def ReadVtkImageData(filename): + scn = libift.ReadScene(filename) + img=SceneToVtkImageData(scn) + libift.NewDestroyScene(scn) + return img + + diff --git a/invesalius/libc/libscnvtk/makefile.vc b/invesalius/libc/libscnvtk/makefile.vc new file mode 100644 index 0000000..876c1b9 --- /dev/null +++ b/invesalius/libc/libscnvtk/makefile.vc @@ -0,0 +1,36 @@ + +#---------------------------------------------------------------------- +# This is the Makefile to compile lib-ift with MS Visual C++ (cl.exe) +# using the GNU make or NMAKE. +# +# Instruction: Open the "Visual Studio Command Prompt" and type +# "C:\ift> make -f makefile.vc" or +# "C:\ift> nmake -f makefile.vc" +# +#---------------------------------------------------------------------- + +# Set these variables first +IFT_DIR="C:\ift" +PY_INC="C:\Python26\include" +PY_LIB="C:\Python26\libs\python26.lib" +VTK_INC="C:\Arquivos de programas\VTK\include\vtk-5.4" + +PROG=scnvtk + +all: _$(PROG).pyd + +_$(PROG).pyd: $(PROG).i $(PROG).cxx + @echo Generating wrappers... + @swig -c++ -python $(PROG).i + @echo Compiling... + @cl.exe /nologo /EHsc -c $(PROG).cxx $(PROG)_wrap.cxx -I $(PY_INC) -I $(VTK_INC) -I $(IFT_DIR)\include + @echo Linking... + @link.exe /nologo -dll $(PROG).obj $(PROG)_wrap.obj $(PY_LIB) $(IFT_DIR)\lib\libift.lib -out:_$(PROG).pyd + @echo Done. + +clean: + del $(PROG).o $(PROG).py $(PROG)_wrap.c $(PROG)_wrap.o $(PROG).py _$(PROG).so *.pyc *.obj *.pyd *.exp *.lib *~ + + + + diff --git a/invesalius/libc/libscnvtk/scnvtk.cxx b/invesalius/libc/libscnvtk/scnvtk.cxx new file mode 100644 index 0000000..c75a86d --- /dev/null +++ b/invesalius/libc/libscnvtk/scnvtk.cxx @@ -0,0 +1,86 @@ + +#include "vtkImageData.h" + + +extern "C" { + #include "ift.h" +} + + +// Prototypes + + +char *PointerToString(void *ptr, const char *type); +void *StringToPointer(char *ptrText, int len, const char *type); +void CopyImageBufferScnToVtk(char *ptrvtk, Scene *scn); +void CopyImageBufferVtkToScn(Scene *scn, char *ptrvtk); + + + + + +//#if defined ( _MSC_VER ) +//# define vtkConvertPtrToLong(x) ((long)(PtrToUlong(x))) +//#else +# define vtkConvertPtrToLong(x) ((long)(x)) +//#endif + +//-------------------------------------------------------------------- +// mangle a void pointer into a SWIG-style string +char *PointerToString(void *ptr, const char *type) +{ + static char ptrText[128]; + sprintf(ptrText,"_%*.*lx_%s",2*(int)sizeof(void *),2*(int)sizeof(void *), + vtkConvertPtrToLong(ptr),type); + return ptrText; +} + +//-------------------------------------------------------------------- +// unmangle a void pointer from a SWIG-style string +void *StringToPointer(char *ptrText, int len, const char *type) +{ + int i; + void *ptr; + char typeCheck[128]; + if (len < 128) { + i = sscanf(ptrText,"_%lx_%s",(long *)&ptr,typeCheck); + if (strcmp(type,typeCheck) == 0) { + // sucessfully unmangle + return ptr; + } + } + return NULL; +} + + + +void CopyImageBufferScnToVtk(char *ptrvtk, Scene *scn) { + int i; + int n = scn->xsize*scn->ysize*scn->zsize; + short int *ptr = (short int *) StringToPointer(ptrvtk,strlen(ptrvtk),"void_p"); + if (ptr==NULL) { + printf("CopyImageBufferScnToVtk() error! Null Pointer!\n"); + return; + } + for (i=0;idata[i]; +} + + +void CopyImageBufferVtkToScn(Scene *scn, char *ptrvtk) { + int i; + int n = scn->xsize*scn->ysize*scn->zsize; + short int *ptr = (short int *) StringToPointer(ptrvtk,strlen(ptrvtk),"void_p"); + if (ptr==NULL) { + printf("CopyImageBufferVtkToScn() error! Null Pointer!\n"); + return; + } + for (i=0;idata[i] = (int) *(ptr+i); +} + + + + + + diff --git a/invesalius/libc/libscnvtk/scnvtk.i b/invesalius/libc/libscnvtk/scnvtk.i new file mode 100644 index 0000000..9fec928 --- /dev/null +++ b/invesalius/libc/libscnvtk/scnvtk.i @@ -0,0 +1,33 @@ + + +/* example.i */ +%module scnvtk + +%{ +/* Put header files here or function declarations like below */ + +extern "C" { + #include "ift.h" +} +#include "vtkImageData.h" + +extern char *PointerToString(void *ptr, const char *type); +extern void *StringToPointer(char *ptrText, int len, const char *type); +extern void CopyImageBufferScnToVtk(char *ptrvtk, Scene *scn); +extern void CopyImageBufferVtkToScn(Scene *scn, char *ptrvtk); + +%} + + +extern "C" { + #include "ift.h" +} +#include "vtkImageData.h" + +extern char *PointerToString(void *ptr, const char *type); +extern void *StringToPointer(char *ptrText, int len, const char *type); +extern void CopyImageBufferScnToVtk(char *ptrvtk, Scene *scn); +extern void CopyImageBufferVtkToScn(Scene *scn, char *ptrvtk); + + + -- libgit2 0.21.2