Commit a21f0c3764214fc0171dccea0459695f157f478e

Authored by tfmoraes
1 parent ce061625

Saving inv3

invesalius/control.py
... ... @@ -236,6 +236,13 @@ class Controller():
236 236 proj = prj.Project()
237 237 proj.OpenPlistProject(path)
238 238 proj.SetAcquisitionModality(proj.modality)
  239 + self.Slice = sl.Slice()
  240 + self.Slice._open_image_matrix(proj.matrix_filename,
  241 + tuple(proj.matrix_shape),
  242 + proj.matrix_dtype)
  243 +
  244 + self.Slice.window_level = proj.level
  245 + self.Slice.window_width = proj.window
239 246  
240 247 mask = msk.Mask()
241 248 mask._set_class_index(proj.last_mask_index)
... ... @@ -246,6 +253,8 @@ class Controller():
246 253  
247 254 self.LoadProject()
248 255  
  256 + ps.Publisher().sendMessage('Update threshold limits',
  257 + proj.threshold_range)
249 258 session = ses.Session()
250 259 session.OpenProject(filepath)
251 260 ps.Publisher().sendMessage("Enable state project", True)
... ... @@ -329,8 +338,8 @@ class Controller():
329 338 patients_groups = dcm.GetDicomGroups(directory)
330 339 if len(patients_groups):
331 340 group = dcm.SelectLargerDicomGroup(patients_groups)
332   - imagedata, dicom = self.OpenDicomGroup(group, 0, [0,0],gui=True)
333   - self.CreateDicomProject(imagedata, dicom)
  341 + matrix, matrix_filename, dicom = self.OpenDicomGroup(group, 0, [0,0],gui=True)
  342 + self.CreateDicomProject(dicom, matrix, matrix_filename)
334 343 # OPTION 2: ANALYZE?
335 344 else:
336 345 imagedata = analyze.ReadDirectory(directory)
... ... @@ -352,6 +361,9 @@ class Controller():
352 361 const.WINDOW_LEVEL[_('Default')] = (proj.window, proj.level)
353 362 const.WINDOW_LEVEL[_('Manual')] = (proj.window, proj.level)
354 363  
  364 + self.Slice = sl.Slice()
  365 + self.Slice.spacing = proj.spacing
  366 +
355 367 ps.Publisher().sendMessage('Load slice to viewer',
356 368 (proj.imagedata,
357 369 proj.mask_dict))
... ... @@ -375,6 +387,11 @@ class Controller():
375 387  
376 388 if len(proj.mask_dict):
377 389 mask_index = len(proj.mask_dict) -1
  390 + for m in proj.mask_dict.values():
  391 + ps.Publisher().sendMessage('Add mask',
  392 + (m.index, m.name,
  393 + m.threshold_range, m.colour))
  394 + self.Slice.current_mask = proj.mask_dict[mask_index]
