Commit 1ea30e1a8036001b46b0fccacc929cd8a1c4c190

Authored by Paulo Henrique Junqueira Amorim
1 parent 6f637a00

FIX: Again function to reduce vtkImageData with 3 dimension.

invesalius/data/imagedata_utils.py
@@ -4,7 +4,27 @@ import vtk @@ -4,7 +4,27 @@ import vtk
4 # TODO: Test cases which are originally in sagittal/coronal orientation 4 # TODO: Test cases which are originally in sagittal/coronal orientation
5 # and have gantry 5 # and have gantry
6 6
7 -def ResampleMatrix(imagedata, xy_dimension): 7 +def ResampleImage3D(imagedata, value):
  8 + """
  9 + Resample vtkImageData matrix.
  10 + """
  11 + spacing = imagedata.GetSpacing()
  12 + extent = imagedata.GetExtent()
  13 + size = imagedata.GetDimensions()
  14 +
  15 + width = float(size[0])
  16 + height = float(size[1]/value)
  17 +
  18 + resolution = (height/(extent[1]-extent[0])+1)*spacing[1]
  19 +
  20 + resample = vtk.vtkImageResample()
  21 + resample.SetInput(imagedata)
  22 + resample.SetAxisMagnificationFactor(0, resolution)
  23 + resample.SetAxisMagnificationFactor(1, resolution)
  24 +
  25 + return resample.GetOutput()
  26 +
  27 +def ResampleImage2D(imagedata, xy_dimension):
8 """ 28 """
9 Resample vtkImageData matrix. 29 Resample vtkImageData matrix.
10 """ 30 """
@@ -27,18 +47,16 @@ def ResampleMatrix(imagedata, xy_dimension): @@ -27,18 +47,16 @@ def ResampleMatrix(imagedata, xy_dimension):
27 y = 2 47 y = 2
28 48
29 factor = xy_dimension/float(f+1) 49 factor = xy_dimension/float(f+1)
30 - 50 +
31 resample = vtk.vtkImageResample() 51 resample = vtk.vtkImageResample()
32 resample.SetInput(imagedata) 52 resample.SetInput(imagedata)
33 resample.SetAxisMagnificationFactor(0, factor) 53 resample.SetAxisMagnificationFactor(0, factor)
34 resample.SetAxisMagnificationFactor(1, factor) 54 resample.SetAxisMagnificationFactor(1, factor)
35 resample.SetOutputSpacing(spacing[0] * factor, spacing[1] * factor, spacing[2]) 55 resample.SetOutputSpacing(spacing[0] * factor, spacing[1] * factor, spacing[2])
36 resample.Update() 56 resample.Update()
37 -  
38 - 57 +
  58 +
39 return resample.GetOutput() 59 return resample.GetOutput()
40 -  
41 -  
42 60
43 def FixGantryTilt(imagedata, tilt): 61 def FixGantryTilt(imagedata, tilt):
44 """ 62 """
invesalius/data/surface.py
@@ -29,26 +29,26 @@ class SurfaceManager(): @@ -29,26 +29,26 @@ class SurfaceManager():
29 - creating new surfaces; 29 - creating new surfaces;
30 - managing surfaces' properties; 30 - managing surfaces' properties;
31 - removing existing surfaces. 31 - removing existing surfaces.
32 - 32 +
33 Send pubsub events to other classes: 33 Send pubsub events to other classes:
34 - GUI: Update progress status 34 - GUI: Update progress status
35 - volume_viewer: Sends surface actors as the are created 35 - volume_viewer: Sends surface actors as the are created
36 - 36 +
37 """ 37 """
38 def __init__(self): 38 def __init__(self):
39 self.actors_dict = {} 39 self.actors_dict = {}
40 self.__bind_events() 40 self.__bind_events()
41 - 41 +
42 def __bind_events(self): 42 def __bind_events(self):
43 ps.Publisher().subscribe(self.AddNewActor, 'Create surface') 43 ps.Publisher().subscribe(self.AddNewActor, 'Create surface')
44 ps.Publisher().subscribe(self.SetActorTransparency, 44 ps.Publisher().subscribe(self.SetActorTransparency,
45 'Set surface transparency') 45 'Set surface transparency')
46 ps.Publisher().subscribe(self.SetActorColour, 46 ps.Publisher().subscribe(self.SetActorColour,
47 'Set surface colour') 47 'Set surface colour')
48 - 48 +
49 ps.Publisher().subscribe(self.OnChangeSurfaceName, 'Change surface name') 49 ps.Publisher().subscribe(self.OnChangeSurfaceName, 'Change surface name')
50 ps.Publisher().subscribe(self.OnShowSurface, 'Show surface') 50 ps.Publisher().subscribe(self.OnShowSurface, 'Show surface')
51 - 51 +
52 def AddNewActor(self, pubsub_evt): 52 def AddNewActor(self, pubsub_evt):
53 """ 53 """
54 Create surface actor, save into project and send it to viewer. 54 Create surface actor, save into project and send it to viewer.
@@ -56,7 +56,7 @@ class SurfaceManager(): @@ -56,7 +56,7 @@ class SurfaceManager():
56 imagedata, colour, [min_value, max_value] = pubsub_evt.data 56 imagedata, colour, [min_value, max_value] = pubsub_evt.data
57 quality='Optimal' 57 quality='Optimal'
58 mode = 'CONTOUR' # 'GRAYSCALE' 58 mode = 'CONTOUR' # 'GRAYSCALE'
59 - 59 +
60 if quality in const.SURFACE_QUALITY.keys(): 60 if quality in const.SURFACE_QUALITY.keys():
61 imagedata_resolution = const.SURFACE_QUALITY[quality][0] 61 imagedata_resolution = const.SURFACE_QUALITY[quality][0]
62 smooth_iterations = const.SURFACE_QUALITY[quality][1] 62 smooth_iterations = const.SURFACE_QUALITY[quality][1]
@@ -64,8 +64,8 @@ class SurfaceManager(): @@ -64,8 +64,8 @@ class SurfaceManager():
64 decimate_reduction = const.SURFACE_QUALITY[quality][3] 64 decimate_reduction = const.SURFACE_QUALITY[quality][3]
65 65
66 if imagedata_resolution: 66 if imagedata_resolution:
67 - imagedata = iu.ResampleMatrix(imagedata)  
68 - 67 + imagedata = iu.ResampleImage3D(imagedata, imagedata_resolution)
  68 +
