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