378 395 ps.Publisher().sendMessage('Show mask', (mask_index, True))
379 396  
380 397 ps.Publisher().sendMessage('Load measurement dict',
... ... @@ -419,7 +436,7 @@ class Controller():
419 436 ps.Publisher().sendMessage('Update threshold limits',
420 437 proj.threshold_range)
421 438  
422   - def CreateDicomProject(self, imagedata, dicom):
  439 + def CreateDicomProject(self, dicom, matrix, matrix_filename):
423 440 name_to_const = {"AXIAL":const.AXIAL,
424 441 "CORONAL":const.CORONAL,
425 442 "SAGITTAL":const.SAGITAL}
... ... @@ -428,14 +445,17 @@ class Controller():
428 445 proj.name = dicom.patient.name
429 446 proj.modality = dicom.acquisition.modality
430 447 proj.SetAcquisitionModality(dicom.acquisition.modality)
431   - proj.imagedata = imagedata
  448 + proj.matrix_shape = matrix.shape
  449 + proj.matrix_dtype = matrix.dtype.name
  450 + proj.matrix_filename = matrix_filename
  451 + #proj.imagedata = imagedata
432 452 proj.dicom_sample = dicom
433 453 proj.original_orientation =\
434 454 name_to_const[dicom.image.orientation_label]
435 455 proj.window = float(dicom.image.window)
436 456 proj.level = float(dicom.image.level)
437 457 proj.threshold_range = (-1024, 3033)
438   -
  458 + proj.spacing = self.Slice.spacing
439 459  
440 460 ######
441 461 session = ses.Session()
... ... @@ -448,8 +468,8 @@ class Controller():
448 468  
449 469 def OnOpenDicomGroup(self, pubsub_evt):
450 470 group, interval, file_range = pubsub_evt.data
451   - imagedata, dicom = self.OpenDicomGroup(group, interval, file_range, gui=True)
452   - self.CreateDicomProject(imagedata, dicom)
  471 + matrix, matrix_filename, dicom = self.OpenDicomGroup(group, interval, file_range, gui=True)
  472 + self.CreateDicomProject(dicom, matrix, matrix_filename)
453 473 self.LoadProject()
454 474 ps.Publisher().sendMessage("Enable state project", True)
455 475  
... ... @@ -511,12 +531,13 @@ class Controller():
511 531 elif orientation == 'SAGITTAL':
512 532 self.Slice.spacing = zspacing, xyspacing[1], xyspacing[0]
513 533  
  534 +
514 535 self.Slice.window_level = wl
515 536 self.Slice.window_width = ww
516 537  
517 538 ps.Publisher().sendMessage('Update threshold limits', scalar_range)
518 539  
519   - return imagedata, dicom
  540 + return self.matrix, self.filename, dicom
520 541  
521 542 def LoadImagedataInfo(self):
522 543 proj = prj.Project()
... ...
invesalius/data/imagedata_utils.py
... ... @@ -215,8 +215,8 @@ def Export(imagedata, filename, bin=False):
215 215 writer.SetDataModeToBinary()
216 216 else:
217 217 writer.SetDataModeToAscii()
218   - writer.SetInput(imagedata)
219   - writer.Write()
  218 + #writer.SetInput(imagedata)
  219 + #writer.Write()
220 220  
221 221 def Import(filename):
222 222 reader = vtk.vtkXMLImageDataReader()
... ... @@ -497,6 +497,7 @@ def dcm2memmap(files, slice_size, orientation):
497 497 array.shape = matrix.shape[0], matrix.shape[1]
498 498 matrix[:, :, n] = array
499 499 else:
  500 + print array.shape, matrix.shape
500 501 array.shape = matrix.shape[1], matrix.shape[2]
501 502 matrix[n] = array
502 503 update_progress(cont,message)
... ...
invesalius/data/mask.py
... ... @@ -20,6 +20,7 @@
20 20 import os
21 21 import plistlib
22 22 import random
  23 +import shutil
23 24 import tempfile
24 25  
25 26 import numpy
... ... @@ -44,42 +45,46 @@ class Mask():
44 45  
45 46 def SavePlist(self, filename):
46 47 mask = {}
47   - filename = '%s$%s$%d' % (filename, 'mask', self.index)
48   -
49   - d = self.__dict__
50   - for key in d:
51   - if isinstance(d[key], vtk.vtkImageData):
52   - img_name = '%s_%s.vti' % (filename, key)
53   - iu.Export(d[key], img_name, bin=True)
54   - mask[key] = {'$vti': os.path.split(img_name)[1]}
55   - elif key == 'edited_points':
56   - edited_points = {}
57   - for p in self.edited_points:
58   - edited_points[str(p)] = self.edited_points[p]
59   - mask[key] = edited_points
60   - else:
61   - mask[key] = d[key]
  48 + filename = u'%s_%s_%d_%s' % (filename, 'mask', self.index, self.name)
  49 + img_name = u'%s.dat' % filename
  50 + self._save_mask(img_name)
  51 +
  52 + mask['index'] = self.index
  53 + mask['colour'] = self.colour
  54 + mask['opacity'] = self.opacity
  55 + mask['threshold range'] = self.threshold_range
  56 + mask['name'] = self.name
  57 + mask['edition threshold range'] = self.edition_threshold_range
  58 + mask['show'] = self.is_shown
  59 + mask['mask file'] = os.path.split(img_name)[1]
  60 + mask['mask shape'] = self.matrix.shape
  61 +
62 62 plistlib.writePlist(mask, filename + '.plist')
63 63 return os.path.split(filename)[1] + '.plist'
64 64  
65 65 def OpenPList(self, filename):
66 66 mask = plistlib.readPlist(filename)
  67 +
  68 + self.index = mask['index']
  69 + self.colour = mask['colour']
  70 + self.opacity = mask['opacity']
  71 + self.threshold_range = mask['threshold range']
  72 + self.name = mask['name']
  73 + self.edition_threshold_range = mask['edition threshold range']
  74 + self.is_shown = mask['show']
  75 + mask_file = mask['mask file']
  76 + shape = mask['mask shape']
67 77 dirpath = os.path.abspath(os.path.split(filename)[0])
68   - for key in mask:
69   - print "Key", key
70   - if key == 'imagedata':
71   - filepath = os.path.split(mask[key]["$vti"])[-1]
72   - path = os.path.join(dirpath, filepath)
73   - self.imagedata = iu.Import(path)
74   - elif key == 'edited_points':
75   - edited_points = {}
76   - for p in mask[key]:
77   - k = [float(i) for i in p.replace('(', '').replace(')', '').split(',')]
78   - edited_points[tuple(k)] = mask[key][p]
79   -
80   - setattr(self, key, edited_points)
81   - else:
82   - setattr(self, key, mask[key])
  78 + path = os.path.join(dirpath, mask_file)
  79 + self._open_mask(path, tuple(shape))
  80 +
  81 + def _save_mask(self, filename):
  82 + shutil.copyfile(self.temp_file, filename)
  83 +
  84 + def _open_mask(self, filename, shape, dtype='uint8'):
  85 + print ">>", filename, shape
  86 + self.temp_file = filename
  87 + self.matrix = numpy.memmap(filename, shape=shape, dtype=dtype, mode="r+")
83 88  
84 89 def _set_class_index(self, index):
85 90 Mask.general_index = index
... ...
invesalius/data/slice_.py
... ... @@ -75,6 +75,7 @@ class Slice(object):
75 75 self.current_mask = None
76 76 self.blend_filter = None
77 77 self.matrix = None
  78 + self.spacing = (1.0, 1.0, 1.0)
78 79  
79 80 self.number_of_colours = 256
80 81 self.saturation_range = (0, 0)
... ... @@ -542,6 +543,7 @@ class Slice(object):
542 543  
543 544 def ShowMask(self, index, value):
544 545 "Show a mask given its index and 'show' value (0: hide, other: show)"
  546 + print "Showing Mask"
545 547 proj = Project()
546 548 proj.mask_dict[index].is_shown = value
547 549 if (index == self.current_mask.index):
... ... @@ -946,6 +948,12 @@ class Slice(object):
946 948  
947 949 return imagedata_mask
948 950  
  951 + def _open_image_matrix(self, filename, shape, dtype):
  952 + self.matrix_filename = filename
  953 + print ">>>", filename
  954 + self.matrix = numpy.memmap(filename, shape=shape, dtype=dtype,
  955 + mode='r+')
  956 +
949 957 def OnExportMask(self, pubsub_evt):
950 958 #imagedata = self.current_mask.imagedata
951 959 imagedata = self.imagedata
... ...
invesalius/data/viewer_slice.py
... ... @@ -1172,7 +1172,7 @@ class Viewer(wx.Panel):
1172 1172 max_slice_number)
1173 1173  
1174 1174 self.slice_data = self.create_slice_window()
1175   - self.slice_data.actor.SetInput(imagedata)
  1175 + #self.slice_data.actor.SetInput(imagedata)