69 pipeline_size = 3 69 pipeline_size = 3
70 if decimate_reduction: 70 if decimate_reduction:
71 pipeline_size += 1 71 pipeline_size += 1
@@ -74,7 +74,7 @@ class SurfaceManager(): @@ -74,7 +74,7 @@ class SurfaceManager():
74 74
75 # Update progress value in GUI 75 # Update progress value in GUI
76 UpdateProgress = vu.ShowProgress(pipeline_size) 76 UpdateProgress = vu.ShowProgress(pipeline_size)
77 - 77 +
78 # Flip original vtkImageData 78 # Flip original vtkImageData
79 flip = vtk.vtkImageFlip() 79 flip = vtk.vtkImageFlip()
80 flip.SetInput(imagedata) 80 flip.SetInput(imagedata)
@@ -103,7 +103,7 @@ class SurfaceManager(): @@ -103,7 +103,7 @@ class SurfaceManager():
103 mcubes.AddObserver("ProgressEvent", lambda obj, evt: 103 mcubes.AddObserver("ProgressEvent", lambda obj, evt:
104 UpdateProgress(contour, "Generating 3D surface...")) 104 UpdateProgress(contour, "Generating 3D surface..."))
105 polydata = mcubes.GetOutput() 105 polydata = mcubes.GetOutput()
106 - 106 +
107 # Reduce number of triangles (previous classes create a large amount) 107 # Reduce number of triangles (previous classes create a large amount)
108 # Important: vtkQuadricDecimation presented better results than 108 # Important: vtkQuadricDecimation presented better results than
109 # vtkDecimatePro 109 # vtkDecimatePro
@@ -112,10 +112,10 @@ class SurfaceManager(): @@ -112,10 +112,10 @@ class SurfaceManager():
112 decimation.SetInput(polydata) 112 decimation.SetInput(polydata)
113 decimation.SetTargetReduction(decimate_reduction) 113 decimation.SetTargetReduction(decimate_reduction)
114 decimation.GetOutput().ReleaseDataFlagOn() 114 decimation.GetOutput().ReleaseDataFlagOn()
115 - decimation.AddObserver("ProgressEvent", lambda obj, evt: 115 + decimation.AddObserver("ProgressEvent", lambda obj, evt:
116 UpdateProgress(decimation, "Reducing number of triangles...")) 116 UpdateProgress(decimation, "Reducing number of triangles..."))
117 polydata = decimation.GetOutput() 117 polydata = decimation.GetOutput()
118 - 118 +
119 # TODO (Paulo): Why do we need this filter? 119 # TODO (Paulo): Why do we need this filter?
120 #triangle = vtk.vtkTriangleFilter() 120 #triangle = vtk.vtkTriangleFilter()
121 #triangle.SetInput(polydata) 121 #triangle.SetInput(polydata)
@@ -127,7 +127,7 @@ class SurfaceManager(): @@ -127,7 +127,7 @@ class SurfaceManager():
127 127
128 # Smooth surface without changing structures 128 # Smooth surface without changing structures
129 # Important: vtkSmoothPolyDataFilter presented better results than 129 # Important: vtkSmoothPolyDataFilter presented better results than
130 - # vtkImageGaussianSmooth and vtkWindowedSincPolyDataFilter 130 + # vtkImageGaussianSmooth and vtkWindowedSincPolyDataFilter
131 if smooth_iterations and smooth_relaxation_factor: 131 if smooth_iterations and smooth_relaxation_factor:
132 smoother = vtk.vtkSmoothPolyDataFilter() 132 smoother = vtk.vtkSmoothPolyDataFilter()
133 smoother.SetInput(polydata) 133 smoother.SetInput(polydata)
@@ -140,7 +140,7 @@ class SurfaceManager(): @@ -140,7 +140,7 @@ class SurfaceManager():
140 smoother.AddObserver("ProgressEvent", lambda obj, evt: 140 smoother.AddObserver("ProgressEvent", lambda obj, evt:
141 UpdateProgress(smoother, "Smoothing surface...")) 141 UpdateProgress(smoother, "Smoothing surface..."))
142 polydata = smoother.GetOutput() 142 polydata = smoother.GetOutput()
143 - 143 +
144 # Filter used to detect and fill holes. Only fill boundary edges holes. 144 # Filter used to detect and fill holes. Only fill boundary edges holes.
145 #TODO: Hey! This piece of code is the same from 145 #TODO: Hey! This piece of code is the same from
146 # polydata_utils.FillSurfaceHole, we need to review this. 146 # polydata_utils.FillSurfaceHole, we need to review this.
@@ -161,7 +161,7 @@ class SurfaceManager(): @@ -161,7 +161,7 @@ class SurfaceManager():
161 normals.AddObserver("ProgressEvent", lambda obj, evt: 161 normals.AddObserver("ProgressEvent", lambda obj, evt:
162 UpdateProgress(normals, "Orienting normals...")) 162 UpdateProgress(normals, "Orienting normals..."))
163 polydata = normals.GetOutput() 163 polydata = normals.GetOutput()
164 - 164 +
165 #======= Temporary Code ======= 165 #======= Temporary Code =======
166 stl = vtk.vtkSTLWriter() 166 stl = vtk.vtkSTLWriter()
167 stl.SetFileTypeToBinary() 167 stl.SetFileTypeToBinary()
@@ -176,24 +176,24 @@ class SurfaceManager(): @@ -176,24 +176,24 @@ class SurfaceManager():
176 stripper.SetInput(normals.GetOutput()) 176 stripper.SetInput(normals.GetOutput())
177 stripper.PassThroughCellIdsOn() 177 stripper.PassThroughCellIdsOn()
178 stripper.PassThroughPointIdsOn() 178 stripper.PassThroughPointIdsOn()
179 - stripper.AddObserver("ProgressEvent", lambda obj, evt: 179 + stripper.AddObserver("ProgressEvent", lambda obj, evt:
180 UpdateProgress(stripper, "Stripping surface...")) 180 UpdateProgress(stripper, "Stripping surface..."))
181 -  
182 - # Map polygonal data (vtkPolyData) to graphics primitives. 181 +
  182 + # Map polygonal data (vtkPolyData) to graphics primitives.
