Commit b7a728d9f0c667ecd7584c8f8927074c0d165bf3

Authored by tfmoraes
1 parent 7b7b807a

Some cleaning in code

invesalius/data/slice_.py
... ... @@ -24,12 +24,13 @@ import wx.lib.pubsub as ps
24 24  
25 25 import constants as const
26 26 import imagedata_utils as iu
27   -from mask import Mask
28 27 import style as st
29   -from project import Project
30 28 import session as ses
31 29 import utils
32 30  
  31 +from mask import Mask
  32 +from project import Project
  33 +
33 34 class SliceBuffer(object):
34 35 """
35 36 This class is used as buffer that mantains the vtkImageData and numpy array
... ... @@ -169,14 +170,12 @@ class Slice(object):
169 170 edition_threshold_range = original_mask.edition_threshold_range,
170 171 edited_points = original_mask.edited_points)
171 172  
172   -
173 173 def OnEnableStyle(self, pubsub_evt):
174 174 state = pubsub_evt.data
175 175 if (state in const.SLICE_STYLES):
176 176 new_state = self.interaction_style.AddState(state)
177 177 ps.Publisher().sendMessage('Set slice interaction style', new_state)
178 178  
179   -
180 179 def OnDisableStyle(self, pubsub_evt):
181 180 state = pubsub_evt.data
182 181 if (state in const.SLICE_STYLES):
... ... @@ -186,7 +185,6 @@ class Slice(object):
186 185 if (state == const.SLICE_STATE_EDITOR):
187 186 ps.Publisher().sendMessage('Set interactor default cursor')
188 187  
189   -
190 188 def OnCloseProject(self, pubsub_evt):
191 189 self.CloseProject()
192 190  
... ... @@ -198,7 +196,6 @@ class Slice(object):
198 196 #self.blend_filter = None
199 197 #self.num_gradient = 0
200 198  
201   -
202 199 def __set_current_mask_threshold_limits(self, pubsub_evt):
203 200 thresh_min = pubsub_evt.data[0]
204 201 thresh_max = pubsub_evt.data[1]
... ... @@ -206,14 +203,9 @@ class Slice(object):
206 203 index = self.current_mask.index
207 204 self.SetMaskEditionThreshold(index, (thresh_min, thresh_max))
208 205  
209   -
210   -
211 206 #---------------------------------------------------------------------------
212 207 # BEGIN PUBSUB_EVT METHODS
213 208 #---------------------------------------------------------------------------
214   - #def __get_mask_data_for_surface_creation(self, pubsub_evt):
215   - # mask_index = pubsub_evt.data
216   - # CreateSurfaceFromIndex
217 209  
218 210 def __add_mask(self, pubsub_evt):
219 211 mask_name = pubsub_evt.data
... ... @@ -242,9 +234,6 @@ class Slice(object):
242 234 def __set_current_mask_threshold(self, evt_pubsub):
243 235 threshold_range = evt_pubsub.data
244 236 index = self.current_mask.index
245   - #self.SetMaskThreshold(index, threshold_range)
246   - #Clear edited points
247   - self.current_mask.edited_points = {}
248 237 self.num_gradient += 1
249 238 self.current_mask.matrix[:] = 0
250 239  
... ... @@ -256,8 +245,6 @@ class Slice(object):
256 245 self.SetMaskThreshold(index, threshold_range,
257 246 self.buffer_slices[orientation].index,
258 247 orientation)
259   - #Clear edited points
260   - self.current_mask.edited_points = {}
261 248 self.num_gradient += 1
262 249  
263 250 ps.Publisher().sendMessage('Reload actual slice')
... ... @@ -282,71 +269,8 @@ class Slice(object):
282 269 if self.current_mask:
283 270 index, value = pubsub_evt.data
284 271 self.ShowMask(index, value)
285   - #---------------------------------------------------------------------------
286   - def erase_mask_pixel(self, index, position, radius, orientation):
287   - mask = self.buffer_slices[orientation].mask
288   - image = self.buffer_slices[orientation].image
289   -
290   - if hasattr(position, '__iter__'):
291   - py, px = position
292   - if orientation == 'AXIAL':
293   - sx = self.spacing[0]
294   - sy = self.spacing[1]
295   - elif orientation == 'CORONAL':
296   - sx = self.spacing[0]
297   - sy = self.spacing[2]
298   - elif orientation == 'SAGITAL':
299   - sx = self.spacing[1]
300   - sy = self.spacing[2]
301   -
302   - else:
303   - if orientation == 'AXIAL':
304   - sx = self.spacing[0]
305   - sy = self.spacing[1]
306   - py = position / mask.shape[1]
307   - px = position % mask.shape[1]
308   - elif orientation == 'CORONAL':
309   - sx = self.spacing[0]
310   - sy = self.spacing[2]
311   - py = position / mask.shape[1]
312   - px = position % mask.shape[1]
313   - elif orientation == 'SAGITAL':
314   - sx = self.spacing[1]
315   - sy = self.spacing[2]
316   - py = position / mask.shape[1]
317   - px = position % mask.shape[1]
318   -
319   - xi = px - math.ceil(radius/sx)
320   - xf = px + math.ceil(radius/sx)
321   - yi = py - math.ceil(radius/sy)
322   - yf = py + math.ceil(radius/sy)
323   -
324   - if yi < 0:
325   - index = index[abs(yi):,:]
326   - yi = 0
327   - if yf > image.shape[0]:
328   - index = index[:index.shape[0]-(yf-image.shape[0]), :]
329   - yf = image.shape[0]
330   -
331   - if xi < 0:
332   - index = index[:,abs(xi):]
333   - xi = 0
334   - if xf > image.shape[1]:
335   - index = index[:,:index.shape[1]-(xf-image.shape[1])]
336   - xf = image.shape[1]
337   -
338   - # Verifying if the points is over the image array.
339   - if (not 0 < xi < image.shape[1] and not 0 < xf < image.shape[1]) or \
340   - (not 0 < yi < image.shape[0] and not 0 < yf < image.shape[0]):
341   - return
342   -
343   - roi_m = mask[yi:yf,xi:xf]
344   - roi_i = image[yi:yf, xi:xf]
345   -
346   - roi_m[index] = 1
347   - self.buffer_slices[orientation].discard_vtk_mask()
348 272  
349   - def edit_mask_pixel(self, index, position, radius, orientation):
  273 + def edit_mask_pixel(self, operation, index, position, radius, orientation):
350 274 mask = self.buffer_slices[orientation].mask
351 275 image = self.buffer_slices[orientation].image
352 276 thresh_min, thresh_max = self.current_mask.edition_threshold_range
... ... @@ -407,101 +331,17 @@ class Slice(object):
407 331 roi_m = mask[yi:yf,xi:xf]
408 332 roi_i = image[yi:yf, xi:xf]
409 333  
410   - # It's a trick to make points between threshold gets value 254
411   - # (1 * 253 + 1) and out ones gets value 1 (0 * 253 + 1).
412   - roi_m[index] = (((roi_i[index] >= thresh_min)
413   - & (roi_i[index] <= thresh_max)) * 253) + 1
  334 + if operation == const.BRUSH_THRESH:
  335 + # It's a trick to make points between threshold gets value 254
  336 + # (1 * 253 + 1) and out ones gets value 1 (0 * 253 + 1).
  337 + roi_m[index] = (((roi_i[index] >= thresh_min)
  338 + & (roi_i[index] <= thresh_max)) * 253) + 1
  339 + elif operation == const.BRUSH_DRAW:
  340 + roi_m[index] = 254
  341 + elif operation == const.BRUSH_ERASE:
  342 + roi_m[index] = 1
414 343 self.buffer_slices[orientation].discard_vtk_mask()
415 344  
416   - def add_mask_pixel(self, index, position, radius, orientation):
417   - #mask = self.buffer_slices[orientation].mask
418   - #if orientation == 'AXIAL':
419   - #sx = self.spacing[0]
420   - #sy = self.spacing[1]
421   - #py = position / mask.shape[1]
422   - #px = position % mask.shape[1]
423   - #elif orientation == 'CORONAL':
424   - #sx = self.spacing[0]
425   - #sy = self.spacing[2]
426   - #py = position / mask.shape[1]
427   - #px = position % mask.shape[1]
428   - #elif orientation == 'SAGITAL':
429   - #sx = self.spacing[1]
430   - #sy = self.spacing[2]
431   - #py = position / mask.shape[1]
432   - #px = position % mask.shape[1]
433   -
434   - #print "->px, py", px, py
435   - #print "->position", position
436   - #print '->shape', mask.shape
437   -
438   - #mask[py - radius / sy: py + radius / sy,
439   - #px - radius / sx: px + radius / sx] = 255
440   - #self.buffer_slices[orientation].discard_vtk_mask()
441   - mask = self.buffer_slices[orientation].mask
442   - image = self.buffer_slices[orientation].image
443   -
444   - if hasattr(position, '__iter__'):
445   - py, px = position
446   - if orientation == 'AXIAL':
447   - sx = self.spacing[0]
448   - sy = self.spacing[1]
449   - elif orientation == 'CORONAL':
450   - sx = self.spacing[0]
451   - sy = self.spacing[2]
452   - elif orientation == 'SAGITAL':
453   - sx = self.spacing[1]
454   - sy = self.spacing[2]
455   -
456   - else:
457   - if orientation == 'AXIAL':
458   - sx = self.spacing[0]
459   - sy = self.spacing[1]
460   - py = position / mask.shape[1]
461   - px = position % mask.shape[1]
462   - elif orientation == 'CORONAL':
463   - sx = self.spacing[0]
464   - sy = self.spacing[2]
465   - py = position / mask.shape[1]
466   - px = position % mask.shape[1]
467   - elif orientation == 'SAGITAL':
468   - sx = self.spacing[1]
469   - sy = self.spacing[2]
470   - py = position / mask.shape[1]
471   - px = position % mask.shape[1]
472   -
473   - xi = px - math.ceil(radius/sx)
474   - xf = px + math.ceil(radius/sx)
475   - yi = py - math.ceil(radius/sy)
476   - yf = py + math.ceil(radius/sy)
477   -
478   - if yi < 0:
479   - index = index[abs(yi):,:]
480   - yi = 0
481   - if yf > image.shape[0]:
482   - index = index[:index.shape[0]-(yf-image.shape[0]), :]
483   - yf = image.shape[0]
484   -
485   - if xi < 0:
486   - index = index[:,abs(xi):]
487   - xi = 0
488   - if xf > image.shape[1]:
489   - index = index[:,:index.shape[1]-(xf-image.shape[1])]
490   - xf = image.shape[1]
491   -
492   - # Verifying if the points is over the image array.
493   - if (not 0 < xi < image.shape[1] and not 0 < xf < image.shape[1]) or \
494   - (not 0 < yi < image.shape[0] and not 0 < yf < image.shape[0]):
495   - return
496   -
497   - roi_m = mask[yi:yf,xi:xf]
498   - roi_i = image[yi:yf, xi:xf]
499   -
500   - roi_m[index] = 254
501   - self.buffer_slices[orientation].discard_vtk_mask()
502   - #---------------------------------------------------------------------------
503   - # END PUBSUB_EVT METHODS
504   - #---------------------------------------------------------------------------
505 345  
506 346 def GetSlices(self, orientation, slice_number):
507 347 if self.buffer_slices[orientation].index == slice_number:
... ... @@ -566,7 +406,6 @@ class Slice(object):
566 406 """
567 407 It gets the from actual mask the given slice from given orientation
568 408 """
569   -
570 409 # It's necessary because the first position for each dimension from
571 410 # mask matrix is used as flags to control if the mask in the
572 411 # slice_number position has been generated.
... ... @@ -616,10 +455,6 @@ class Slice(object):
616 455 proj.mask_dict[index].colour = colour
617 456  
618 457 (r,g,b) = colour
619   - #scalar_range = int(self.imagedata.GetScalarRange()[1])
620   - #self.lut_mask.SetTableValue(0, 0, 0, 0, 0.0)
621   - #self.lut_mask.SetTableValue(scalar_range - 1, r, g, b, 1.0)
622   -
623 458 colour_wx = [r*255, g*255, b*255]
624 459 ps.Publisher().sendMessage('Change mask colour in notebook',
625 460 (index, (r,g,b)))
... ... @@ -633,7 +468,6 @@ class Slice(object):
633 468 session = ses.Session()
634 469 session.ChangeProject()
635 470  
636   -
637 471 def SetMaskName(self, index, name):
638 472 "Rename a mask given its index and the new name"
639 473 proj = Project()
... ... @@ -642,7 +476,6 @@ class Slice(object):
642 476 session = ses.Session()
643 477 session.ChangeProject()
644 478  
645   -
646 479 def SetMaskEditionThreshold(self, index, threshold_range):
647 480 "Set threshold bounds to be used while editing slice"
648 481 proj = Project()
... ... @@ -660,22 +493,7 @@ class Slice(object):
660 493 thresh_min, thresh_max = threshold_range
661 494  
662 495 if self.current_mask.index == index:
663   - ## Update pipeline (this must be here, so pipeline is not broken)
664   - #self.img_thresh_mask.SetInput(self.imagedata)
665   - #self.img_thresh_mask.ThresholdBetween(float(thresh_min),
666   - #float(thresh_max))
667   - #self.img_thresh_mask.Update()
668   -
669   - ## Create imagedata copy so the pipeline is not broken
670   - #imagedata = self.img_thresh_mask.GetOutput()
671   - #self.current_mask.imagedata.DeepCopy(imagedata)
672   - #self.current_mask.threshold_range = threshold_range
673   -
674   - ## Update pipeline (this must be here, so pipeline is not broken)
675   - #self.img_colours_mask.SetInput(self.current_mask.imagedata)
676   -
677 496 # TODO: find out a better way to do threshold
678   -
679 497 if slice_number is None:
680 498 for n, slice_ in enumerate(self.matrix):
681 499 m = numpy.ones(slice_.shape, self.current_mask.matrix.dtype)
... ... @@ -702,7 +520,6 @@ class Slice(object):
702 520 proj = Project()
703 521 proj.mask_dict[self.current_mask.index].threshold_range = threshold_range
704 522  
705   -
706 523 def ShowMask(self, index, value):
707 524 "Show a mask given its index and 'show' value (0: hide, other: show)"
708 525 proj = Project()
... ... @@ -713,45 +530,7 @@ class Slice(object):
713 530 buffer_.discard_mask()
714 531 ps.Publisher().sendMessage('Reload actual slice')
715 532 #---------------------------------------------------------------------------
716   - def ErasePixel(self, position):
717   - "Delete pixel, based on x, y and z position coordinates."
718   - x, y, z = round(position[0],0), round(position[1],0),position[2]
719   - colour = self.imagedata.GetScalarRange()[0]
720   - imagedata = self.current_mask.imagedata
721   - imagedata.SetScalarComponentFromDouble(x, y, z, 0, colour)
722   - self.current_mask.edited_points[(x, y, z)] = colour
723 533  
724   - session = ses.Session()
725   - session.ChangeProject()
726   -
727   -
728   - def DrawPixel(self, position, colour=None):
729   - "Draw pixel, based on x, y and z position coordinates."
730   - x, y, z = round(position[0],0), round(position[1],0),position[2]
731   - colour = self.imagedata.GetScalarRange()[1]
732   - imagedata = self.current_mask.imagedata
733   - imagedata.SetScalarComponentFromDouble(x, y, z, 0, colour)
734   - self.current_mask.edited_points[(x, y, z)] = colour
735   -
736   - session = ses.Session()
737   - session.ChangeProject()
738   -
739   -
740   - def EditPixelBasedOnThreshold(self, position):
741   - "Erase or draw pixel based on edition threshold range."
742   - x, y, z = round(position[0],0), round(position[1],0),position[2]
743   - colour = self.imagedata.GetScalarComponentAsDouble(x, y, z, 0)
744   - thresh_min, thresh_max = self.current_mask.edition_threshold_range
745   - if (colour >= thresh_min) and (colour <= thresh_max):
746   - self.DrawPixel(position, colour)
747   - else:
748   - self.ErasePixel(position)
749   -
750   - session = ses.Session()
751   - session.ChangeProject()
752   -
753   -
754   - #---------------------------------------------------------------------------
755 534 def SelectCurrentMask(self, index):
756 535 "Insert mask data, based on given index, into pipeline."
757 536 # This condition is not necessary in Linux, only under mac and windows
... ... @@ -805,6 +584,7 @@ class Slice(object):
805 584 return self.blend_filter.GetOutput()
806 585  
807 586 def SetInput(self, imagedata, mask_dict):
  587 + print "SETINPUT!"
808 588 self.imagedata = imagedata
809 589 self.extent = imagedata.GetExtent()
810 590  
... ... @@ -857,7 +637,6 @@ class Slice(object):
857 637 return img_colours_bg.GetOutput()
858 638  
859 639 def UpdateWindowLevelBackground(self, pubsub_evt):
860   -
861 640 window, level = pubsub_evt.data
862 641 self.window_width = window
863 642 self.window_level = level
... ... @@ -867,20 +646,6 @@ class Slice(object):
867 646  
868 647 ps.Publisher().sendMessage('Reload actual slice')
869 648  
870   - #window_level = self.window_level
871   -
872   - #if not((window == window_level.GetWindow()) and\
873   - #(level == window_level.GetLevel())):
874   -
875   - #window_level.SetWindow(window)
876   - #window_level.SetLevel(level)
877   - #window_level.SetOutputFormatToLuminance()
878   - #window_level.Update()
879   -
880   - #thresh_min, thresh_max = window_level.GetOutput().GetScalarRange()
881   - #self.lut_bg.SetTableRange(thresh_min, thresh_max)
882   - #self.img_colours_bg.SetInput(window_level.GetOutput())
883   -
884 649 def UpdateColourTableBackground(self, pubsub_evt):
885 650 values = pubsub_evt.data
886 651  
... ... @@ -925,39 +690,13 @@ class Slice(object):
925 690 future_mask.edition_threshold_range = edition_threshold_range
926 691 if edited_points:
927 692 future_mask.edited_points = edited_points
928   -
929   - ## this is not the first mask, so we will import data from old imagedata
930   - #if imagedata is None:
931   - #old_mask = self.current_mask
932   - #imagedata = old_mask.imagedata
933   - #future_mask.threshold_range = old_mask.threshold_range
934   -
935   - #if threshold_range:
936   - #future_mask.threshold_range = threshold_range
937   - #future_mask.imagedata = self.__create_mask_threshold(self.imagedata,
938   - #threshold_range)
939   - #else:
940   - #future_mask.imagedata = vtk.vtkImageData()
941   - #future_mask.imagedata.DeepCopy(imagedata)
942   - #future_mask.imagedata.Update()
943   -
944   -
945   - ## when this is not the first instance, user will have defined a name
946   - #if name is not None:
947   - #future_mask.name = name
948   - #if future_mask.is_shown:
949   - #self.blend_filter.SetOpacity(1, future_mask.opacity)
950   - #else:
951   - #self.blend_filter.SetOpacity(1, 0)
952   - #self.blend_filter.Update()
  693 + if threshold_range:
  694 + future_mask.threshold_range = threshold_range
953 695  
954 696 # insert new mask into project and retrieve its index
955 697 proj = Project()
956 698 index = proj.AddMask(future_mask)
957 699 future_mask.index = index
958   - #if threshold_range:
959   - #self.SetMaskThreshold(index, threshold_range)
960   - #future_mask.edited_points = {}
961 700  
962 701 ## update gui related to mask
963 702 ps.Publisher().sendMessage('Add mask',
... ... @@ -968,12 +707,9 @@ class Slice(object):
968 707  
969 708 self.current_mask = future_mask
970 709  
971   - print self.current_mask.matrix
972   -
973 710 ps.Publisher().sendMessage('Change mask selected', future_mask.index)
974 711 ps.Publisher().sendMessage('Update slice viewer')
975 712  
976   -
977 713 def __load_masks(self, imagedata, mask_dict):
978 714 keys = mask_dict.keys()
979 715 keys.sort()
... ... @@ -996,8 +732,6 @@ class Slice(object):
996 732 ps.Publisher().sendMessage('Update slice viewer')
997 733  
998 734 def do_ww_wl(self, image):
999   - print "WW, WL", self.window_width, self.window_level
1000   - print image.GetScalarRange()
1001 735 colorer = vtk.vtkImageMapToWindowLevelColors()
1002 736 colorer.SetInput(image)
1003 737 colorer.SetWindow(self.window_width)
... ... @@ -1049,9 +783,9 @@ class Slice(object):
1049 783 return img_colours_mask.GetOutput()
1050 784  
1051 785 def do_blend(self, imagedata, mask):
1052   - # blend both imagedatas, so it can be inserted into viewer
1053   - print "Blending Spacing", imagedata.GetSpacing(), mask.GetSpacing()
1054   -
  786 + """
  787 + blend image with the mask.
  788 + """
1055 789 blend_imagedata = vtk.vtkImageBlend()
1056 790 blend_imagedata.SetBlendModeToNormal()
1057 791 # blend_imagedata.SetOpacity(0, 1.0)
... ... @@ -1060,8 +794,6 @@ class Slice(object):
1060 794 blend_imagedata.AddInput(mask)
1061 795 blend_imagedata.Update()
1062 796  
1063   - # return colorer.GetOutput()
1064   -
1065 797 return blend_imagedata.GetOutput()
1066 798  
1067 799 def apply_slice_buffer_to_mask(self, orientation):
... ... @@ -1070,7 +802,6 @@ class Slice(object):
1070 802 """
1071 803 b_mask = self.buffer_slices[orientation].mask
1072 804 index = self.buffer_slices[orientation].index
1073   - print "-> ORIENTATION", orientation, index, b_mask
1074 805 if orientation == 'AXIAL':
1075 806 self.current_mask.matrix[index+1,1:,1:] = b_mask
1076 807 elif orientation == 'CORONAL':
... ... @@ -1127,7 +858,6 @@ class Slice(object):
1127 858  
1128 859 return img_colours_mask.GetOutput()
1129 860  
1130   -
1131 861 def __create_mask_threshold(self, imagedata, threshold_range=None):
1132 862 if not threshold_range:
1133 863 thresh_min, thresh_max = self.current_mask.threshold_range
... ... @@ -1150,7 +880,6 @@ class Slice(object):
1150 880  
1151 881 return imagedata_mask
1152 882  
1153   -
1154 883 def OnExportMask(self, pubsub_evt):
1155 884 #imagedata = self.current_mask.imagedata
1156 885 imagedata = self.imagedata
... ...
invesalius/data/viewer_slice.py
... ... @@ -634,19 +634,9 @@ class Viewer(wx.Panel):
634 634  
635 635 if position < 0:
636 636 position = self.calculate_matrix_position(coord)
637   -
638 637  
639   - # TODO: Call slice_ functions instead of to use pubsub message,
640   - # maybe we can get some performances improvements here.
641   - if self._brush_cursor_op == const.BRUSH_ERASE:
642   - self.slice_.erase_mask_pixel(cursor.GetPixels(), position, radius,
643   - self.orientation)
644   - elif self._brush_cursor_op == const.BRUSH_DRAW:
645   - self.slice_.add_mask_pixel(cursor.GetPixels(), position, radius,
646   - self.orientation)
647   - elif self._brush_cursor_op == const.BRUSH_THRESH:
648   - self.slice_.edit_mask_pixel(cursor.GetPixels(), position, radius,
649   - self.orientation)
  638 + self.slice_.edit_mask_pixel(self._brush_cursor_op, cursor.GetPixels(),
  639 + position, radius, self.orientation)
650 640  
651 641 # TODO: To create a new function to reload images to viewer.
652 642 self.OnScrollBar()
... ... @@ -685,18 +675,8 @@ class Viewer(wx.Panel):
685 675 if position < 0:
686 676 position = self.calculate_matrix_position(coord)
687 677  
688   -
689   - # TODO: Call slice_ functions instead of to use pubsub message,
690   - # maybe we can get some performances improvements here.
691   - if self._brush_cursor_op == const.BRUSH_ERASE:
692   - self.slice_.erase_mask_pixel(cursor.GetPixels(), position, radius,
693   - self.orientation)
694   - elif self._brush_cursor_op == const.BRUSH_DRAW:
695   - self.slice_.add_mask_pixel(cursor.GetPixels(), position, radius,
696   - self.orientation)
697   - elif self._brush_cursor_op == const.BRUSH_THRESH:
698   - self.slice_.edit_mask_pixel(cursor.GetPixels(), position, radius,
699   - self.orientation)
  678 + self.slice_.edit_mask_pixel(self._brush_cursor_op, cursor.GetPixels(),
  679 + position, radius, self.orientation)
700 680  
701 681 # TODO: To create a new function to reload images to viewer.
702 682 self.OnScrollBar()
... ...