1176 1176 self.slice_data.SetCursor(self.__create_cursor())
1177 1177 self.cam = self.slice_data.renderer.GetActiveCamera()
1178 1178 self.__build_cross_lines(imagedata)
... ...
invesalius/gui/task_slice.py
... ... @@ -479,6 +479,7 @@ class MaskProperties(wx.Panel):
479 479 (thresh_min, thresh_max) = Project().threshold_modes[evt.GetString()]
480 480 self.gradient.SetMinValue(thresh_min)
481 481 self.gradient.SetMaxValue(thresh_max)
  482 + self.OnSlideChanging(None)
482 483 self.OnSlideChanged(None)
483 484  
484 485 def OnSlideChanged(self, evt):
... ...
invesalius/gui/widgets/gradient.py
... ... @@ -320,6 +320,7 @@ class GradientCtrl(wx.Panel):
320 320 self.minimun = minValue
321 321 self.maximun = maxValue
322 322 self.colour = colour
  323 + self.changed = False
323 324 self._draw_controls()
324 325 self._bind_events_wx()
325 326 self.SetBackgroundColour((0, 255, 0))
... ... @@ -353,13 +354,15 @@ class GradientCtrl(wx.Panel):
353 354 self.gradient_slider.Bind(EVT_SLIDER_CHANGED, self.OnSlider)
354 355  
355 356 # self.spin_min.Bind(wx.lib.intctrl.EVT_INT, self.ChangeMinValue)
356   - self.spin_min.Bind(wx.EVT_KILL_FOCUS, self._FireSpinMinChange)
357   - self.spin_min.Bind(wx.EVT_TEXT_ENTER, self._FireSpinMinChange)
  357 + self.spin_min.Bind(wx.EVT_LEAVE_WINDOW, self._FireSpinMinChanged)
  358 + self.spin_min.Bind(wx.EVT_KILL_FOCUS, self._FireSpinMinChanged)
  359 + self.spin_min.Bind(wx.EVT_KEY_DOWN, self._FireSpinMinChange)