183 mapper = vtk.vtkPolyDataMapper() 183 mapper = vtk.vtkPolyDataMapper()
184 mapper.SetInput(stripper.GetOutput()) 184 mapper.SetInput(stripper.GetOutput())
185 mapper.ScalarVisibilityOff() 185 mapper.ScalarVisibilityOff()
186 186
187 - # Represent an object (geometry & properties) in the rendered scene 187 + # Represent an object (geometry & properties) in the rendered scene
188 actor = vtk.vtkActor() 188 actor = vtk.vtkActor()
189 actor.SetMapper(mapper) 189 actor.SetMapper(mapper)
190 - 190 +
191 # Create Surface instance 191 # Create Surface instance
192 surface = Surface() 192 surface = Surface()
193 surface.colour = colour 193 surface.colour = colour
194 surface.polydata = polydata 194 surface.polydata = polydata
195 195
196 - 196 +
197 # Set actor colour and transparency 197 # Set actor colour and transparency
198 actor.GetProperty().SetColor(colour) 198 actor.GetProperty().SetColor(colour)
199 actor.GetProperty().SetOpacity(1-surface.transparency) 199 actor.GetProperty().SetOpacity(1-surface.transparency)
@@ -201,28 +201,28 @@ class SurfaceManager(): @@ -201,28 +201,28 @@ class SurfaceManager():
201 # Append surface into Project.surface_dict 201 # Append surface into Project.surface_dict
202 proj = Project() 202 proj = Project()
203 proj.surface_dict[surface.index] = surface 203 proj.surface_dict[surface.index] = surface
204 - 204 +
205 # Save actor for future management tasks 205 # Save actor for future management tasks
206 self.actors_dict[surface.index] = actor 206 self.actors_dict[surface.index] = actor
207 - 207 +
208 # Send actor by pubsub to viewer's render 208 # Send actor by pubsub to viewer's render
209 ps.Publisher().sendMessage('Load surface actor into viewer', (actor)) 209 ps.Publisher().sendMessage('Load surface actor into viewer', (actor))
210 - 210 +
211 ps.Publisher().sendMessage('Update status text in GUI', 211 ps.Publisher().sendMessage('Update status text in GUI',
212 "Surface created.") 212 "Surface created.")
213 - 213 +
214 # The following lines have to be here, otherwise all volumes disappear 214 # The following lines have to be here, otherwise all volumes disappear
215 measured_polydata = vtk.vtkMassProperties() 215 measured_polydata = vtk.vtkMassProperties()
216 measured_polydata.SetInput(polydata) 216 measured_polydata.SetInput(polydata)
217 volume = measured_polydata.GetVolume() 217 volume = measured_polydata.GetVolume()
218 surface.volume = volume 218 surface.volume = volume
219 - 219 +
220 ps.Publisher().sendMessage('Update surface info in GUI', 220 ps.Publisher().sendMessage('Update surface info in GUI',
221 - (surface.index, surface.name, 221 + (surface.index, surface.name,
222 surface.colour, surface.volume, 222 surface.colour, surface.volume,
223 surface.transparency)) 223 surface.transparency))
224 -  
225 - 224 +
  225 +
