Commit 1ea30e1a8036001b46b0fccacc929cd8a1c4c190
1 parent
6f637a00
Exists in
master
and in
68 other branches
FIX: Again function to reduce vtkImageData with 3 dimension.
Showing
2 changed files
with
58 additions
and
40 deletions
Show diff stats
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 | """ |