358 360 self.spin_min.Bind(wx.EVT_MOUSEWHEEL, self.OnMinMouseWheel)
359 361  
360 362 # self.spin_max.Bind(wx.lib.intctrl.EVT_INT, self.ChangeMaxValue)
361   - self.spin_max.Bind(wx.EVT_KILL_FOCUS, self._FireSpinMaxChange)
362   - self.spin_max.Bind(wx.EVT_TEXT_ENTER, self._FireSpinMaxChange)
  363 + self.spin_max.Bind(wx.EVT_LEAVE_WINDOW, self._FireSpinMaxChanged)
  364 + self.spin_max.Bind(wx.EVT_KILL_FOCUS, self._FireSpinMaxChanged)
  365 + self.spin_max.Bind(wx.EVT_KEY_DOWN, self._FireSpinMaxChange)
363 366 self.spin_max.Bind(wx.EVT_MOUSEWHEEL, self.OnMaxMouseWheel)
364 367  
365 368 def OnSlider(self, evt):
... ... @@ -377,17 +380,27 @@ class GradientCtrl(wx.Panel):
377 380 self._GenerateEvent(myEVT_THRESHOLD_CHANGING)
378 381  
379 382 def _FireSpinMinChange(self, evt):
  383 + evt.Skip()
380 384 value = int(self.spin_min.GetValue())
381 385 if value != self.GetMinValue():
382 386 self.SetMinValue(value)
383 387 self._GenerateEvent(myEVT_THRESHOLD_CHANGING)
384 388  
  389 + def _FireSpinMinChanged(self, evt):
  390 + if self.changed:
  391 + self._GenerateEvent(myEVT_THRESHOLD_CHANGED)
  392 +
385 393 def _FireSpinMaxChange(self, evt):
  394 + evt.Skip()
386 395 value = int(self.spin_max.GetValue())
387 396 if value != self.GetMaxValue():
388 397 self.SetMaxValue(value)
389 398 self._GenerateEvent(myEVT_THRESHOLD_CHANGING)
390 399  
  400 + def _FireSpinMaxChanged(self, evt):
  401 + if self.changed:
  402 + self._GenerateEvent(myEVT_THRESHOLD_CHANGED)
  403 +