226 def RemoveActor(self, index): 226 def RemoveActor(self, index):
227 """ 227 """
228 Remove actor, according to given actor index. 228 Remove actor, according to given actor index.
@@ -233,17 +233,17 @@ class SurfaceManager(): @@ -233,17 +233,17 @@ class SurfaceManager():
233 proj = Project() 233 proj = Project()
234 proj.surface_dict.pop(index) 234 proj.surface_dict.pop(index)
235 235
236 - 236 +
237 def OnChangeSurfaceName(self, pubsub_evt): 237 def OnChangeSurfaceName(self, pubsub_evt):
238 index, name = pubsub_evt.data 238 index, name = pubsub_evt.data
239 proj = Project() 239 proj = Project()
240 proj.surface_dict[index].name = name 240 proj.surface_dict[index].name = name
241 - 241 +
242 def OnShowSurface(self, pubsub_evt): 242 def OnShowSurface(self, pubsub_evt):
243 index, value = pubsub_evt.data 243 index, value = pubsub_evt.data
244 print "OnShowSurface", index, value 244 print "OnShowSurface", index, value
245 self.ShowActor(index, value) 245 self.ShowActor(index, value)
246 - 246 +
247 def ShowActor(self, index, value): 247 def ShowActor(self, index, value):
248 """ 248 """
249 Show or hide actor, according to given actor index and value. 249 Show or hide actor, according to given actor index and value.
@@ -253,7 +253,7 @@ class SurfaceManager(): @@ -253,7 +253,7 @@ class SurfaceManager():
253 proj = Project() 253 proj = Project()
254 proj.surface_dict[index].is_shown = value 254 proj.surface_dict[index].is_shown = value
255 ps.Publisher().sendMessage('Render volume viewer') 255 ps.Publisher().sendMessage('Render volume viewer')
256 - 256 +
257 def SetActorTransparency(self, pubsub_evt): 257 def SetActorTransparency(self, pubsub_evt):
258 """ 258 """
259 Set actor transparency (oposite to opacity) according to given actor 259 Set actor transparency (oposite to opacity) according to given actor
@@ -265,7 +265,7 @@ class SurfaceManager(): @@ -265,7 +265,7 @@ class SurfaceManager():
265 proj = Project() 265 proj = Project()
266 proj.surface_dict[index].transparency = value 266 proj.surface_dict[index].transparency = value
267 ps.Publisher().sendMessage('Render volume viewer') 267 ps.Publisher().sendMessage('Render volume viewer')
268 - 268 +
269 def SetActorColour(self, pubsub_evt): 269 def SetActorColour(self, pubsub_evt):
270 """ 270 """
271 """ 271 """