Commit 87bb8b913bd958cd13016dc921c46d39ce44ca5e
Exists in
master
Merge branch 'master' into multimodal_tracking
# Conflicts: # invesalius/gui/task_navigator.py
Showing
11 changed files
with
70 additions
and
115 deletions
Show diff stats
invesalius/constants.py
@@ -828,7 +828,7 @@ TREKKER_CONFIG = {'seed_max': 1, 'step_size': 0.1, 'min_fod': 0.1, 'probe_qualit | @@ -828,7 +828,7 @@ TREKKER_CONFIG = {'seed_max': 1, 'step_size': 0.1, 'min_fod': 0.1, 'probe_qualit | ||
828 | 'write_interval': 50, 'numb_threads': '', 'max_lenth': 200, | 828 | 'write_interval': 50, 'numb_threads': '', 'max_lenth': 200, |
829 | 'min_lenth': 20, 'max_sampling_step': 100} | 829 | 'min_lenth': 20, 'max_sampling_step': 100} |
830 | 830 | ||
831 | -MARKER_FILE_MAGICK_STRING = "INVESALIUS3_MARKER_FILE_" | 831 | +MARKER_FILE_MAGICK_STRING = "##INVESALIUS3_MARKER_FILE_" |
832 | CURRENT_MARKER_FILE_VERSION = 0 | 832 | CURRENT_MARKER_FILE_VERSION = 0 |
833 | WILDCARD_MARKER_FILES = _("Marker scanner coord files (*.mkss)|*.mkss") | 833 | WILDCARD_MARKER_FILES = _("Marker scanner coord files (*.mkss)|*.mkss") |
834 | 834 |
invesalius/control.py
@@ -122,8 +122,6 @@ class Controller(): | @@ -122,8 +122,6 @@ class Controller(): | ||
122 | 122 | ||
123 | Publisher.subscribe(self.OnSaveProject, 'Save project') | 123 | Publisher.subscribe(self.OnSaveProject, 'Save project') |
124 | 124 | ||
125 | - Publisher.subscribe(self.Send_affine, 'Get affine matrix') | ||
126 | - | ||
127 | Publisher.subscribe(self.create_project_from_matrix, 'Create project from matrix') | 125 | Publisher.subscribe(self.create_project_from_matrix, 'Create project from matrix') |
128 | 126 | ||
129 | Publisher.subscribe(self.show_mask_preview, 'Show mask preview') | 127 | Publisher.subscribe(self.show_mask_preview, 'Show mask preview') |
@@ -506,8 +504,9 @@ class Controller(): | @@ -506,8 +504,9 @@ class Controller(): | ||
506 | utils.debug("No medical images found on given directory") | 504 | utils.debug("No medical images found on given directory") |
507 | return | 505 | return |
508 | 506 | ||
509 | - matrix, matrix_filename = self.OpenOtherFiles(group) | ||
510 | - self.CreateOtherProject(str(name[0]), matrix, matrix_filename) | 507 | + if group: |
508 | + matrix, matrix_filename = self.OpenOtherFiles(group) | ||
509 | + self.CreateOtherProject(str(name[0]), matrix, matrix_filename) | ||
511 | # OPTION 4: Nothing... | 510 | # OPTION 4: Nothing... |
512 | 511 | ||
513 | self.LoadProject() | 512 | self.LoadProject() |
@@ -623,6 +622,11 @@ class Controller(): | @@ -623,6 +622,11 @@ class Controller(): | ||
623 | Publisher.sendMessage(('Set scroll position', 'AXIAL'), index=proj.matrix_shape[0]/2) | 622 | Publisher.sendMessage(('Set scroll position', 'AXIAL'), index=proj.matrix_shape[0]/2) |
624 | Publisher.sendMessage(('Set scroll position', 'SAGITAL'),index=proj.matrix_shape[1]/2) | 623 | Publisher.sendMessage(('Set scroll position', 'SAGITAL'),index=proj.matrix_shape[1]/2) |
625 | Publisher.sendMessage(('Set scroll position', 'CORONAL'),index=proj.matrix_shape[2]/2) | 624 | Publisher.sendMessage(('Set scroll position', 'CORONAL'),index=proj.matrix_shape[2]/2) |
625 | + | ||
626 | + if self.Slice.affine is not None: | ||
627 | + Publisher.sendMessage('Enable Go-to-Coord', status=True) | ||
628 | + else: | ||
629 | + Publisher.sendMessage('Enable Go-to-Coord', status=False) | ||
626 | 630 | ||
627 | Publisher.sendMessage('End busy cursor') | 631 | Publisher.sendMessage('End busy cursor') |
628 | 632 | ||
@@ -715,9 +719,6 @@ class Controller(): | @@ -715,9 +719,6 @@ class Controller(): | ||
715 | proj.matrix_dtype = matrix.dtype.name | 719 | proj.matrix_dtype = matrix.dtype.name |
716 | proj.matrix_filename = matrix_filename | 720 | proj.matrix_filename = matrix_filename |
717 | 721 | ||
718 | - if self.affine is not None: | ||
719 | - proj.affine = self.affine.tolist() | ||
720 | - | ||
721 | # Orientation must be CORONAL in order to as_closes_canonical and | 722 | # Orientation must be CORONAL in order to as_closes_canonical and |
722 | # swap axis in img2memmap to work in a standardized way. | 723 | # swap axis in img2memmap to work in a standardized way. |
723 | # TODO: Create standard import image for all acquisition orientations | 724 | # TODO: Create standard import image for all acquisition orientations |
@@ -730,6 +731,8 @@ class Controller(): | @@ -730,6 +731,8 @@ class Controller(): | ||
730 | proj.level = self.Slice.window_level | 731 | proj.level = self.Slice.window_level |
731 | proj.threshold_range = int(matrix.min()), int(matrix.max()) | 732 | proj.threshold_range = int(matrix.min()), int(matrix.max()) |
732 | proj.spacing = self.Slice.spacing | 733 | proj.spacing = self.Slice.spacing |
734 | + if self.Slice.affine is not None: | ||
735 | + proj.affine = self.Slice.affine.tolist() | ||
733 | 736 | ||
734 | ###### | 737 | ###### |
735 | session = ses.Session() | 738 | session = ses.Session() |
@@ -915,16 +918,7 @@ class Controller(): | @@ -915,16 +918,7 @@ class Controller(): | ||
915 | matrix, matrix_filename = self.OpenOtherFiles(group) | 918 | matrix, matrix_filename = self.OpenOtherFiles(group) |
916 | self.CreateOtherProject(name, matrix, matrix_filename) | 919 | self.CreateOtherProject(name, matrix, matrix_filename) |
917 | self.LoadProject() | 920 | self.LoadProject() |
918 | - if group.affine.any(): | ||
919 | - # TODO: replace the inverse of the affine by the actual affine in the whole code | ||
920 | - # remove scaling factor for non-unitary voxel dimensions | ||
921 | - # self.affine = image_utils.world2invspace(affine=group.affine) | ||
922 | - scale, shear, angs, trans, persp = tr.decompose_matrix(group.affine) | ||
923 | - self.affine = np.linalg.inv(tr.compose_matrix(scale=None, shear=shear, | ||
924 | - angles=angs, translate=trans, perspective=persp)) | ||
925 | - # print("repos_img: {}".format(repos_img)) | ||
926 | - self.Slice.affine = self.affine | ||
927 | - Publisher.sendMessage('Update affine matrix', affine=self.affine) | 921 | + |
928 | Publisher.sendMessage("Enable state project", state=True) | 922 | Publisher.sendMessage("Enable state project", state=True) |
929 | else: | 923 | else: |
930 | dialog.ImportInvalidFiles(ftype="Others") | 924 | dialog.ImportInvalidFiles(ftype="Others") |
@@ -1034,13 +1028,7 @@ class Controller(): | @@ -1034,13 +1028,7 @@ class Controller(): | ||
1034 | self.matrix, scalar_range, self.filename = image_utils.img2memmap(group) | 1028 | self.matrix, scalar_range, self.filename = image_utils.img2memmap(group) |
1035 | 1029 | ||
1036 | hdr = group.header | 1030 | hdr = group.header |
1037 | - # if group.affine.any(): | ||
1038 | - # self.affine = group.affine | ||
1039 | - # Publisher.sendMessage('Update affine matrix', | ||
1040 | - # affine=self.affine, status=True) | ||
1041 | hdr.set_data_dtype('int16') | 1031 | hdr.set_data_dtype('int16') |
1042 | - dims = hdr.get_zooms() | ||
1043 | - dimsf = tuple([float(s) for s in dims]) | ||
1044 | 1032 | ||
1045 | wl = float((scalar_range[0] + scalar_range[1]) * 0.5) | 1033 | wl = float((scalar_range[0] + scalar_range[1]) * 0.5) |
1046 | ww = float((scalar_range[1] - scalar_range[0])) | 1034 | ww = float((scalar_range[1] - scalar_range[0])) |
@@ -1048,19 +1036,29 @@ class Controller(): | @@ -1048,19 +1036,29 @@ class Controller(): | ||
1048 | self.Slice = sl.Slice() | 1036 | self.Slice = sl.Slice() |
1049 | self.Slice.matrix = self.matrix | 1037 | self.Slice.matrix = self.matrix |
1050 | self.Slice.matrix_filename = self.filename | 1038 | self.Slice.matrix_filename = self.filename |
1051 | - | ||
1052 | - self.Slice.spacing = dimsf | 1039 | + # even though the axes 0 and 2 are swapped when creating self.matrix |
1040 | + # the spacing should be kept the original, as it is modified somewhere later | ||
1041 | + # otherwise generate wrong results | ||
1042 | + # also need to convert to float because original get_zooms return numpy.float32 | ||
1043 | + # which is unsupported by the plist for saving the project | ||
1044 | + self.Slice.spacing = tuple([float(s) for s in hdr.get_zooms()]) | ||
1053 | self.Slice.window_level = wl | 1045 | self.Slice.window_level = wl |
1054 | self.Slice.window_width = ww | 1046 | self.Slice.window_width = ww |
1055 | 1047 | ||
1048 | + if group.affine.any(): | ||
1049 | + # remove scaling factor for non-unitary voxel dimensions | ||
1050 | + scale, shear, angs, trans, persp = tr.decompose_matrix(group.affine) | ||
1051 | + self.Slice.affine = np.linalg.inv(tr.compose_matrix(scale=None, shear=shear, | ||
1052 | + angles=angs, translate=trans, perspective=persp)) | ||
1053 | + else: | ||
1054 | + self.Slice.affine = None | ||
1055 | + | ||
1056 | scalar_range = int(scalar_range[0]), int(scalar_range[1]) | 1056 | scalar_range = int(scalar_range[0]), int(scalar_range[1]) |
1057 | + | ||
1057 | Publisher.sendMessage('Update threshold limits list', | 1058 | Publisher.sendMessage('Update threshold limits list', |
1058 | threshold_range=scalar_range) | 1059 | threshold_range=scalar_range) |
1059 | - return self.matrix, self.filename | ||
1060 | 1060 | ||
1061 | - def Send_affine(self): | ||
1062 | - if self.affine is not None: | ||
1063 | - Publisher.sendMessage('Update affine matrix', affine=self.affine) | 1061 | + return self.matrix, self.filename |
1064 | 1062 | ||
1065 | def LoadImagedataInfo(self): | 1063 | def LoadImagedataInfo(self): |
1066 | proj = prj.Project() | 1064 | proj = prj.Project() |
invesalius/data/imagedata_utils.py
@@ -549,6 +549,17 @@ def get_LUT_value_255(data, window, level): | @@ -549,6 +549,17 @@ def get_LUT_value_255(data, window, level): | ||
549 | return data | 549 | return data |
550 | 550 | ||
551 | 551 | ||
552 | +def get_LUT_value(data, window, level): | ||
553 | + shape = data.shape | ||
554 | + data_ = data.ravel() | ||
555 | + data = np.piecewise(data_, | ||
556 | + [data_ <= (level - 0.5 - (window-1)/2), | ||
557 | + data_ > (level - 0.5 + (window-1)/2)], | ||
558 | + [0, window, lambda data_: ((data_ - (level - 0.5))/(window-1) + 0.5)*(window)]) | ||
559 | + data.shape = shape | ||
560 | + return data | ||
561 | + | ||
562 | + | ||
552 | def image_normalize(image, min_=0.0, max_=1.0, output_dtype=np.int16): | 563 | def image_normalize(image, min_=0.0, max_=1.0, output_dtype=np.int16): |
553 | output = np.empty(shape=image.shape, dtype=output_dtype) | 564 | output = np.empty(shape=image.shape, dtype=output_dtype) |
554 | imin, imax = image.min(), image.max() | 565 | imin, imax = image.min(), image.max() |
@@ -595,7 +606,7 @@ def convert_invesalius_to_voxel(position): | @@ -595,7 +606,7 @@ def convert_invesalius_to_voxel(position): | ||
595 | :return: a vector of 3 coordinates in the voxel space | 606 | :return: a vector of 3 coordinates in the voxel space |
596 | """ | 607 | """ |
597 | slice = sl.Slice() | 608 | slice = sl.Slice() |
598 | - return np.array((position[0], slice.matrix.shape[1] - position[1] - 1, position[2])) | 609 | + return np.array((position[0], slice.spacing[1]*(slice.matrix.shape[1] - 1) - position[1], position[2])) |
599 | 610 | ||
600 | 611 | ||
601 | def convert_invesalius_to_world(position, orientation): | 612 | def convert_invesalius_to_world(position, orientation): |
invesalius/data/styles.py
@@ -45,6 +45,7 @@ import invesalius.utils as utils | @@ -45,6 +45,7 @@ import invesalius.utils as utils | ||
45 | from invesalius.data.measures import (CircleDensityMeasure, MeasureData, | 45 | from invesalius.data.measures import (CircleDensityMeasure, MeasureData, |
46 | PolygonDensityMeasure) | 46 | PolygonDensityMeasure) |
47 | 47 | ||
48 | +from invesalius.data.imagedata_utils import get_LUT_value, get_LUT_value_255 | ||
48 | from invesalius_cy import floodfill | 49 | from invesalius_cy import floodfill |
49 | 50 | ||
50 | # For tracts | 51 | # For tracts |
@@ -69,26 +70,6 @@ WATERSHED_OPERATIONS = {_("Erase"): BRUSH_ERASE, | @@ -69,26 +70,6 @@ WATERSHED_OPERATIONS = {_("Erase"): BRUSH_ERASE, | ||
69 | _("Foreground"): BRUSH_FOREGROUND, | 70 | _("Foreground"): BRUSH_FOREGROUND, |
70 | _("Background"): BRUSH_BACKGROUND,} | 71 | _("Background"): BRUSH_BACKGROUND,} |
71 | 72 | ||
72 | -def get_LUT_value(data, window, level): | ||
73 | - shape = data.shape | ||
74 | - data_ = data.ravel() | ||
75 | - data = np.piecewise(data_, | ||
76 | - [data_ <= (level - 0.5 - (window-1)/2), | ||
77 | - data_ > (level - 0.5 + (window-1)/2)], | ||
78 | - [0, window, lambda data_: ((data_ - (level - 0.5))/(window-1) + 0.5)*(window)]) | ||
79 | - data.shape = shape | ||
80 | - return data | ||
81 | - | ||
82 | -def get_LUT_value_255(data, window, level): | ||
83 | - shape = data.shape | ||
84 | - data_ = data.ravel() | ||
85 | - data = np.piecewise(data_, | ||
86 | - [data_ <= (level - 0.5 - (window-1)/2), | ||
87 | - data_ > (level - 0.5 + (window-1)/2)], | ||
88 | - [0, 255, lambda data_: ((data_ - (level - 0.5))/(window-1) + 0.5)*(255)]) | ||
89 | - data.shape = shape | ||
90 | - return data | ||
91 | - | ||
92 | 73 | ||
93 | class BaseImageInteractorStyle(vtk.vtkInteractorStyleImage): | 74 | class BaseImageInteractorStyle(vtk.vtkInteractorStyleImage): |
94 | def __init__(self, viewer): | 75 | def __init__(self, viewer): |
invesalius/data/surface.py
@@ -51,6 +51,7 @@ else: | @@ -51,6 +51,7 @@ else: | ||
51 | 51 | ||
52 | import invesalius.constants as const | 52 | import invesalius.constants as const |
53 | import invesalius.data.imagedata_utils as iu | 53 | import invesalius.data.imagedata_utils as iu |
54 | +import invesalius.data.slice_ as sl | ||
54 | import invesalius.data.polydata_utils as pu | 55 | import invesalius.data.polydata_utils as pu |
55 | import invesalius.project as prj | 56 | import invesalius.project as prj |
56 | import invesalius.session as ses | 57 | import invesalius.session as ses |
@@ -159,7 +160,6 @@ class SurfaceManager(): | @@ -159,7 +160,6 @@ class SurfaceManager(): | ||
159 | def __init__(self): | 160 | def __init__(self): |
160 | self.actors_dict = {} | 161 | self.actors_dict = {} |
161 | self.last_surface_index = 0 | 162 | self.last_surface_index = 0 |
162 | - self.affine_vtk = None | ||
163 | self.convert2inv = None | 163 | self.convert2inv = None |
164 | self.__bind_events() | 164 | self.__bind_events() |
165 | 165 | ||
@@ -207,7 +207,6 @@ class SurfaceManager(): | @@ -207,7 +207,6 @@ class SurfaceManager(): | ||
207 | 207 | ||
208 | Publisher.subscribe(self.OnImportSurfaceFile, 'Import surface file') | 208 | Publisher.subscribe(self.OnImportSurfaceFile, 'Import surface file') |
209 | 209 | ||
210 | - Publisher.subscribe(self.UpdateAffineMatrix, 'Update affine matrix') | ||
211 | Publisher.subscribe(self.UpdateConvert2InvFlag, 'Update convert2inv flag') | 210 | Publisher.subscribe(self.UpdateConvert2InvFlag, 'Update convert2inv flag') |
212 | 211 | ||
213 | Publisher.subscribe(self.CreateSurfaceFromPolydata, 'Create surface from polydata') | 212 | Publisher.subscribe(self.CreateSurfaceFromPolydata, 'Create surface from polydata') |
@@ -338,16 +337,6 @@ class SurfaceManager(): | @@ -338,16 +337,6 @@ class SurfaceManager(): | ||
338 | name = os.path.splitext(os.path.split(filename)[-1])[0] | 337 | name = os.path.splitext(os.path.split(filename)[-1])[0] |
339 | self.CreateSurfaceFromPolydata(polydata, name=name, scalar=scalar) | 338 | self.CreateSurfaceFromPolydata(polydata, name=name, scalar=scalar) |
340 | 339 | ||
341 | - def UpdateAffineMatrix(self, affine): | ||
342 | - if affine is not None: | ||
343 | - prj_data = prj.Project() | ||
344 | - matrix_shape = tuple(prj_data.matrix_shape) | ||
345 | - affine = affine.copy() | ||
346 | - affine[1, -1] -= matrix_shape[1] | ||
347 | - self.affine_vtk = vtk_utils.numpy_to_vtkMatrix4x4(affine) | ||
348 | - else: | ||
349 | - self.affine_vtk = None | ||
350 | - | ||
351 | def UpdateConvert2InvFlag(self, convert2inv=False): | 340 | def UpdateConvert2InvFlag(self, convert2inv=False): |
352 | self.convert2inv = convert2inv | 341 | self.convert2inv = convert2inv |
353 | 342 | ||
@@ -373,12 +362,17 @@ class SurfaceManager(): | @@ -373,12 +362,17 @@ class SurfaceManager(): | ||
373 | actor.SetMapper(mapper) | 362 | actor.SetMapper(mapper) |
374 | actor.GetProperty().SetBackfaceCulling(1) | 363 | actor.GetProperty().SetBackfaceCulling(1) |
375 | 364 | ||
376 | - if self.convert2inv and (self.affine_vtk is not None): | ||
377 | - actor.SetUserMatrix(self.affine_vtk) | 365 | + if self.convert2inv: |
366 | + # convert between invesalius and world space with shift in the Y coordinate | ||
367 | + affine = sl.Slice().affine | ||
368 | + if affine is not None: | ||
369 | + affine[1, -1] -= sl.Slice().spacing[1] * (sl.Slice().matrix.shape[1] - 1) | ||
370 | + affine_vtk = vtk_utils.numpy_to_vtkMatrix4x4(affine) | ||
371 | + actor.SetUserMatrix(affine_vtk) | ||
378 | 372 | ||
379 | if overwrite: | 373 | if overwrite: |
380 | if index is None: | 374 | if index is None: |
381 | - index = self.last_surface_index | 375 | + index = self.last_surface_index |
382 | surface = Surface(index=index) | 376 | surface = Surface(index=index) |
383 | else: | 377 | else: |
384 | surface = Surface() | 378 | surface = Surface() |
invesalius/data/viewer_volume.py
@@ -1455,7 +1455,8 @@ class Viewer(wx.Panel): | @@ -1455,7 +1455,8 @@ class Viewer(wx.Panel): | ||
1455 | self.ren.RemoveActor(self.object_orientation_torus_actor) | 1455 | self.ren.RemoveActor(self.object_orientation_torus_actor) |
1456 | self.ren.RemoveActor(self.obj_projection_arrow_actor) | 1456 | self.ren.RemoveActor(self.obj_projection_arrow_actor) |
1457 | self.actor_peel = None | 1457 | self.actor_peel = None |
1458 | - self.ball_actor.SetVisibility(1) | 1458 | + if self.ball_actor: |
1459 | + self.ball_actor.SetVisibility(1) | ||
1459 | 1460 | ||
1460 | if flag and actor: | 1461 | if flag and actor: |
1461 | self.ren.AddActor(actor) | 1462 | self.ren.AddActor(actor) |
invesalius/gui/dialogs.py
@@ -4208,37 +4208,23 @@ class GoToDialogScannerCoord(wx.Dialog): | @@ -4208,37 +4208,23 @@ class GoToDialogScannerCoord(wx.Dialog): | ||
4208 | self.__bind_events() | 4208 | self.__bind_events() |
4209 | 4209 | ||
4210 | btn_ok.Bind(wx.EVT_BUTTON, self.OnOk) | 4210 | btn_ok.Bind(wx.EVT_BUTTON, self.OnOk) |
4211 | - Publisher.sendMessage('Get affine matrix') | ||
4212 | 4211 | ||
4213 | def __bind_events(self): | 4212 | def __bind_events(self): |
4214 | Publisher.subscribe(self.SetNewFocalPoint, 'Cross focal point') | 4213 | Publisher.subscribe(self.SetNewFocalPoint, 'Cross focal point') |
4215 | - Publisher.subscribe(self.UpdateAffineMatrix, 'Update affine matrix') | ||
4216 | - | ||
4217 | - def UpdateAffineMatrix(self, affine): | ||
4218 | - self.affine = affine | ||
4219 | 4214 | ||
4220 | def SetNewFocalPoint(self, coord, spacing): | 4215 | def SetNewFocalPoint(self, coord, spacing): |
4221 | Publisher.sendMessage('Update cross pos', coord=self.result*spacing) | 4216 | Publisher.sendMessage('Update cross pos', coord=self.result*spacing) |
4222 | 4217 | ||
4223 | def OnOk(self, evt): | 4218 | def OnOk(self, evt): |
4224 | - from numpy.linalg import inv | ||
4225 | import invesalius.data.slice_ as slc | 4219 | import invesalius.data.slice_ as slc |
4226 | try: | 4220 | try: |
4227 | - #get affine from image import | ||
4228 | - if self.affine is not None: | ||
4229 | - affine = self.affine | ||
4230 | - #get affine from project | ||
4231 | - else: | ||
4232 | - from invesalius.project import Project | ||
4233 | - affine = Project().affine | ||
4234 | - | ||
4235 | point = [float(self.goto_sagital.GetValue()), | 4221 | point = [float(self.goto_sagital.GetValue()), |
4236 | float(self.goto_coronal.GetValue()), | 4222 | float(self.goto_coronal.GetValue()), |
4237 | float(self.goto_axial.GetValue())] | 4223 | float(self.goto_axial.GetValue())] |
4238 | 4224 | ||
4239 | # transformation from scanner coordinates to inv coord system | 4225 | # transformation from scanner coordinates to inv coord system |
4240 | - affine = inv(affine) | ||
4241 | - self.result = np.dot(affine[:3, :3], np.transpose(point[0:3])) + affine[:3, 3] | 4226 | + affine_inverse = np.linalg.inv(slc.Slice().affine) |
4227 | + self.result = np.dot(affine_inverse[:3, :3], np.transpose(point[0:3])) + affine_inverse[:3, 3] | ||
4242 | self.result[1] = slc.Slice().GetMaxSliceNumber(const.CORONAL_STR) - self.result[1] | 4228 | self.result[1] = slc.Slice().GetMaxSliceNumber(const.CORONAL_STR) - self.result[1] |
4243 | 4229 | ||
4244 | Publisher.sendMessage('Update status text in GUI', label=_("Calculating the transformation ...")) | 4230 | Publisher.sendMessage('Update status text in GUI', label=_("Calculating the transformation ...")) |
invesalius/gui/frame.py
@@ -892,7 +892,7 @@ class MenuBar(wx.MenuBar): | @@ -892,7 +892,7 @@ class MenuBar(wx.MenuBar): | ||
892 | sub(self.OnEnableState, "Enable state project") | 892 | sub(self.OnEnableState, "Enable state project") |
893 | sub(self.OnEnableUndo, "Enable undo") | 893 | sub(self.OnEnableUndo, "Enable undo") |
894 | sub(self.OnEnableRedo, "Enable redo") | 894 | sub(self.OnEnableRedo, "Enable redo") |
895 | - sub(self.OnEnableGotoCoord, "Update affine matrix") | 895 | + sub(self.OnEnableGotoCoord, "Enable Go-to-Coord") |
896 | sub(self.OnEnableNavigation, "Navigation status") | 896 | sub(self.OnEnableNavigation, "Navigation status") |
897 | 897 | ||
898 | sub(self.OnAddMask, "Add mask") | 898 | sub(self.OnAddMask, "Add mask") |
@@ -1242,15 +1242,13 @@ class MenuBar(wx.MenuBar): | @@ -1242,15 +1242,13 @@ class MenuBar(wx.MenuBar): | ||
1242 | else: | 1242 | else: |
1243 | self.FindItemById(wx.ID_REDO).Enable(False) | 1243 | self.FindItemById(wx.ID_REDO).Enable(False) |
1244 | 1244 | ||
1245 | - def OnEnableGotoCoord(self, affine): | 1245 | + def OnEnableGotoCoord(self, status=True): |
1246 | """ | 1246 | """ |
1247 | - Disable goto coord either if there is no affine matrix or affine is wrongly imported. | ||
1248 | - :param status: Affine matrix status | 1247 | + Enable or disable goto coord depending on the imported affine matrix. |
1248 | + :param status: True for enabling and False for disabling the Go-To-Coord | ||
1249 | """ | 1249 | """ |
1250 | - if affine is not None: | ||
1251 | - self.FindItemById(const.ID_GOTO_COORD).Enable(True) | ||
1252 | - else: | ||
1253 | - self.FindItemById(const.ID_GOTO_COORD).Enable(False) | 1250 | + |
1251 | + self.FindItemById(const.ID_GOTO_COORD).Enable(status) | ||
1254 | 1252 | ||
1255 | def OnEnableNavigation(self, nav_status, vis_status): | 1253 | def OnEnableNavigation(self, nav_status, vis_status): |
1256 | """ | 1254 | """ |
invesalius/gui/task_navigator.py
@@ -691,8 +691,8 @@ class NeuronavigationPanel(wx.Panel): | @@ -691,8 +691,8 @@ class NeuronavigationPanel(wx.Panel): | ||
691 | size = 2 | 691 | size = 2 |
692 | seed = 3 * [0.] | 692 | seed = 3 * [0.] |
693 | 693 | ||
694 | - Publisher.sendMessage('Create marker', coord=coord, colour=colour, size=size, label=label, seed=seed) | ||
695 | - | 694 | + Publisher.sendMessage('Create marker', coord=coord, colour=colour, size=size, |
695 | + label=label, seed=seed) | ||
696 | else: | 696 | else: |
697 | for m in [0, 1, 2]: | 697 | for m in [0, 1, 2]: |
698 | self.numctrls_fiducial[n][m].SetValue(float(self.current_coord[m])) | 698 | self.numctrls_fiducial[n][m].SetValue(float(self.current_coord[m])) |
@@ -1189,11 +1189,11 @@ class MarkersPanel(wx.Panel): | @@ -1189,11 +1189,11 @@ class MarkersPanel(wx.Panel): | ||
1189 | res += '\t'.join(map(lambda x: 'N/A' if x is None else str(x), (*position_world, *orientation_world))) | 1189 | res += '\t'.join(map(lambda x: 'N/A' if x is None else str(x), (*position_world, *orientation_world))) |
1190 | return res | 1190 | return res |
1191 | 1191 | ||
1192 | - def from_string(self, str): | ||
1193 | - """Deserialize from a tab-separated string. If the string is not | 1192 | + def from_string(self, inp_str): |
1193 | + """Deserialize from a tab-separated string. If the string is not | ||
1194 | properly formatted, might throw an exception and leave the object | 1194 | properly formatted, might throw an exception and leave the object |
1195 | in an inconsistent state.""" | 1195 | in an inconsistent state.""" |
1196 | - for field, str_val in zip(dataclasses.fields(self.__class__), str.split('\t')): | 1196 | + for field, str_val in zip(dataclasses.fields(self.__class__), inp_str.split('\t')): |
1197 | if field.type is float: | 1197 | if field.type is float: |
1198 | setattr(self, field.name, float(str_val)) | 1198 | setattr(self, field.name, float(str_val)) |
1199 | if field.type is int: | 1199 | if field.type is int: |
@@ -1294,7 +1294,7 @@ class MarkersPanel(wx.Panel): | @@ -1294,7 +1294,7 @@ class MarkersPanel(wx.Panel): | ||
1294 | self.lc.InsertColumn(1, 'X') | 1294 | self.lc.InsertColumn(1, 'X') |
1295 | self.lc.InsertColumn(2, 'Y') | 1295 | self.lc.InsertColumn(2, 'Y') |
1296 | self.lc.InsertColumn(3, 'Z') | 1296 | self.lc.InsertColumn(3, 'Z') |
1297 | - self.lc.InsertColumn(4, 'ID') | 1297 | + self.lc.InsertColumn(4, 'Label') |
1298 | self.lc.InsertColumn(5, 'Target') | 1298 | self.lc.InsertColumn(5, 'Target') |
1299 | self.lc.InsertColumn(6, 'Session') | 1299 | self.lc.InsertColumn(6, 'Session') |
1300 | 1300 | ||
@@ -2125,7 +2125,7 @@ class SessionPanel(wx.Panel): | @@ -2125,7 +2125,7 @@ class SessionPanel(wx.Panel): | ||
2125 | except AttributeError: | 2125 | except AttributeError: |
2126 | default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) | 2126 | default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) |
2127 | self.SetBackgroundColour(default_colour) | 2127 | self.SetBackgroundColour(default_colour) |
2128 | - | 2128 | + |
2129 | # session count spinner | 2129 | # session count spinner |
2130 | self.__spin_session = wx.SpinCtrl(self, -1, "", size=wx.Size(40, 23)) | 2130 | self.__spin_session = wx.SpinCtrl(self, -1, "", size=wx.Size(40, 23)) |
2131 | self.__spin_session.SetRange(1, 99) | 2131 | self.__spin_session.SetRange(1, 99) |
@@ -2133,13 +2133,13 @@ class SessionPanel(wx.Panel): | @@ -2133,13 +2133,13 @@ class SessionPanel(wx.Panel): | ||
2133 | 2133 | ||
2134 | self.__spin_session.Bind(wx.EVT_TEXT, self.OnSessionChanged) | 2134 | self.__spin_session.Bind(wx.EVT_TEXT, self.OnSessionChanged) |
2135 | self.__spin_session.Bind(wx.EVT_SPINCTRL, self.OnSessionChanged) | 2135 | self.__spin_session.Bind(wx.EVT_SPINCTRL, self.OnSessionChanged) |
2136 | - | 2136 | + |
2137 | sizer_create = wx.FlexGridSizer(rows=1, cols=1, hgap=5, vgap=5) | 2137 | sizer_create = wx.FlexGridSizer(rows=1, cols=1, hgap=5, vgap=5) |
2138 | sizer_create.AddMany([(self.__spin_session, 1)]) | 2138 | sizer_create.AddMany([(self.__spin_session, 1)]) |
2139 | 2139 | ||
2140 | def OnSessionChanged(self, evt): | 2140 | def OnSessionChanged(self, evt): |
2141 | Publisher.sendMessage('Current session changed', new_session_id=self.__spin_session.GetValue()) | 2141 | Publisher.sendMessage('Current session changed', new_session_id=self.__spin_session.GetValue()) |
2142 | - | 2142 | + |
2143 | 2143 | ||
2144 | class InputAttributes(object): | 2144 | class InputAttributes(object): |
2145 | # taken from https://stackoverflow.com/questions/2466191/set-attributes-from-dictionary-in-python | 2145 | # taken from https://stackoverflow.com/questions/2466191/set-attributes-from-dictionary-in-python |
invesalius/project.py
@@ -329,8 +329,6 @@ class Project(metaclass=Singleton): | @@ -329,8 +329,6 @@ class Project(metaclass=Singleton): | ||
329 | 329 | ||
330 | if project.get("affine", ""): | 330 | if project.get("affine", ""): |
331 | self.affine = project["affine"] | 331 | self.affine = project["affine"] |
332 | - Publisher.sendMessage('Update affine matrix', | ||
333 | - affine=np.asarray(self.affine).reshape(4, 4)) | ||
334 | 332 | ||
335 | # Opening the masks | 333 | # Opening the masks |
336 | self.mask_dict = TwoWaysDictionary() | 334 | self.mask_dict = TwoWaysDictionary() |
invesalius/segmentation/brain/segment.py
@@ -22,17 +22,6 @@ SIZE = 48 | @@ -22,17 +22,6 @@ SIZE = 48 | ||
22 | OVERLAP = SIZE // 2 + 1 | 22 | OVERLAP = SIZE // 2 + 1 |
23 | 23 | ||
24 | 24 | ||
25 | -def get_LUT_value(data, window, level): | ||
26 | - shape = data.shape | ||
27 | - data_ = data.ravel() | ||
28 | - data = np.piecewise(data_, | ||
29 | - [data_ <= (level - 0.5 - (window-1)/2), | ||
30 | - data_ > (level - 0.5 + (window-1)/2)], | ||
31 | - [0, window, lambda data_: ((data_ - (level - 0.5))/(window-1) + 0.5)*(window)]) | ||
32 | - data.shape = shape | ||
33 | - return data | ||
34 | - | ||
35 | - | ||
36 | def gen_patches(image, patch_size, overlap): | 25 | def gen_patches(image, patch_size, overlap): |
37 | sz, sy, sx = image.shape | 26 | sz, sy, sx = image.shape |
38 | i_cuts = list( | 27 | i_cuts = list( |
@@ -188,8 +177,7 @@ class SegmentProcess(ctx.Process): | @@ -188,8 +177,7 @@ class SegmentProcess(ctx.Process): | ||
188 | ) | 177 | ) |
189 | 178 | ||
190 | if self.apply_wwwl: | 179 | if self.apply_wwwl: |
191 | - print("Applying window level") | ||
192 | - image = get_LUT_value(image, self.window_width, self.window_level) | 180 | + image = imagedata_utils.get_LUT_value(image, self.window_width, self.window_level) |
193 | 181 | ||
194 | probability_array = np.memmap( | 182 | probability_array = np.memmap( |
195 | self._prob_array_filename, | 183 | self._prob_array_filename, |