Commit 295c16a05abf9da305ffffd927d7706f59206e4b

Authored by tfmoraes
1 parent 6f8c898a

The code fix gantry tilt was rewrite to use the numpy arrays.

The old code to fix gantry tilt was not working with the memmapped
numpy array. That was rewrite so to work with memmapped numpy array
using scipy.ndimage.shift. In
the new code I'm not recalculating the new z-spacing anymore.

Squashed commit of the following:

commit 574b9b042bc6a8585efcdb4fd12a65c4b43e0840
Author: Thiago Franco de Moraes <totonixsame@gmail.com>
Date:   Tue Jun 26 15:19:08 2012 -0300

    Removed the code to calculate a new spacing, it's not necessary

commit 4f91d993995130618275c7aeede4f6502ae66e0c
Author: Thiago Franco de Moraes <totonixsame@gmail.com>
Date:   Tue Jun 26 14:44:22 2012 -0300

    Not rounding spacing values to 2 decimal houses anymore

commit 3313175cdc2a2c22c04bf2d8545c50ede86ced66
Author: Thiago Franco de Moraes <totonixsame@gmail.com>
Date:   Mon Jun 25 16:50:56 2012 -0300

    Testing not applying the translate_coef

commit 363c1ce0bcb2860c4a764201ea5525c865d439dc
Author: Thiago Franco de Moraes <totonixsame@gmail.com>
Date:   Mon Jun 25 13:22:08 2012 -0300

    Changing spacing values when fixing gantry tilt

commit 30785e8ebb945250e45a8b8768253b196112a801
Author: Thiago Franco de Moraes <totonixsame@gmail.com>
Date:   Tue Jun 12 15:32:50 2012 -0300

    Using scipy.ndimage.shift to gantry tilt correction
invesalius/control.py
@@ -513,22 +513,12 @@ class Controller(): @@ -513,22 +513,12 @@ class Controller():
513 513
514 imagedata = None 514 imagedata = None
515 515
516 - # 1(a): Fix gantry tilt, if any  
517 - tilt_value = dicom.acquisition.tilt  
518 - if (tilt_value) and (gui):  
519 - # Tell user gantry tilt and fix, according to answer  
520 - message = _("Fix gantry tilt applying the degrees below")  
521 - value = -1*tilt_value  
522 - tilt_value = dialog.ShowNumberDialog(message, value)  
523 - imagedata = utils.FixGantryTilt(imagedata, tilt_value)  
524 - elif (tilt_value) and not (gui):  
525 - tilt_value = -1*tilt_value  
526 - imagedata = utils.FixGantryTilt(imagedata, tilt_value)  
527 516
528 wl = float(dicom.image.level) 517 wl = float(dicom.image.level)
529 ww = float(dicom.image.window) 518 ww = float(dicom.image.window)
530 self.matrix, scalar_range, self.filename = utils.dcm2memmap(filelist, size, 519 self.matrix, scalar_range, self.filename = utils.dcm2memmap(filelist, size,
531 orientation) 520 orientation)
  521 +
532 self.Slice = sl.Slice() 522 self.Slice = sl.Slice()
533 self.Slice.matrix = self.matrix 523 self.Slice.matrix = self.matrix
534 self.Slice.matrix_filename = self.filename 524 self.Slice.matrix_filename = self.filename
@@ -540,6 +530,17 @@ class Controller(): @@ -540,6 +530,17 @@ class Controller():
540 elif orientation == 'SAGITTAL': 530 elif orientation == 'SAGITTAL':
541 self.Slice.spacing = zspacing, xyspacing[1], xyspacing[0] 531 self.Slice.spacing = zspacing, xyspacing[1], xyspacing[0]
542 532
  533 + # 1(a): Fix gantry tilt, if any
  534 + tilt_value = dicom.acquisition.tilt
  535 + if (tilt_value) and (gui):
  536 + # Tell user gantry tilt and fix, according to answer
  537 + message = _("Fix gantry tilt applying the degrees below")
  538 + value = -1*tilt_value
  539 + tilt_value = dialog.ShowNumberDialog(message, value)
  540 + utils.FixGantryTilt(self.matrix, self.Slice.spacing, tilt_value)
  541 + elif (tilt_value) and not (gui):
  542 + tilt_value = -1*tilt_value
  543 + utils.FixGantryTilt(self.matrix, self.Slice.spacing, tilt_value)