391 404 def OnMinMouseWheel(self, e):
392 405 """
393 406 When the user wheel the mouse over min texbox
... ... @@ -464,6 +477,13 @@ class GradientCtrl(wx.Panel):
464 477 return self.minimun
465 478  
466 479 def _GenerateEvent(self, event):
  480 + if event == myEVT_THRESHOLD_CHANGING:
  481 + self.changed = True
  482 + print 'changing'
  483 + elif event == myEVT_THRESHOLD_CHANGED :
  484 + self.changed = False
  485 + print 'changed'
  486 +
467 487 evt = SliderEvent(event, self.GetId(), self.min_range,
468 488 self.max_range, self.minimun, self.maximun)
469 489 self.GetEventHandler().ProcessEvent(evt)
... ...
invesalius/project.py
... ... @@ -211,7 +211,7 @@ class Project(object):
211 211 # that we encode in utf-8.
212 212 filename = filename.encode('utf-8')
213 213 dir_temp = tempfile.mkdtemp(filename)
214   - filename_tmp = os.path.join(dir_temp, filename)
  214 + filename_tmp = os.path.join(dir_temp, 'matrix.dat')
215 215  
216 216 project = {}
217 217  
... ... @@ -220,18 +220,21 @@ class Project(object):
220 220 project[key] = {'#plist':
221 221 self.__dict__[key].SavePlist(filename_tmp).decode('utf-8')}
222 222 elif key == 'dicom_sample':
223   - sample_path = os.path.join(dir_temp, 'sample.dcm')
224   - shutil.copy(self.dicom_sample.parser.filename,sample_path)
225   - os.chmod(sample_path, stat.S_IREAD|stat.S_IWRITE)
  223 + #sample_path = os.path.join(dir_temp, 'sample.dcm')
  224 + #shutil.copy(self.dicom_sample.parser.filename,sample_path)
  225 + #os.chmod(sample_path, stat.S_IREAD|stat.S_IWRITE)
226 226  
227   - project[key] = 'sample.dcm'
  227 + #project[key] = 'sample.dcm'
  228 + pass
  229 + elif key.startswith('matrix'):
  230 + continue
228 231 else:
229 232 project[key] = self.__dict__[key]
230 233  
231 234 masks = {}
232 235 for index in self.mask_dict:
233 236 masks[str(index)] = {'#mask':\
234   - self.mask_dict[index].SavePlist(filename_tmp).decode('utf-8')}
  237 + self.mask_dict[index].SavePlist(filename_tmp)}
235 238  
236 239 surfaces = {}
237 240 for index in self.surface_dict:
... ... @@ -241,9 +244,10 @@ class Project(object):
241 244 project['surface_dict'] = surfaces
242 245 project['mask_dict'] = masks
243 246 project['measurement_dict'] = self.GetMeasuresDict()
244   - img_file = '%s_%s.vti' % (filename_tmp, 'imagedata')
245   - iu.Export(self.imagedata, img_file, bin=True)
246   - project['imagedata'] = {'$vti':os.path.split(img_file)[1].decode('utf-8')}
  247 + shutil.copyfile(self.matrix_filename, filename_tmp)
  248 + project['matrix'] = {'filename':os.path.split(filename_tmp)[1].decode('utf-8'),
  249 + 'shape': self.matrix_shape,
  250 + 'dtype': self.matrix_dtype}
247 251  
248 252 plistlib.writePlist(project, filename_tmp + '.plist')
249 253  
... ... @@ -268,23 +272,25 @@ class Project(object):
268 272 dirpath = os.path.abspath(os.path.split(filelist[0])[0])
269 273  
270 274 for key in project:
271   - if key == 'imagedata':
272   - filepath = os.path.split(project[key]["$vti"])[-1]
  275 + if key == 'matrix':
  276 + filepath = os.path.split(project[key]["filename"])[-1]
273 277 path = os.path.join(dirpath, filepath)
274   - self.imagedata = iu.Import(path)
  278 + self.matrix_filename = path
  279 + self.matrix_shape = project[key]['shape']
  280 + self.matrix_dtype = project[key]['dtype']
275 281 elif key == 'presets':
276 282 filepath = os.path.split(project[key]["#plist"])[-1]
277 283 path = os.path.join(dirpath, filepath)
278 284 p = Presets()
279 285 p.OpenPlist(path)
280 286 self.presets = p
281   - elif key == 'dicom_sample':
282   - path = os.path.join(dirpath, project[key])
283   - p = dicom.Parser()
284   - p.SetFileName(path)
285   - d = dicom.Dicom()
286   - d.SetParser(p)
287   - self.dicom_sample = d
  287 + #elif key == 'dicom_sample':
  288 + #path = os.path.join(dirpath, project[key])
  289 + #p = dicom.Parser()
  290 + #p.SetFileName(path)
  291 + #d = dicom.Dicom()
  292 + #d.SetParser(p)
  293 + #self.dicom_sample = d
288 294  
289 295 elif key == 'mask_dict':
290 296 self.mask_dict = {}
... ...