Commit 13163add78ab61b1815767cccdf0887a559ab62e
Committed by
GitHub
1 parent
b2b44bbc
Exists in
master
Peel creation using mask and image already loaded (#359)
* Created dialog * some testings * Using ww and wl to set mesh colors * Using ww and wl to set mesh colors * Not cleaning surface before upsample * ww and wl -> window_width and window_level * setting affine_vtk as matrix identity * Some cleaning and setting specular to 0.25 to make peel brighter * created an method to create brain peel from mask * created an method to create brain peel from files * Starting to give support to peel using files * Improvements in GUI * Creating peels from files * Added nifti wildcard * checking if torus orientation and arrow project exists before setting visibility * ADD: Title to the T1 and Mask dialogs for creating peel * ADD: Last directory to load peel files * Using image from invesalius project * FIX: applies vtk affine only for peel from file and decouples self affine variable Co-authored-by: Victor Hugo Souza <victor.souza@aalto.fi> Co-authored-by: Renan <renan_hiroshi@hotmail.com>
Showing
3 changed files
with
277 additions
and
100 deletions
Show diff stats
invesalius/data/brainmesh_handler.py
... | ... | @@ -2,37 +2,95 @@ import vtk |
2 | 2 | import pyacvd |
3 | 3 | # import os |
4 | 4 | import pyvista |
5 | -# import numpy as np | |
5 | +import numpy as np | |
6 | 6 | # import Trekker |
7 | 7 | |
8 | +import invesalius.data.slice_ as sl | |
9 | +from invesalius.data.converters import to_vtk | |
10 | + | |
8 | 11 | |
9 | 12 | class Brain: |
10 | - def __init__(self, img_path, mask_path, n_peels, affine_vtk): | |
13 | + def __init__(self, n_peels, window_width, window_level, affine_vtk=None): | |
11 | 14 | # Create arrays to access the peel data and peel Actors |
12 | 15 | self.peel = [] |
13 | 16 | self.peelActors = [] |
14 | - # Read the image | |
15 | - T1_reader = vtk.vtkNIFTIImageReader() | |
16 | - T1_reader.SetFileName(img_path) | |
17 | - T1_reader.Update() | |
17 | + self.window_width = window_width | |
18 | + self.window_level = window_level | |
19 | + self.numberOfPeels = n_peels | |
20 | + self.affine_vtk = affine_vtk | |
21 | + | |
22 | + def from_mask(self, mask): | |
23 | + mask= np.array(mask.matrix[1:, 1:, 1:]) | |
24 | + slic = sl.Slice() | |
25 | + image = slic.matrix | |
26 | + | |
27 | + mask = to_vtk(mask, spacing=slic.spacing) | |
28 | + image = to_vtk(image, spacing=slic.spacing) | |
29 | + | |
30 | + flip = vtk.vtkImageFlip() | |
31 | + flip.SetInputData(image) | |
32 | + flip.SetFilteredAxis(1) | |
33 | + flip.FlipAboutOriginOn() | |
34 | + flip.ReleaseDataFlagOn() | |
35 | + flip.Update() | |
36 | + image = flip.GetOutput() | |
37 | + | |
38 | + flip = vtk.vtkImageFlip() | |
39 | + flip.SetInputData(mask) | |
40 | + flip.SetFilteredAxis(1) | |
41 | + flip.FlipAboutOriginOn() | |
42 | + flip.ReleaseDataFlagOn() | |
43 | + flip.Update() | |
44 | + mask = flip.GetOutput() | |
45 | + | |
18 | 46 | # Image |
19 | - self.refImage = T1_reader.GetOutput() | |
47 | + self.refImage = image | |
48 | + | |
49 | + self._do_surface_creation(mask) | |
50 | + | |
51 | + | |
52 | + def from_mask_file(self, mask_path): | |
53 | + slic = sl.Slice() | |
54 | + image = slic.matrix | |
55 | + image = to_vtk(image, spacing=slic.spacing) | |
56 | + | |
20 | 57 | # Read the mask |
21 | 58 | mask_reader = vtk.vtkNIFTIImageReader() |
22 | 59 | mask_reader.SetFileName(mask_path) |
23 | 60 | mask_reader.Update() |
61 | + | |
62 | + mask = mask_reader.GetOutput() | |
63 | + | |
64 | + mask_sFormMatrix = mask_reader.GetSFormMatrix() | |
65 | + | |
66 | + # Image | |
67 | + self.refImage = image | |
68 | + | |
69 | + self._do_surface_creation(mask, mask_sFormMatrix) | |
70 | + | |
71 | + | |
72 | + def _do_surface_creation(self, mask, mask_sFormMatrix=None, qFormMatrix=None): | |
73 | + if mask_sFormMatrix is None: | |
74 | + mask_sFormMatrix = vtk.vtkMatrix4x4() | |
75 | + | |
76 | + if qFormMatrix is None: | |
77 | + qFormMatrix = vtk.vtkMatrix4x4() | |
78 | + | |
79 | + value = np.mean(mask.GetScalarRange()) | |
80 | + | |
24 | 81 | # Use the mask to create isosurface |
25 | 82 | mc = vtk.vtkContourFilter() |
26 | - mc.SetInputConnection(mask_reader.GetOutputPort()) | |
27 | - mc.SetValue(0, 1) | |
83 | + mc.SetInputData(mask) | |
84 | + mc.SetValue(0, value) | |
85 | + mc.ComputeNormalsOn() | |
28 | 86 | mc.Update() |
29 | 87 | |
30 | 88 | # Mask isosurface |
31 | 89 | refSurface = mc.GetOutput() |
90 | + | |
32 | 91 | # Create a uniformly meshed surface |
33 | 92 | tmpPeel = downsample(refSurface) |
34 | 93 | # Standard space coordinates |
35 | - mask_sFormMatrix = mask_reader.GetSFormMatrix() | |
36 | 94 | |
37 | 95 | # Apply coordinate transform to the meshed mask |
38 | 96 | mask_ijk2xyz = vtk.vtkTransform() |
... | ... | @@ -48,7 +106,7 @@ class Brain: |
48 | 106 | # Configure calculation of normals |
49 | 107 | tmpPeel = fixMesh(tmpPeel) |
50 | 108 | # Remove duplicate points etc |
51 | - tmpPeel = cleanMesh(tmpPeel) | |
109 | + # tmpPeel = cleanMesh(tmpPeel) | |
52 | 110 | # Generate triangles |
53 | 111 | tmpPeel = upsample(tmpPeel) |
54 | 112 | |
... | ... | @@ -56,9 +114,6 @@ class Brain: |
56 | 114 | tmpPeel = fixMesh(tmpPeel) |
57 | 115 | tmpPeel = cleanMesh(tmpPeel) |
58 | 116 | |
59 | - # Scanner coordinates from image | |
60 | - qFormMatrix = T1_reader.GetQFormMatrix() | |
61 | - | |
62 | 117 | refImageSpace2_xyz_transform = vtk.vtkTransform() |
63 | 118 | refImageSpace2_xyz_transform.SetMatrix(qFormMatrix) |
64 | 119 | |
... | ... | @@ -83,16 +138,16 @@ class Brain: |
83 | 138 | self.peel_centers = vtk.vtkFloatArray() |
84 | 139 | self.peel.append(newPeel) |
85 | 140 | self.currentPeelActor = vtk.vtkActor() |
86 | - self.currentPeelActor.SetUserMatrix(affine_vtk) | |
141 | + if self.affine_vtk: | |
142 | + self.currentPeelActor.SetUserMatrix(self.affine_vtk) | |
87 | 143 | self.GetCurrentPeelActor(currentPeel) |
88 | 144 | self.peelActors.append(self.currentPeelActor) |
89 | 145 | # locator will later find the triangle on the peel surface where the coil's normal intersect |
90 | 146 | self.locator = vtk.vtkCellLocator() |
91 | - self.numberOfPeels = n_peels | |
92 | 147 | self.PeelDown(currentPeel) |
93 | 148 | |
94 | - def get_actor(self, n, affine_vtk): | |
95 | - return self.GetPeelActor(n, affine_vtk) | |
149 | + def get_actor(self, n): | |
150 | + return self.GetPeelActor(n) | |
96 | 151 | |
97 | 152 | def SliceDown(self, currentPeel): |
98 | 153 | # Warp using the normals |
... | ... | @@ -159,9 +214,10 @@ class Brain: |
159 | 214 | |
160 | 215 | self.currentPeelNo += 1 |
161 | 216 | |
162 | - def TransformPeelPosition(self, p, affine_vtk): | |
217 | + def TransformPeelPosition(self, p): | |
163 | 218 | peel_transform = vtk.vtkTransform() |
164 | - peel_transform.SetMatrix(affine_vtk) | |
219 | + if self.affine_vtk: | |
220 | + peel_transform.SetMatrix(self.affine_vtk) | |
165 | 221 | refpeelspace = vtk.vtkTransformPolyDataFilter() |
166 | 222 | refpeelspace.SetInputData(self.peel[p]) |
167 | 223 | refpeelspace.SetTransform(peel_transform) |
... | ... | @@ -169,34 +225,26 @@ class Brain: |
169 | 225 | currentPeel = refpeelspace.GetOutput() |
170 | 226 | return currentPeel |
171 | 227 | |
172 | - def GetPeelActor(self, p, affine_vtk): | |
173 | - colors = vtk.vtkNamedColors() | |
174 | - # Create the color map | |
175 | - colorLookupTable = vtk.vtkLookupTable() | |
176 | - colorLookupTable.SetNumberOfColors(512) | |
177 | - colorLookupTable.SetSaturationRange(0, 0) | |
178 | - colorLookupTable.SetHueRange(0, 0) | |
179 | - colorLookupTable.SetValueRange(0, 1) | |
180 | - # colorLookupTable.SetTableRange(0, 1000) | |
181 | - # colorLookupTable.SetTableRange(0, 250) | |
182 | - colorLookupTable.SetTableRange(0, 200) | |
183 | - # colorLookupTable.SetTableRange(0, 150) | |
184 | - colorLookupTable.Build() | |
228 | + def GetPeelActor(self, p): | |
229 | + lut = vtk.vtkWindowLevelLookupTable() | |
230 | + lut.SetWindow(self.window_width) | |
231 | + lut.SetLevel(self.window_level) | |
232 | + lut.Build() | |
233 | + | |
234 | + init = self.window_level - self.window_width / 2 | |
235 | + end = self.window_level + self.window_width / 2 | |
185 | 236 | |
186 | 237 | # Set mapper auto |
187 | - mapper = vtk.vtkOpenGLPolyDataMapper() | |
238 | + mapper = vtk.vtkPolyDataMapper() | |
188 | 239 | mapper.SetInputData(self.peel[p]) |
189 | - # mapper.SetScalarRange(0, 1000) | |
190 | - # mapper.SetScalarRange(0, 250) | |
191 | - mapper.SetScalarRange(0, 200) | |
192 | - # mapper.SetScalarRange(0, 150) | |
193 | - mapper.SetLookupTable(colorLookupTable) | |
240 | + mapper.SetScalarRange(init, end) | |
241 | + mapper.SetLookupTable(lut) | |
194 | 242 | mapper.InterpolateScalarsBeforeMappingOn() |
195 | 243 | |
196 | 244 | # Set actor |
197 | 245 | self.currentPeelActor.SetMapper(mapper) |
198 | 246 | |
199 | - currentPeel = self.TransformPeelPosition(p, affine_vtk) | |
247 | + currentPeel = self.TransformPeelPosition(p) | |
200 | 248 | |
201 | 249 | self.locator.SetDataSet(currentPeel) |
202 | 250 | self.locator.BuildLocator() |
... | ... | @@ -206,34 +254,26 @@ class Brain: |
206 | 254 | return self.currentPeelActor |
207 | 255 | |
208 | 256 | def GetCurrentPeelActor(self, currentPeel): |
209 | - colors = vtk.vtkNamedColors() | |
210 | - | |
211 | - # Create the color map | |
212 | - colorLookupTable = vtk.vtkLookupTable() | |
213 | - colorLookupTable.SetNumberOfColors(512) | |
214 | - colorLookupTable.SetSaturationRange(0, 0) | |
215 | - colorLookupTable.SetHueRange(0, 0) | |
216 | - colorLookupTable.SetValueRange(0, 1) | |
217 | - # colorLookupTable.SetTableRange(0, 1000) | |
218 | - # colorLookupTable.SetTableRange(0, 250) | |
219 | - colorLookupTable.SetTableRange(0, 200) | |
220 | - # colorLookupTable.SetTableRange(0, 150) | |
221 | - colorLookupTable.Build() | |
257 | + lut = vtk.vtkWindowLevelLookupTable() | |
258 | + lut.SetWindow(self.window_width) | |
259 | + lut.SetLevel(self.window_level) | |
260 | + lut.Build() | |
261 | + | |
262 | + init = self.window_level - self.window_width / 2 | |
263 | + end = self.window_level + self.window_width / 2 | |
222 | 264 | |
223 | 265 | # Set mapper auto |
224 | - mapper = vtk.vtkOpenGLPolyDataMapper() | |
266 | + mapper = vtk.vtkPolyDataMapper() | |
225 | 267 | mapper.SetInputData(currentPeel) |
226 | - # mapper.SetScalarRange(0, 1000) | |
227 | - # mapper.SetScalarRange(0, 250) | |
228 | - mapper.SetScalarRange(0, 200) | |
229 | - # mapper.SetScalarRange(0, 150) | |
230 | - mapper.SetLookupTable(colorLookupTable) | |
268 | + mapper.SetScalarRange(init, end) | |
269 | + mapper.SetLookupTable(lut) | |
231 | 270 | mapper.InterpolateScalarsBeforeMappingOn() |
232 | 271 | |
233 | 272 | # Set actor |
234 | 273 | self.currentPeelActor.SetMapper(mapper) |
235 | 274 | self.currentPeelActor.GetProperty().SetBackfaceCulling(1) |
236 | 275 | self.currentPeelActor.GetProperty().SetOpacity(0.5) |
276 | + self.currentPeelActor.GetProperty().SetSpecular(0.25) | |
237 | 277 | |
238 | 278 | return self.currentPeelActor |
239 | 279 | ... | ... |
invesalius/gui/dialogs.py
... | ... | @@ -46,6 +46,7 @@ except ImportError: |
46 | 46 | from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor |
47 | 47 | from wx.lib import masked |
48 | 48 | from wx.lib.agw import floatspin |
49 | +import wx.lib.filebrowsebutton as filebrowse | |
49 | 50 | from wx.lib.wordwrap import wordwrap |
50 | 51 | from invesalius.pubsub import pub as Publisher |
51 | 52 | import csv |
... | ... | @@ -4995,3 +4996,134 @@ class SetSpacingDialog(wx.Dialog): |
4995 | 4996 | |
4996 | 4997 | def OnCancel(self, evt): |
4997 | 4998 | self.EndModal(wx.ID_CANCEL) |
4999 | + | |
5000 | + | |
5001 | +class PeelsCreationDlg(wx.Dialog): | |
5002 | + FROM_MASK = 1 | |
5003 | + FROM_FILES = 2 | |
5004 | + def __init__(self, parent, *args, **kwds): | |
5005 | + wx.Dialog.__init__(self, parent, *args, **kwds) | |
5006 | + | |
5007 | + self.mask_path = '' | |
5008 | + self.method = self.FROM_MASK | |
5009 | + | |
5010 | + self._init_gui() | |
5011 | + self._bind_events_wx() | |
5012 | + self.get_all_masks() | |
5013 | + | |
5014 | + def _init_gui(self): | |
5015 | + self.SetTitle("dialog") | |
5016 | + | |
5017 | + from_mask_stbox = self._from_mask_gui() | |
5018 | + from_files_stbox = self._from_files_gui() | |
5019 | + | |
5020 | + main_sizer = wx.BoxSizer(wx.VERTICAL) | |
5021 | + main_sizer.Add(from_mask_stbox, 0, wx.EXPAND | wx.ALL, 5) | |
5022 | + main_sizer.Add(from_files_stbox, 0, wx.EXPAND | wx.ALL, 5) | |
5023 | + | |
5024 | + btn_sizer = wx.StdDialogButtonSizer() | |
5025 | + main_sizer.Add(btn_sizer, 0, wx.ALIGN_RIGHT | wx.ALL, 4) | |
5026 | + | |
5027 | + self.btn_ok = wx.Button(self, wx.ID_OK, "") | |
5028 | + self.btn_ok.SetDefault() | |
5029 | + btn_sizer.AddButton(self.btn_ok) | |
5030 | + | |
5031 | + self.btn_cancel = wx.Button(self, wx.ID_CANCEL, "") | |
5032 | + btn_sizer.AddButton(self.btn_cancel) | |
5033 | + | |
5034 | + btn_sizer.Realize() | |
5035 | + | |
5036 | + self.SetSizer(main_sizer) | |
5037 | + main_sizer.Fit(self) | |
5038 | + | |
5039 | + self.SetAffirmativeId(self.btn_ok.GetId()) | |
5040 | + self.SetEscapeId(self.btn_cancel.GetId()) | |
5041 | + | |
5042 | + self.Layout() | |
5043 | + | |
5044 | + def _from_mask_gui(self): | |
5045 | + mask_box = wx.StaticBox(self, -1, _("From mask")) | |
5046 | + from_mask_stbox = wx.StaticBoxSizer(mask_box, wx.VERTICAL) | |
5047 | + | |
5048 | + self.cb_masks = wx.ComboBox(self, wx.ID_ANY, choices=[]) | |
5049 | + self.from_mask_rb = wx.RadioButton(self, -1, "", style = wx.RB_GROUP) | |
5050 | + | |
5051 | + internal_sizer = wx.BoxSizer(wx.HORIZONTAL) | |
5052 | + internal_sizer.Add(self.from_mask_rb, 0, wx.ALL | wx.EXPAND, 5) | |
5053 | + internal_sizer.Add(self.cb_masks, 1, wx.ALL | wx.EXPAND, 5) | |
5054 | + | |
5055 | + from_mask_stbox.Add(internal_sizer, 0, wx.EXPAND) | |
5056 | + | |
5057 | + return from_mask_stbox | |
5058 | + | |
5059 | + def _from_files_gui(self): | |
5060 | + session = ses.Session() | |
5061 | + last_directory = session.get('paths', 'last_directory_%d' % const.ID_NIFTI_IMPORT, '') | |
5062 | + | |
5063 | + files_box = wx.StaticBox(self, -1, _("From files")) | |
5064 | + from_files_stbox = wx.StaticBoxSizer(files_box, wx.VERTICAL) | |
5065 | + | |
5066 | + self.mask_file_browse = filebrowse.FileBrowseButton(self, -1, labelText=_("Mask file"), | |
5067 | + fileMask=WILDCARD_NIFTI, dialogTitle=_("Choose Mask file"), startDirectory = last_directory, | |
5068 | + changeCallback=lambda evt: self._set_files_callback(mask_path=evt.GetString())) | |
5069 | + self.from_files_rb = wx.RadioButton(self, -1, "") | |
5070 | + | |
5071 | + ctrl_sizer = wx.BoxSizer(wx.VERTICAL) | |
5072 | + ctrl_sizer.Add(self.mask_file_browse, 0, wx.ALL | wx.EXPAND, 5) | |
5073 | + | |
5074 | + internal_sizer = wx.BoxSizer(wx.HORIZONTAL) | |
5075 | + internal_sizer.Add(self.from_files_rb, 0, wx.ALL | wx.EXPAND, 5) | |
5076 | + internal_sizer.Add(ctrl_sizer, 0, wx.ALL | wx.EXPAND, 5) | |
5077 | + | |
5078 | + from_files_stbox.Add(internal_sizer, 0, wx.EXPAND) | |
5079 | + | |
5080 | + return from_files_stbox | |
5081 | + | |
5082 | + def _bind_events_wx(self): | |
5083 | + self.from_mask_rb.Bind(wx.EVT_RADIOBUTTON, self.on_select_method) | |
5084 | + self.from_files_rb.Bind(wx.EVT_RADIOBUTTON, self.on_select_method) | |
5085 | + | |
5086 | + def get_all_masks(self): | |
5087 | + import invesalius.project as prj | |
5088 | + inv_proj = prj.Project() | |
5089 | + choices = [i.name for i in inv_proj.mask_dict.values()] | |
5090 | + try: | |
5091 | + initial_value = choices[0] | |
5092 | + enable = True | |
5093 | + except IndexError: | |
5094 | + initial_value = "" | |
5095 | + enable = False | |
5096 | + | |
5097 | + self.cb_masks.SetItems(choices) | |
5098 | + self.cb_masks.SetValue(initial_value) | |
5099 | + self.btn_ok.Enable(enable) | |
5100 | + | |
5101 | + def on_select_method(self, evt): | |
5102 | + radio_selected = evt.GetEventObject() | |
5103 | + if radio_selected is self.from_mask_rb: | |
5104 | + self.method = self.FROM_MASK | |
5105 | + if self.cb_masks.GetItems(): | |
5106 | + self.btn_ok.Enable(True) | |
5107 | + else: | |
5108 | + self.btn_ok.Enable(False) | |
5109 | + else: | |
5110 | + self.method = self.FROM_FILES | |
5111 | + if self._check_if_files_exists(): | |
5112 | + self.btn_ok.Enable(True) | |
5113 | + else: | |
5114 | + self.btn_ok.Enable(False) | |
5115 | + | |
5116 | + def _set_files_callback(self, mask_path=''): | |
5117 | + if mask_path: | |
5118 | + self.mask_path = mask_path | |
5119 | + if self.method == self.FROM_FILES: | |
5120 | + if self._check_if_files_exists(): | |
5121 | + self.btn_ok.Enable(True) | |
5122 | + else: | |
5123 | + self.btn_ok.Enable(False) | |
5124 | + | |
5125 | + def _check_if_files_exists(self): | |
5126 | + if self.mask_path and os.path.exists(self.mask_path): | |
5127 | + return True | |
5128 | + else: | |
5129 | + return False | ... | ... |
invesalius/gui/task_navigator.py
... | ... | @@ -31,7 +31,8 @@ try: |
31 | 31 | import Trekker |
32 | 32 | has_trekker = True |
33 | 33 | except ImportError: |
34 | - has_trekker = False | |
34 | + has_trekker = True | |
35 | + | |
35 | 36 | try: |
36 | 37 | import invesalius.data.elfin as elfin |
37 | 38 | import invesalius.data.elfin_processing as elfin_process |
... | ... | @@ -40,6 +41,7 @@ except ImportError: |
40 | 41 | has_robot = False |
41 | 42 | |
42 | 43 | import wx |
44 | +import vtk | |
43 | 45 | |
44 | 46 | try: |
45 | 47 | import wx.lib.agw.foldpanelbar as fpb |
... | ... | @@ -72,6 +74,7 @@ from invesalius.navigation.icp import ICP |
72 | 74 | from invesalius.navigation.navigation import Navigation |
73 | 75 | from invesalius.navigation.tracker import Tracker |
74 | 76 | from invesalius.navigation.robot import Robot |
77 | +from invesalius.data.converters import to_vtk | |
75 | 78 | |
76 | 79 | from invesalius.net.neuronavigation_api import NeuronavigationApi |
77 | 80 | |
... | ... | @@ -1939,7 +1942,7 @@ class TractographyPanel(wx.Panel): |
1939 | 1942 | def OnSelectPeelingDepth(self, evt, ctrl): |
1940 | 1943 | self.peel_depth = ctrl.GetValue() |
1941 | 1944 | if self.checkpeeling.GetValue(): |
1942 | - actor = self.brain_peel.get_actor(self.peel_depth, self.affine_vtk) | |
1945 | + actor = self.brain_peel.get_actor(self.peel_depth) | |
1943 | 1946 | Publisher.sendMessage('Update peel', flag=True, actor=actor) |
1944 | 1947 | Publisher.sendMessage('Get peel centers and normals', centers=self.brain_peel.peel_centers, |
1945 | 1948 | normals=self.brain_peel.peel_normals) |
... | ... | @@ -1972,7 +1975,7 @@ class TractographyPanel(wx.Panel): |
1972 | 1975 | def OnShowPeeling(self, evt, ctrl): |
1973 | 1976 | # self.view_peeling = ctrl.GetValue() |
1974 | 1977 | if ctrl.GetValue(): |
1975 | - actor = self.brain_peel.get_actor(self.peel_depth, self.affine_vtk) | |
1978 | + actor = self.brain_peel.get_actor(self.peel_depth) | |
1976 | 1979 | self.peel_loaded = True |
1977 | 1980 | Publisher.sendMessage('Update peel visualization', data=self.peel_loaded) |
1978 | 1981 | else: |
... | ... | @@ -2002,46 +2005,48 @@ class TractographyPanel(wx.Panel): |
2002 | 2005 | |
2003 | 2006 | def OnLinkBrain(self, event=None): |
2004 | 2007 | Publisher.sendMessage('Begin busy cursor') |
2005 | - mask_path = dlg.ShowImportOtherFilesDialog(const.ID_NIFTI_IMPORT, _("Import brain mask")) | |
2006 | - img_path = dlg.ShowImportOtherFilesDialog(const.ID_NIFTI_IMPORT, _("Import T1 anatomical image")) | |
2007 | - # data_dir = os.environ.get('OneDrive') + r'\data\dti_navigation\baran\anat_reg_improve_20200609' | |
2008 | - # mask_file = 'Baran_brain_mask.nii' | |
2009 | - # mask_path = os.path.join(data_dir, mask_file) | |
2010 | - # img_file = 'Baran_T1_inFODspace.nii' | |
2011 | - # img_path = os.path.join(data_dir, img_file) | |
2012 | - | |
2013 | - if not self.affine_vtk: | |
2008 | + inv_proj = prj.Project() | |
2009 | + peels_dlg = dlg.PeelsCreationDlg(wx.GetApp().GetTopWindow()) | |
2010 | + ret = peels_dlg.ShowModal() | |
2011 | + method = peels_dlg.method | |
2012 | + if ret == wx.ID_OK: | |
2014 | 2013 | slic = sl.Slice() |
2015 | - prj_data = prj.Project() | |
2016 | - matrix_shape = tuple(prj_data.matrix_shape) | |
2017 | - spacing = tuple(prj_data.spacing) | |
2018 | - img_shift = spacing[1] * (matrix_shape[1] - 1) | |
2019 | - self.affine = slic.affine.copy() | |
2020 | - self.affine[1, -1] -= img_shift | |
2021 | - self.affine_vtk = vtk_utils.numpy_to_vtkMatrix4x4(self.affine) | |
2022 | - | |
2023 | - if mask_path and img_path: | |
2024 | - Publisher.sendMessage('Update status text in GUI', label=_("Busy")) | |
2025 | - try: | |
2026 | - self.brain_peel = brain.Brain(img_path, mask_path, self.n_peels, self.affine_vtk) | |
2027 | - self.brain_actor = self.brain_peel.get_actor(self.peel_depth, self.affine_vtk) | |
2028 | - self.brain_actor.GetProperty().SetOpacity(self.brain_opacity) | |
2029 | - | |
2030 | - self.checkpeeling.Enable(1) | |
2031 | - self.checkpeeling.SetValue(True) | |
2032 | - self.spin_opacity.Enable(1) | |
2033 | - self.peel_loaded = True | |
2034 | - | |
2035 | - Publisher.sendMessage('Update peel', flag=True, actor=self.brain_actor) | |
2036 | - Publisher.sendMessage('Get peel centers and normals', centers=self.brain_peel.peel_centers, | |
2037 | - normals=self.brain_peel.peel_normals) | |
2038 | - Publisher.sendMessage('Get init locator', locator=self.brain_peel.locator) | |
2039 | - Publisher.sendMessage('Update status text in GUI', label=_("Brain model loaded")) | |
2040 | - Publisher.sendMessage('Update peel visualization', data= self.peel_loaded) | |
2041 | - except: | |
2042 | - Publisher.sendMessage('Update status text in GUI', label=_("Brain mask initialization failed.")) | |
2043 | - wx.MessageBox(_("Unable to load brain mask."), _("InVesalius 3")) | |
2014 | + ww = slic.window_width | |
2015 | + wl = slic.window_level | |
2016 | + affine_vtk = vtk.vtkMatrix4x4() | |
2017 | + | |
2018 | + if method == peels_dlg.FROM_FILES: | |
2019 | + matrix_shape = tuple(inv_proj.matrix_shape) | |
2020 | + try: | |
2021 | + affine = slic.affine.copy() | |
2022 | + except AttributeError: | |
2023 | + affine = np.eye(4) | |
2024 | + affine[1, -1] -= matrix_shape[1] | |
2025 | + affine_vtk = vtk_utils.numpy_to_vtkMatrix4x4(affine) | |
2026 | + | |
2027 | + self.brain_peel = brain.Brain(self.n_peels, ww, wl, affine_vtk) | |
2028 | + if method == peels_dlg.FROM_MASK: | |
2029 | + choices = [i for i in inv_proj.mask_dict.values()] | |
2030 | + mask_index = peels_dlg.cb_masks.GetSelection() | |
2031 | + mask = choices[mask_index] | |
2032 | + self.brain_peel.from_mask(mask) | |
2033 | + else: | |
2034 | + mask_path = peels_dlg.mask_path | |
2035 | + self.brain_peel.from_mask_file(mask_path) | |
2036 | + self.brain_actor = self.brain_peel.get_actor(self.peel_depth) | |
2037 | + self.brain_actor.GetProperty().SetOpacity(self.brain_opacity) | |
2038 | + Publisher.sendMessage('Update peel', flag=True, actor=self.brain_actor) | |
2039 | + Publisher.sendMessage('Get peel centers and normals', centers=self.brain_peel.peel_centers, | |
2040 | + normals=self.brain_peel.peel_normals) | |
2041 | + Publisher.sendMessage('Get init locator', locator=self.brain_peel.locator) | |
2042 | + self.checkpeeling.Enable(1) | |
2043 | + self.checkpeeling.SetValue(True) | |
2044 | + self.spin_opacity.Enable(1) | |
2045 | + Publisher.sendMessage('Update status text in GUI', label=_("Brain model loaded")) | |
2046 | + self.peel_loaded = True | |
2047 | + Publisher.sendMessage('Update peel visualization', data= self.peel_loaded) | |
2044 | 2048 | |
2049 | + peels_dlg.Destroy() | |
2045 | 2050 | Publisher.sendMessage('End busy cursor') |
2046 | 2051 | |
2047 | 2052 | def OnLinkFOD(self, event=None): | ... | ... |