Commit eead43d517b427aecc929d52c37b41fa1c6ac599
1 parent
c010bda2
Exists in
master
and in
47 other branches
starting to clean slice_.py
Showing
1 changed file
with
18 additions
and
176 deletions
Show diff stats
invesalius/data/slice_.py
| @@ -16,7 +16,6 @@ | @@ -16,7 +16,6 @@ | ||
| 16 | # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | 16 | # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais |
| 17 | # detalhes. | 17 | # detalhes. |
| 18 | #-------------------------------------------------------------------------- | 18 | #-------------------------------------------------------------------------- |
| 19 | -import math | ||
| 20 | import os | 19 | import os |
| 21 | import tempfile | 20 | import tempfile |
| 22 | 21 | ||
| @@ -79,7 +78,6 @@ class Slice(object): | @@ -79,7 +78,6 @@ class Slice(object): | ||
| 79 | # Therefore, we use Singleton design pattern for implementing it. | 78 | # Therefore, we use Singleton design pattern for implementing it. |
| 80 | 79 | ||
| 81 | def __init__(self): | 80 | def __init__(self): |
| 82 | - self.imagedata = None | ||
| 83 | self.current_mask = None | 81 | self.current_mask = None |
| 84 | self.blend_filter = None | 82 | self.blend_filter = None |
| 85 | self.histogram = None | 83 | self.histogram = None |
| @@ -249,7 +247,6 @@ class Slice(object): | @@ -249,7 +247,6 @@ class Slice(object): | ||
| 249 | self.CloseProject() | 247 | self.CloseProject() |
| 250 | 248 | ||
| 251 | def CloseProject(self): | 249 | def CloseProject(self): |
| 252 | - self.imagedata = None | ||
| 253 | f = self._matrix.filename | 250 | f = self._matrix.filename |
| 254 | self._matrix._mmap.close() | 251 | self._matrix._mmap.close() |
| 255 | self._matrix = None | 252 | self._matrix = None |
| @@ -836,19 +833,12 @@ class Slice(object): | @@ -836,19 +833,12 @@ class Slice(object): | ||
| 836 | 833 | ||
| 837 | def SelectCurrentMask(self, index): | 834 | def SelectCurrentMask(self, index): |
| 838 | "Insert mask data, based on given index, into pipeline." | 835 | "Insert mask data, based on given index, into pipeline." |
| 839 | - # This condition is not necessary in Linux, only under mac and windows | ||
| 840 | - # because combobox event is binded when the same item is selected again. | ||
| 841 | - #if index != self.current_mask.index: | ||
| 842 | - print "SelectCurrentMask" | ||
| 843 | - print "index:", index | ||
| 844 | proj = Project() | 836 | proj = Project() |
| 845 | future_mask = proj.GetMask(index) | 837 | future_mask = proj.GetMask(index) |
| 846 | future_mask.is_shown = True | 838 | future_mask.is_shown = True |
| 847 | self.current_mask = future_mask | 839 | self.current_mask = future_mask |
| 848 | 840 | ||
| 849 | colour = future_mask.colour | 841 | colour = future_mask.colour |
| 850 | - #index = future_mask.index | ||
| 851 | - print index | ||
| 852 | self.SetMaskColour(index, colour, update=False) | 842 | self.SetMaskColour(index, colour, update=False) |
| 853 | 843 | ||
| 854 | self.buffer_slices = {"AXIAL": SliceBuffer(), | 844 | self.buffer_slices = {"AXIAL": SliceBuffer(), |
| @@ -871,18 +861,9 @@ class Slice(object): | @@ -871,18 +861,9 @@ class Slice(object): | ||
| 871 | proj = Project() | 861 | proj = Project() |
| 872 | mask = proj.mask_dict[surface_parameters['options']['index']] | 862 | mask = proj.mask_dict[surface_parameters['options']['index']] |
| 873 | 863 | ||
| 874 | - # This is very important. Do not use masks' imagedata. It would mess up | ||
| 875 | - # surface quality event when using contour | ||
| 876 | - #self.SetMaskThreshold(mask.index, threshold) | ||
| 877 | - for n in xrange(1, mask.matrix.shape[0]): | ||
| 878 | - if mask.matrix[n, 0, 0] == 0: | ||
| 879 | - m = mask.matrix[n, 1:, 1:] | ||
| 880 | - mask.matrix[n, 1:, 1:] = self.do_threshold_to_a_slice(self.matrix[n-1], m) | 864 | + self.do_threshold_to_all_slices(mask) |
| 865 | + Publisher.sendMessage('Create surface', (self, mask, surface_parameters)) | ||
| 881 | 866 | ||
| 882 | - mask.matrix.flush() | ||
| 883 | - | ||
| 884 | - Publisher.sendMessage('Create surface', (self, mask, | ||
| 885 | - surface_parameters)) | ||
| 886 | def GetOutput(self): | 867 | def GetOutput(self): |
| 887 | return self.blend_filter.GetOutput() | 868 | return self.blend_filter.GetOutput() |
| 888 | 869 | ||
| @@ -906,59 +887,6 @@ class Slice(object): | @@ -906,59 +887,6 @@ class Slice(object): | ||
| 906 | 887 | ||
| 907 | Publisher.sendMessage('Check projection menu', tprojection) | 888 | Publisher.sendMessage('Check projection menu', tprojection) |
| 908 | 889 | ||
| 909 | - def SetInput(self, imagedata, mask_dict): | ||
| 910 | - print "SETINPUT!" | ||
| 911 | - self.imagedata = imagedata | ||
| 912 | - self.extent = imagedata.GetExtent() | ||
| 913 | - | ||
| 914 | - imagedata_bg = self.__create_background(imagedata) | ||
| 915 | - | ||
| 916 | - if not mask_dict: | ||
| 917 | - imagedata_mask = self.__build_mask(imagedata, create=True) | ||
| 918 | - else: | ||
| 919 | - self.__load_masks(imagedata, mask_dict) | ||
| 920 | - imagedata_mask = self.img_colours_mask.GetOutput() | ||
| 921 | - | ||
| 922 | - mask_opacity = self.current_mask.opacity | ||
| 923 | - | ||
| 924 | - # blend both imagedatas, so it can be inserted into viewer | ||
| 925 | - blend_filter = vtk.vtkImageBlend() | ||
| 926 | - blend_filter.SetBlendModeToNormal() | ||
| 927 | - blend_filter.SetOpacity(0, 1) | ||
| 928 | - if self.current_mask.is_shown: | ||
| 929 | - blend_filter.SetOpacity(1, mask_opacity) | ||
| 930 | - else: | ||
| 931 | - blend_filter.SetOpacity(1, 0) | ||
| 932 | - blend_filter.SetInput(0, imagedata_bg) | ||
| 933 | - blend_filter.SetInput(1, imagedata_mask) | ||
| 934 | - blend_filter.SetBlendModeToNormal() | ||
| 935 | - blend_filter.GetOutput().ReleaseDataFlagOn() | ||
| 936 | - self.blend_filter = blend_filter | ||
| 937 | - | ||
| 938 | - self.window_level = vtk.vtkImageMapToWindowLevelColors() | ||
| 939 | - self.window_level.SetInput(self.imagedata) | ||
| 940 | - | ||
| 941 | - def __create_background(self, imagedata): | ||
| 942 | - thresh_min, thresh_max = imagedata.GetScalarRange() | ||
| 943 | - Publisher.sendMessage('Update threshold limits list', (thresh_min, | ||
| 944 | - thresh_max)) | ||
| 945 | - | ||
| 946 | - # map scalar values into colors | ||
| 947 | - lut_bg = self.lut_bg = vtk.vtkLookupTable() | ||
| 948 | - lut_bg.SetTableRange(thresh_min, thresh_max) | ||
| 949 | - lut_bg.SetSaturationRange(0, 0) | ||
| 950 | - lut_bg.SetHueRange(0, 0) | ||
| 951 | - lut_bg.SetValueRange(0, 1) | ||
| 952 | - lut_bg.Build() | ||
| 953 | - | ||
| 954 | - # map the input image through a lookup table | ||
| 955 | - img_colours_bg = self.img_colours_bg = vtk.vtkImageMapToColors() | ||
| 956 | - img_colours_bg.SetOutputFormatToRGBA() | ||
| 957 | - img_colours_bg.SetLookupTable(lut_bg) | ||
| 958 | - img_colours_bg.SetInput(imagedata) | ||
| 959 | - | ||
| 960 | - return img_colours_bg.GetOutput() | ||
| 961 | - | ||
| 962 | def UpdateWindowLevelBackground(self, pubsub_evt): | 890 | def UpdateWindowLevelBackground(self, pubsub_evt): |
| 963 | window, level = pubsub_evt.data | 891 | window, level = pubsub_evt.data |
| 964 | self.window_width = window | 892 | self.window_width = window |
| @@ -1030,15 +958,12 @@ class Slice(object): | @@ -1030,15 +958,12 @@ class Slice(object): | ||
| 1030 | cast.ClampOverflowOn() | 958 | cast.ClampOverflowOn() |
| 1031 | cast.Update() | 959 | cast.Update() |
| 1032 | 960 | ||
| 1033 | - #if (original_orientation == const.AXIAL): | ||
| 1034 | flip = vtk.vtkImageFlip() | 961 | flip = vtk.vtkImageFlip() |
| 1035 | flip.SetInput(cast.GetOutput()) | 962 | flip.SetInput(cast.GetOutput()) |
| 1036 | flip.SetFilteredAxis(1) | 963 | flip.SetFilteredAxis(1) |
| 1037 | flip.FlipAboutOriginOn() | 964 | flip.FlipAboutOriginOn() |
| 1038 | flip.Update() | 965 | flip.Update() |
| 1039 | widget.SetInput(flip.GetOutput()) | 966 | widget.SetInput(flip.GetOutput()) |
| 1040 | - #else: | ||
| 1041 | - #widget.SetInput(cast.GetOutput()) | ||
| 1042 | 967 | ||
| 1043 | def UpdateSlice3D(self, pubsub_evt): | 968 | def UpdateSlice3D(self, pubsub_evt): |
| 1044 | widget, orientation = pubsub_evt.data | 969 | widget, orientation = pubsub_evt.data |
| @@ -1111,27 +1036,6 @@ class Slice(object): | @@ -1111,27 +1036,6 @@ class Slice(object): | ||
| 1111 | Publisher.sendMessage('Change mask selected', mask.index) | 1036 | Publisher.sendMessage('Change mask selected', mask.index) |
| 1112 | Publisher.sendMessage('Update slice viewer') | 1037 | Publisher.sendMessage('Update slice viewer') |
| 1113 | 1038 | ||
| 1114 | - def __load_masks(self, imagedata, mask_dict): | ||
| 1115 | - keys = mask_dict.keys() | ||
| 1116 | - keys.sort() | ||
| 1117 | - for key in keys: | ||
| 1118 | - mask = mask_dict[key] | ||
| 1119 | - | ||
| 1120 | - # update gui related to mask | ||
| 1121 | - utils.debug("__load_masks") | ||
| 1122 | - utils.debug('THRESHOLD_RANGE %s'% mask.threshold_range) | ||
| 1123 | - Publisher.sendMessage('Add mask', | ||
| 1124 | - (mask.index, | ||
| 1125 | - mask.name, | ||
| 1126 | - mask.threshold_range, | ||
| 1127 | - mask.colour)) | ||
| 1128 | - | ||
| 1129 | - self.current_mask = mask | ||
| 1130 | - self.__build_mask(imagedata, False) | ||
| 1131 | - | ||
| 1132 | - Publisher.sendMessage('Change mask selected', mask.index) | ||
| 1133 | - Publisher.sendMessage('Update slice viewer') | ||
| 1134 | - | ||
| 1135 | def do_ww_wl(self, image): | 1039 | def do_ww_wl(self, image): |
| 1136 | if self.from_ == PLIST: | 1040 | if self.from_ == PLIST: |
| 1137 | lut = vtk.vtkWindowLevelLookupTable() | 1041 | lut = vtk.vtkWindowLevelLookupTable() |
| @@ -1212,12 +1116,16 @@ class Slice(object): | @@ -1212,12 +1116,16 @@ class Slice(object): | ||
| 1212 | m[mask == 254] = 254 | 1116 | m[mask == 254] = 254 |
| 1213 | return m.astype('uint8') | 1117 | return m.astype('uint8') |
| 1214 | 1118 | ||
| 1215 | - def do_threshold_to_all_slices(self): | ||
| 1216 | - mask = self.current_mask | 1119 | + def do_threshold_to_all_slices(self, mask=None): |
| 1120 | + """ | ||
| 1121 | + Apply threshold to all slices. | ||
| 1217 | 1122 | ||
| 1218 | - # This is very important. Do not use masks' imagedata. It would mess up | ||
| 1219 | - # surface quality event when using contour | ||
| 1220 | - #self.SetMaskThreshold(mask.index, threshold) | 1123 | + Params: |
| 1124 | + - mask: the mask where result of the threshold will be stored.If | ||
| 1125 | + None, it'll be the current mask. | ||
| 1126 | + """ | ||
| 1127 | + if mask is None: | ||
| 1128 | + mask = self.current_mask | ||
| 1221 | for n in xrange(1, mask.matrix.shape[0]): | 1129 | for n in xrange(1, mask.matrix.shape[0]): |
| 1222 | if mask.matrix[n, 0, 0] == 0: | 1130 | if mask.matrix[n, 0, 0] == 0: |
| 1223 | m = mask.matrix[n, 1:, 1:] | 1131 | m = mask.matrix[n, 1:, 1:] |
| @@ -1390,76 +1298,9 @@ class Slice(object): | @@ -1390,76 +1298,9 @@ class Slice(object): | ||
| 1390 | self.buffer_slices[o].discard_vtk_mask() | 1298 | self.buffer_slices[o].discard_vtk_mask() |
| 1391 | Publisher.sendMessage('Reload actual slice') | 1299 | Publisher.sendMessage('Reload actual slice') |
| 1392 | 1300 | ||
| 1393 | - def __build_mask(self, imagedata, create=True): | ||
| 1394 | - # create new mask instance and insert it into project | ||
| 1395 | - if create: | ||
| 1396 | - self.CreateMask(imagedata=imagedata) | ||
| 1397 | - current_mask = self.current_mask | ||
| 1398 | - | ||
| 1399 | - # properties to be inserted into pipeline | ||
| 1400 | - scalar_range = int(imagedata.GetScalarRange()[1]) | ||
| 1401 | - r,g,b = current_mask.colour | ||
| 1402 | - | ||
| 1403 | - # map scalar values into colors | ||
| 1404 | - lut_mask = vtk.vtkLookupTable() | ||
| 1405 | - lut_mask.SetNumberOfTableValues(1) | ||
| 1406 | - lut_mask.SetNumberOfColors(1) | ||
| 1407 | - lut_mask.SetHueRange(const.THRESHOLD_HUE_RANGE) | ||
| 1408 | - lut_mask.SetSaturationRange(1, 1) | ||
| 1409 | - lut_mask.SetValueRange(1, 1) | ||
| 1410 | - lut_mask.SetNumberOfTableValues(scalar_range) | ||
| 1411 | - lut_mask.SetTableValue(1, r, g, b, 1.0) | ||
| 1412 | - lut_mask.SetTableValue(scalar_range - 1, r, g, b, 1.0) | ||
| 1413 | - lut_mask.SetRampToLinear() | ||
| 1414 | - lut_mask.Build() | ||
| 1415 | - self.lut_mask = lut_mask | ||
| 1416 | - | ||
| 1417 | - mask_thresh_imagedata = self.__create_mask_threshold(imagedata) | ||
| 1418 | - | ||
| 1419 | - if create: | ||
| 1420 | - # threshold pipeline | ||
| 1421 | - current_mask.imagedata.DeepCopy(mask_thresh_imagedata) | ||
| 1422 | - else: | ||
| 1423 | - mask_thresh_imagedata = self.current_mask.imagedata | ||
| 1424 | - | ||
| 1425 | - # map the input image through a lookup table | ||
| 1426 | - img_colours_mask = vtk.vtkImageMapToColors() | ||
| 1427 | - img_colours_mask.SetOutputFormatToRGBA() | ||
| 1428 | - img_colours_mask.SetLookupTable(lut_mask) | ||
| 1429 | - | ||
| 1430 | - img_colours_mask.SetInput(mask_thresh_imagedata) | ||
| 1431 | - | ||
| 1432 | - self.img_colours_mask = img_colours_mask | ||
| 1433 | - | ||
| 1434 | - return img_colours_mask.GetOutput() | ||
| 1435 | - | ||
| 1436 | - def __create_mask_threshold(self, imagedata, threshold_range=None): | ||
| 1437 | - if not threshold_range: | ||
| 1438 | - thresh_min, thresh_max = self.current_mask.threshold_range | ||
| 1439 | - else: | ||
| 1440 | - thresh_min, thresh_max = threshold_range | ||
| 1441 | - | ||
| 1442 | - # flexible threshold | ||
| 1443 | - img_thresh_mask = vtk.vtkImageThreshold() | ||
| 1444 | - img_thresh_mask.SetInValue(const.THRESHOLD_INVALUE) | ||
| 1445 | - img_thresh_mask.SetInput(imagedata) | ||
| 1446 | - img_thresh_mask.SetOutValue(const.THRESHOLD_OUTVALUE) | ||
| 1447 | - img_thresh_mask.ThresholdBetween(float(thresh_min), float(thresh_max)) | ||
| 1448 | - img_thresh_mask.Update() | ||
| 1449 | - self.img_thresh_mask = img_thresh_mask | ||
| 1450 | - | ||
| 1451 | - # copy of threshold output | ||
| 1452 | - imagedata_mask = vtk.vtkImageData() | ||
| 1453 | - imagedata_mask.DeepCopy(img_thresh_mask.GetOutput()) | ||
| 1454 | - imagedata_mask.Update() | ||
| 1455 | - | ||
| 1456 | - return imagedata_mask | ||
| 1457 | - | ||
| 1458 | def _open_image_matrix(self, filename, shape, dtype): | 1301 | def _open_image_matrix(self, filename, shape, dtype): |
| 1459 | self.matrix_filename = filename | 1302 | self.matrix_filename = filename |
| 1460 | - print ">>>", filename | ||
| 1461 | - self.matrix = numpy.memmap(filename, shape=shape, dtype=dtype, | ||
| 1462 | - mode='r+') | 1303 | + self.matrix = numpy.memmap(filename, shape=shape, dtype=dtype, mode='r+') |
| 1463 | 1304 | ||
| 1464 | def OnFlipVolume(self, pubsub_evt): | 1305 | def OnFlipVolume(self, pubsub_evt): |
| 1465 | axis = pubsub_evt.data | 1306 | axis = pubsub_evt.data |
| @@ -1489,8 +1330,9 @@ class Slice(object): | @@ -1489,8 +1330,9 @@ class Slice(object): | ||
| 1489 | print type(self.matrix) | 1330 | print type(self.matrix) |
| 1490 | 1331 | ||
| 1491 | def OnExportMask(self, pubsub_evt): | 1332 | def OnExportMask(self, pubsub_evt): |
| 1492 | - #imagedata = self.current_mask.imagedata | ||
| 1493 | - imagedata = self.imagedata | ||
| 1494 | - filename, filetype = pubsub_evt.data | ||
| 1495 | - if (filetype == const.FILETYPE_IMAGEDATA): | ||
| 1496 | - iu.Export(imagedata, filename) | 1333 | + pass |
| 1334 | + ##imagedata = self.current_mask.imagedata | ||
| 1335 | + #imagedata = self.imagedata | ||
| 1336 | + #filename, filetype = pubsub_evt.data | ||
| 1337 | + #if (filetype == const.FILETYPE_IMAGEDATA): | ||
| 1338 | + #iu.Export(imagedata, filename) |