Commit 379a62714282b82147d84134864df41cc1975b1e
1 parent
6d9e7e2a
Exists in
master
Using the resample method to calculate the final image size when rescaling (closes #126)
Showing
1 changed file
with
54 additions
and
60 deletions
Show diff stats
invesalius/data/imagedata_utils.py
@@ -27,7 +27,7 @@ import vtk | @@ -27,7 +27,7 @@ import vtk | ||
27 | import vtkgdcm | 27 | import vtkgdcm |
28 | from wx.lib.pubsub import pub as Publisher | 28 | from wx.lib.pubsub import pub as Publisher |
29 | 29 | ||
30 | -from scipy.ndimage import shift | 30 | +from scipy.ndimage import shift, zoom |
31 | from vtk.util import numpy_support | 31 | from vtk.util import numpy_support |
32 | 32 | ||
33 | import invesalius.constants as const | 33 | import invesalius.constants as const |
@@ -69,20 +69,20 @@ def ResampleImage2D(imagedata, px=None, py=None, resolution_percentage = None, | @@ -69,20 +69,20 @@ def ResampleImage2D(imagedata, px=None, py=None, resolution_percentage = None, | ||
69 | dimensions = imagedata.GetDimensions() | 69 | dimensions = imagedata.GetDimensions() |
70 | 70 | ||
71 | if resolution_percentage: | 71 | if resolution_percentage: |
72 | - px = math.ceil(dimensions[0] * resolution_percentage) | ||
73 | - py = math.ceil(dimensions[1] * resolution_percentage) | ||
74 | - | ||
75 | - if abs(extent[1]-extent[3]) < abs(extent[3]-extent[5]): | ||
76 | - f = extent[1] | ||
77 | - elif abs(extent[1]-extent[5]) < abs(extent[1] - extent[3]): | ||
78 | - f = extent[1] | ||
79 | - elif abs(extent[3]-extent[5]) < abs(extent[1] - extent[3]): | ||
80 | - f = extent[3] | 72 | + factor_x = resolution_percentage |
73 | + factor_y = resolution_percentage | ||
81 | else: | 74 | else: |
82 | - f = extent[1] | 75 | + if abs(extent[1]-extent[3]) < abs(extent[3]-extent[5]): |
76 | + f = extent[1] | ||
77 | + elif abs(extent[1]-extent[5]) < abs(extent[1] - extent[3]): | ||
78 | + f = extent[1] | ||
79 | + elif abs(extent[3]-extent[5]) < abs(extent[1] - extent[3]): | ||
80 | + f = extent[3] | ||
81 | + else: | ||
82 | + f = extent[1] | ||
83 | 83 | ||
84 | - factor_x = px/float(f+1) | ||
85 | - factor_y = py/float(f+1) | 84 | + factor_x = px/float(f+1) |
85 | + factor_y = py/float(f+1) | ||
86 | 86 | ||
87 | resample = vtk.vtkImageResample() | 87 | resample = vtk.vtkImageResample() |
88 | resample.SetInputData(imagedata) | 88 | resample.SetInputData(imagedata) |
@@ -98,6 +98,35 @@ def ResampleImage2D(imagedata, px=None, py=None, resolution_percentage = None, | @@ -98,6 +98,35 @@ def ResampleImage2D(imagedata, px=None, py=None, resolution_percentage = None, | ||
98 | 98 | ||
99 | return resample.GetOutput() | 99 | return resample.GetOutput() |
100 | 100 | ||
101 | + | ||
102 | +def resize_slice(im_array, resolution_percentage): | ||
103 | + """ | ||
104 | + Uses ndimage.zoom to resize a slice. | ||
105 | + | ||
106 | + input: | ||
107 | + im_array: slice as a numpy array. | ||
108 | + resolution_percentage: percentage of resize. | ||
109 | + """ | ||
110 | + out = zoom(im_array, resolution_percentage, im_array.dtype, order=2) | ||
111 | + return out | ||
112 | + | ||
113 | + | ||
114 | +def read_dcm_slice_as_np(filename, resolution_percentage=1.0): | ||
115 | + """ | ||
116 | + read a dicom slice file and return the slice as numpy ndarray | ||
117 | + """ | ||
118 | + dcm_reader = vtkgdcm.vtkGDCMImageReader() | ||
119 | + dcm_reader.SetFileName(filename) | ||
120 | + dcm_reader.Update() | ||
121 | + image = dcm_reader.GetOutput() | ||
122 | + if resolution_percentage < 1.0: | ||
123 | + image = ResampleImage2D(image, resolution_percentage=resolution_percentage) | ||
124 | + dx, dy, dz = image.GetDimensions() | ||
125 | + im_array = numpy_support.vtk_to_numpy(image.GetPointData().GetScalars()) | ||
126 | + im_array.shape = dy, dx | ||
127 | + return im_array | ||
128 | + | ||
129 | + | ||
101 | def FixGantryTilt(matrix, spacing, tilt): | 130 | def FixGantryTilt(matrix, spacing, tilt): |
102 | """ | 131 | """ |
103 | Fix gantry tilt given a vtkImageData and the tilt value. Return new | 132 | Fix gantry tilt given a vtkImageData and the tilt value. Return new |
@@ -525,70 +554,35 @@ def dcm2memmap(files, slice_size, orientation, resolution_percentage): | @@ -525,70 +554,35 @@ def dcm2memmap(files, slice_size, orientation, resolution_percentage): | ||
525 | message = _("Generating multiplanar visualization...") | 554 | message = _("Generating multiplanar visualization...") |
526 | update_progress= vtk_utils.ShowProgress(len(files) - 1, dialog_type = "ProgressDialog") | 555 | update_progress= vtk_utils.ShowProgress(len(files) - 1, dialog_type = "ProgressDialog") |
527 | 556 | ||
557 | + first_slice = read_dcm_slice_as_np(files[0], resolution_percentage) | ||
558 | + slice_size = first_slice.shape[::-1] | ||
559 | + | ||
528 | temp_file = tempfile.mktemp() | 560 | temp_file = tempfile.mktemp() |
529 | 561 | ||
530 | if orientation == 'SAGITTAL': | 562 | if orientation == 'SAGITTAL': |
531 | - if resolution_percentage == 1.0: | ||
532 | - shape = slice_size[0], slice_size[1], len(files) | ||
533 | - else: | ||
534 | - shape = int(math.ceil(slice_size[0]*resolution_percentage)),\ | ||
535 | - int(math.ceil(slice_size[1]*resolution_percentage)), len(files) | ||
536 | - | 563 | + shape = slice_size[0], slice_size[1], len(files) |
537 | elif orientation == 'CORONAL': | 564 | elif orientation == 'CORONAL': |
538 | - if resolution_percentage == 1.0: | ||
539 | - shape = slice_size[1], len(files), slice_size[0] | ||
540 | - else: | ||
541 | - shape = int(math.ceil(slice_size[1]*resolution_percentage)), len(files),\ | ||
542 | - int(math.ceil(slice_size[0]*resolution_percentage)) | 565 | + shape = slice_size[1], len(files), slice_size[0] |
543 | else: | 566 | else: |
544 | - if resolution_percentage == 1.0: | ||
545 | - shape = len(files), slice_size[1], slice_size[0] | ||
546 | - else: | ||
547 | - shape = len(files), int(math.ceil(slice_size[1]*resolution_percentage)),\ | ||
548 | - int(math.ceil(slice_size[0]*resolution_percentage)) | 567 | + shape = len(files), slice_size[1], slice_size[0] |
549 | 568 | ||
550 | matrix = numpy.memmap(temp_file, mode='w+', dtype='int16', shape=shape) | 569 | matrix = numpy.memmap(temp_file, mode='w+', dtype='int16', shape=shape) |
551 | - dcm_reader = vtkgdcm.vtkGDCMImageReader() | ||
552 | - cont = 0 | ||
553 | - max_scalar = None | ||
554 | - min_scalar = None | ||
555 | - | ||
556 | for n, f in enumerate(files): | 570 | for n, f in enumerate(files): |
557 | - dcm_reader.SetFileName(f) | ||
558 | - dcm_reader.Update() | ||
559 | - image = dcm_reader.GetOutput() | ||
560 | - | ||
561 | - if resolution_percentage != 1.0: | ||
562 | - image_resized = ResampleImage2D(image, px=None, py=None,\ | ||
563 | - resolution_percentage = resolution_percentage, update_progress = None) | ||
564 | - | ||
565 | - image = image_resized | ||
566 | - | ||
567 | - min_aux, max_aux = image.GetScalarRange() | ||
568 | - if min_scalar is None or min_aux < min_scalar: | ||
569 | - min_scalar = min_aux | ||
570 | - | ||
571 | - if max_scalar is None or max_aux > max_scalar: | ||
572 | - max_scalar = max_aux | 571 | + im_array = read_dcm_slice_as_np(f, resolution_percentage) |
573 | 572 | ||
574 | - array = numpy_support.vtk_to_numpy(image.GetPointData().GetScalars()) | ||
575 | if orientation == 'CORONAL': | 573 | if orientation == 'CORONAL': |
576 | - array.shape = matrix.shape[0], matrix.shape[2] | ||
577 | - matrix[:, shape[1] - n - 1, :] = array | 574 | + matrix[:, shape[1] - n - 1, :] = im_array |
578 | elif orientation == 'SAGITTAL': | 575 | elif orientation == 'SAGITTAL': |
579 | - array.shape = matrix.shape[0], matrix.shape[1] | ||
580 | # TODO: Verify if it's necessary to add the slices swapped only in | 576 | # TODO: Verify if it's necessary to add the slices swapped only in |
581 | # sagittal rmi or only in # Rasiane's case or is necessary in all | 577 | # sagittal rmi or only in # Rasiane's case or is necessary in all |
582 | # sagittal cases. | 578 | # sagittal cases. |
583 | - matrix[:, :, n] = array | 579 | + matrix[:, :, n] = im_array |
584 | else: | 580 | else: |
585 | - array.shape = matrix.shape[1], matrix.shape[2] | ||
586 | - matrix[n] = array | ||
587 | - update_progress(cont,message) | ||
588 | - cont += 1 | 581 | + matrix[n] = im_array |
582 | + update_progress(n, message) | ||
589 | 583 | ||
590 | matrix.flush() | 584 | matrix.flush() |
591 | - scalar_range = min_scalar, max_scalar | 585 | + scalar_range = matrix.min(), matrix.max() |
592 | 586 | ||
593 | return matrix, scalar_range, temp_file | 587 | return matrix, scalar_range, temp_file |
594 | 588 |