543 544
544 self.Slice.window_level = wl 545 self.Slice.window_level = wl
545 self.Slice.window_width = ww 546 self.Slice.window_width = ww
invesalius/data/imagedata_utils.py
@@ -27,6 +27,7 @@ import vtk @@ -27,6 +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 vtk.util import numpy_support 31 from vtk.util import numpy_support
31 32
32 import constants as const 33 import constants as const
@@ -98,57 +99,18 @@ def ResampleImage2D(imagedata, px, py, @@ -98,57 +99,18 @@ def ResampleImage2D(imagedata, px, py,
98 99
99 return resample.GetOutput() 100 return resample.GetOutput()
100 101
101 -def FixGantryTilt(imagedata, tilt): 102 +def FixGantryTilt(matrix, spacing, tilt):
102 """ 103 """
103 Fix gantry tilt given a vtkImageData and the tilt value. Return new 104 Fix gantry tilt given a vtkImageData and the tilt value. Return new
104 vtkImageData. 105 vtkImageData.
105 """ 106 """
  107 + angle = numpy.radians(tilt)
  108 + spacing = spacing[0], spacing[1], spacing[2]
  109 + gntan = math.tan(angle)
106 110
107 - # Retrieve data from original imagedata  
108 - extent = [int(value) for value in imagedata.GetExtent()]  
109 - origin = imagedata.GetOrigin()  
110 - spacing = [float(value) for value in imagedata.GetSpacing()]  
111 -  
112 - n_slices = int(extent[5])  
113 - new_zspacing = math.cos(tilt*(math.acos(-1.0)/180.0)) * spacing[2] #zspacing  
114 - translate_coef = math.tan(tilt*math.pi/180.0)*new_zspacing*(n_slices-1)  
115 -  
116 - # Class responsible for translating data  
117 - reslice = vtk.vtkImageReslice()  
118 - reslice.SetInput(imagedata)  
119 - reslice.SetInterpolationModeToLinear()  
120 - # Translation will create new pixels. Let's set new pixels' colour to black.  
121 - reslice.SetBackgroundLevel(imagedata.GetScalarRange()[0])  
122 -  
123 - # Class responsible for append translated data  
124 - append = vtk.vtkImageAppend()  
125 - append.SetAppendAxis(2)  
126 -  
127 - # Translate and append each slice  
128 - for i in xrange(n_slices+1):  
129 - slice_imagedata = vtk.vtkImageData()  
130 - value = math.tan(tilt*math.pi/180.0) * new_zspacing * i  
131 - new_origin1 = origin[1] + value - translate_coef  
132 - # Translate data  
133 - reslice.SetOutputOrigin(origin[0], new_origin1, origin[2])  
134 - reslice.SetOutputExtent(extent[0], extent[1], extent[2], extent[3], i,i)  
135 - reslice.Update()  
136 - # Append data  
137 - slice_imagedata.DeepCopy(reslice.GetOutput())  
138 - slice_imagedata.UpdateInformation()  
139 -  
140 - append.AddInput(slice_imagedata)  
141 -  
142 - append.Update()  
143 -  
144 - # Final imagedata  
145 - imagedata = vtk.vtkImageData()  
146 - imagedata.DeepCopy(append.GetOutput())  
147 - imagedata.SetSpacing(spacing[0], spacing[1], new_zspacing)  
148 - imagedata.SetExtent(extent)  
149 - imagedata.UpdateInformation()  
150 -  
151 - return imagedata 111 + for n, slice_ in enumerate(matrix):
  112 + offset = gntan * n * spacing[2]
  113 + matrix[n] = shift(slice_, (-offset/spacing[1], 0), cval=matrix.min())
152 114
153 115
154 def BuildEditedImage(imagedata, points): 116 def BuildEditedImage(imagedata, points):
invesalius/reader/dicom.py
@@ -1933,8 +1933,3 @@ class Image(object): @@ -1933,8 +1933,3 @@ class Image(object):
1933 spacing.append(1.5) 1933 spacing.append(1.5)
1934 except(AttributeError): 1934 except(AttributeError):
1935 spacing = [1, 1, 1] 1935 spacing = [1, 1, 1]
1936 -  
1937 - spacing[0] = round(spacing[0],2)  
1938 - spacing[1] = round(spacing[1],2)  
1939 - spacing[2] = round(spacing[2],2)  
1940 - self.spacing = spacing