Commit 0ce0c1ddee765505bde26017a4f55019c75cc0f0
1 parent
febef67f
Exists in
master
and in
68 other branches
ENH: Choose the best image resolution in accordance with the amount of memory in…
…stalled, (Tested in the Windows) #76
Showing
3 changed files
with
124 additions
and
66 deletions
Show diff stats
invesalius/constants.py
... | ... | @@ -227,12 +227,7 @@ WINDOW_LEVEL = {_("Abdomen"):(350,50), |
227 | 227 | _("Vasculature - Hard"):(240,80), |
228 | 228 | _("Vasculature - Soft"):(650,160)} |
229 | 229 | |
230 | -if (sys.platform == 'win32') and (platform.architecture()[0] == '32bit'): | |
231 | - REDUCE_IMAGEDATA_QUALITY = 1 | |
232 | -elif (sys.platform == 'darwin'): | |
233 | - REDUCE_IMAGEDATA_QUALITY = 1 | |
234 | -else: | |
235 | - REDUCE_IMAGEDATA_QUALITY = 0 | |
230 | +REDUCE_IMAGEDATA_QUALITY = 0 | |
236 | 231 | |
237 | 232 | ICON_DIR = os.path.abspath(os.path.join('..', 'icons')) |
238 | 233 | |
... | ... | @@ -257,8 +252,8 @@ _("Black & White") |
257 | 252 | _("Bone + Skin") |
258 | 253 | _("Bone + Skin II") |
259 | 254 | _("Dark Bone") |
260 | -_("Glossy") | |
261 | -_("Glossy II") | |
255 | +_("Glossy") | |
256 | +_("Glossy II") | |
262 | 257 | _("Gold Bone") |
263 | 258 | _("High Contrast") |
264 | 259 | _("Low Contrast") |
... | ... | @@ -339,7 +334,7 @@ FILETYPE_VRML = wx.NewId() |
339 | 334 | FILETYPE_OBJ = wx.NewId() |
340 | 335 | FILETYPE_VTP = wx.NewId() |
341 | 336 | FILETYPE_PLY = wx.NewId() |
342 | - | |
337 | + | |
343 | 338 | FILETYPE_IMAGEDATA = wx.NewId() |
344 | 339 | |
345 | 340 | FILETYPE_BMP = wx.NewId() | ... | ... |
invesalius/data/imagedata_utils.py
... | ... | @@ -49,16 +49,14 @@ def ResampleImage3D(imagedata, value): |
49 | 49 | |
50 | 50 | return resample.GetOutput() |
51 | 51 | |
52 | -def ResampleImage2D(imagedata, xy_dimension, | |
52 | +def ResampleImage2D(imagedata, px, py, | |
53 | 53 | update_progress = None): |
54 | 54 | """ |
55 | 55 | Resample vtkImageData matrix. |
56 | 56 | """ |
57 | 57 | extent = imagedata.GetExtent() |
58 | - print "-----------------------------" | |
59 | - print "extent:", extent | |
60 | 58 | spacing = imagedata.GetSpacing() |
61 | - print "spacing:", spacing | |
59 | + | |
62 | 60 | |
63 | 61 | #if extent[1]==extent[3]: |
64 | 62 | # f = extent[1] |
... | ... | @@ -68,26 +66,24 @@ def ResampleImage2D(imagedata, xy_dimension, |
68 | 66 | # f = extent[3] |
69 | 67 | |
70 | 68 | if abs(extent[1]-extent[3]) < abs(extent[3]-extent[5]): |
71 | - print 1 | |
72 | 69 | f = extent[1] |
73 | 70 | elif abs(extent[1]-extent[5]) < abs(extent[1] - extent[3]): |
74 | - print 2 | |
75 | 71 | f = extent[1] |
76 | 72 | elif abs(extent[3]-extent[5]) < abs(extent[1] - extent[3]): |
77 | - print 3 | |
78 | 73 | f = extent[3] |
79 | 74 | else: |
80 | - print 4 | |
81 | 75 | f = extent[1] |
82 | - | |
83 | 76 | |
84 | - factor = xy_dimension/float(f+1) | |
77 | + | |
78 | + factor_x = px/float(f+1) | |
79 | + factor_y = py/float(f+1) | |
80 | + | |
85 | 81 | |
86 | 82 | resample = vtk.vtkImageResample() |
87 | 83 | resample.SetInput(imagedata) |
88 | - resample.SetAxisMagnificationFactor(0, factor) | |
89 | - resample.SetAxisMagnificationFactor(1, factor) | |
90 | - resample.SetOutputSpacing(spacing[0] * factor, spacing[1] * factor, spacing[2]) | |
84 | + resample.SetAxisMagnificationFactor(0, factor_x) | |
85 | + resample.SetAxisMagnificationFactor(1, factor_y) | |
86 | + resample.SetOutputSpacing(spacing[0] * factor_x, spacing[1] * factor_y, spacing[2]) | |
91 | 87 | if (update_progress): |
92 | 88 | message = "Generating multiplanar visualization..." |
93 | 89 | resample.AddObserver("ProgressEvent", lambda obj, |
... | ... | @@ -189,7 +185,7 @@ def View(imagedata): |
189 | 185 | viewer.SetColorWindow(200) |
190 | 186 | viewer.SetColorLevel(100) |
191 | 187 | viewer.Render() |
192 | - | |
188 | + | |
193 | 189 | import time |
194 | 190 | time.sleep(10) |
195 | 191 | |
... | ... | @@ -199,40 +195,50 @@ def ViewGDCM(imagedata): |
199 | 195 | viewer.SetColorWindow(500.) |
200 | 196 | viewer.SetColorLevel(50.) |
201 | 197 | viewer.Render() |
202 | - | |
198 | + | |
203 | 199 | import time |
204 | 200 | time.sleep(5) |
205 | 201 | |
206 | 202 | |
207 | - | |
203 | + | |
208 | 204 | def ExtractVOI(imagedata,xi,xf,yi,yf,zi,zf): |
209 | 205 | """ |
210 | - Cropping the vtkImagedata according | |
206 | + Cropping the vtkImagedata according | |
211 | 207 | with values. |
212 | - """ | |
208 | + """ | |
213 | 209 | voi = vtk.vtkExtractVOI() |
214 | 210 | voi.SetVOI(xi,xf,yi,yf,zi,zf) |
215 | 211 | voi.SetInput(imagedata) |
216 | 212 | voi.SetSampleRate(1, 1, 1) |
217 | - voi.Update() | |
213 | + voi.Update() | |
218 | 214 | return voi.GetOutput() |
219 | 215 | |
220 | 216 | def CreateImageData(filelist, zspacing, size, bits): |
221 | 217 | message = "Generating multiplanar visualization..." |
222 | - | |
218 | + | |
223 | 219 | if not const.VTK_WARNING: |
224 | 220 | fow = vtk.vtkFileOutputWindow() |
225 | 221 | fow.SetFileName('vtkoutput.txt') |
226 | 222 | ow = vtk.vtkOutputWindow() |
227 | 223 | ow.SetInstance(fow) |
228 | - | |
224 | + | |
225 | + x,y = size | |
226 | + px, py = utils.PredictingMemory(len(filelist), x, y, bits) | |
227 | + | |
228 | + print "Image Resized to >>>", px, "x", py | |
229 | + | |
230 | + if (x == px) and (y == py): | |
231 | + const.REDUCE_IMAGEDATA_QUALITY = 0 | |
232 | + else: | |
233 | + const.REDUCE_IMAGEDATA_QUALITY = 1 | |
234 | + | |
229 | 235 | if not(const.REDUCE_IMAGEDATA_QUALITY): |
230 | 236 | update_progress= vtk_utils.ShowProgress(1, dialog_type = "ProgressDialog") |
231 | 237 | |
232 | 238 | array = vtk.vtkStringArray() |
233 | 239 | for x in xrange(len(filelist)): |
234 | 240 | array.InsertValue(x,filelist[x]) |
235 | - | |
241 | + | |
236 | 242 | reader = vtkgdcm.vtkGDCMImageReader() |
237 | 243 | reader.SetFileNames(array) |
238 | 244 | reader.AddObserver("ProgressEvent", lambda obj,evt: |
... | ... | @@ -245,16 +251,14 @@ def CreateImageData(filelist, zspacing, size, bits): |
245 | 251 | spacing = imagedata.GetSpacing() |
246 | 252 | imagedata.SetSpacing(spacing[0], spacing[1], zspacing) |
247 | 253 | else: |
248 | - | |
254 | + | |
249 | 255 | update_progress= vtk_utils.ShowProgress(2*len(filelist), |
250 | 256 | dialog_type = "ProgressDialog") |
251 | 257 | |
252 | 258 | # Reformat each slice and future append them |
253 | 259 | appender = vtk.vtkImageAppend() |
254 | 260 | appender.SetAppendAxis(2) #Define Stack in Z |
255 | - | |
256 | - x,y = size | |
257 | - p = utils.PredictingMemory(len(filelist), x, y, bits) | |
261 | + | |
258 | 262 | |
259 | 263 | # Reformat each slice |
260 | 264 | for x in xrange(len(filelist)): |
... | ... | @@ -266,9 +270,9 @@ def CreateImageData(filelist, zspacing, size, bits): |
266 | 270 | reader.AddObserver("ProgressEvent", lambda obj,evt: |
267 | 271 | update_progress(reader,message)) |
268 | 272 | reader.Update() |
269 | - | |
273 | + | |
270 | 274 | #Resample image in x,y dimension |
271 | - slice_imagedata = ResampleImage2D(reader.GetOutput(), p, update_progress) | |
275 | + slice_imagedata = ResampleImage2D(reader.GetOutput(), px, py, update_progress) | |
272 | 276 | #Stack images in Z axes |
273 | 277 | appender.AddInput(slice_imagedata) |
274 | 278 | #appender.AddObserver("ProgressEvent", lambda obj,evt:update_progress(appender)) |
... | ... | @@ -284,7 +288,7 @@ def CreateImageData(filelist, zspacing, size, bits): |
284 | 288 | imagedata.AddObserver("ProgressEvent", lambda obj,evt: |
285 | 289 | update_progress(imagedata,message)) |
286 | 290 | imagedata.Update() |
287 | - | |
291 | + | |
288 | 292 | return imagedata |
289 | 293 | |
290 | 294 | |
... | ... | @@ -292,25 +296,25 @@ def CreateImageData(filelist, zspacing, size, bits): |
292 | 296 | class ImageCreator: |
293 | 297 | def __init__(self): |
294 | 298 | ps.Publisher().sendMessage("Cancel imagedata load", self.CancelImageDataLoad) |
295 | - | |
299 | + | |
296 | 300 | def CancelImageDataLoad(self, evt_pusub): |
297 | 301 | self.running = evt_pusub.data |
298 | - | |
302 | + | |
299 | 303 | def CreateImageData(filelist, zspacing): |
300 | 304 | message = "Generating multiplanar visualization..." |
301 | 305 | if not(const.REDUCE_IMAGEDATA_QUALITY): |
302 | 306 | update_progress= vtk_utils.ShowProgress(1) |
303 | - | |
307 | + | |
304 | 308 | array = vtk.vtkStringArray() |
305 | 309 | for x in xrange(len(filelist)): |
306 | 310 | array.InsertValue(x,filelist[x]) |
307 | - | |
311 | + | |
308 | 312 | reader = vtkgdcm.vtkGDCMImageReader() |
309 | 313 | reader.SetFileNames(array) |
310 | 314 | reader.AddObserver("ProgressEvent", lambda obj,evt: |
311 | 315 | update_progress(reader,message)) |
312 | 316 | reader.Update() |
313 | - | |
317 | + | |
314 | 318 | # The zpacing is a DicomGroup property, so we need to set it |
315 | 319 | imagedata = vtk.vtkImageData() |
316 | 320 | imagedata.DeepCopy(reader.GetOutput()) |
... | ... | @@ -319,11 +323,11 @@ class ImageCreator: |
319 | 323 | else: |
320 | 324 | update_progress= vtk_utils.ShowProgress(2*len(filelist), |
321 | 325 | dialog_type = "ProgressDialog") |
322 | - | |
326 | + | |
323 | 327 | # Reformat each slice and future append them |
324 | 328 | appender = vtk.vtkImageAppend() |
325 | 329 | appender.SetAppendAxis(2) #Define Stack in Z |
326 | - | |
330 | + | |
327 | 331 | # Reformat each slice |
328 | 332 | for x in xrange(len(filelist)): |
329 | 333 | # TODO: We need to check this automatically according |
... | ... | @@ -334,27 +338,27 @@ class ImageCreator: |
334 | 338 | reader.AddObserver("ProgressEvent", lambda obj,evt: |
335 | 339 | update_progress(reader,message)) |
336 | 340 | reader.Update() |
337 | - | |
341 | + | |
338 | 342 | #Resample image in x,y dimension |
339 | - | |
343 | + | |
340 | 344 | slice_imagedata = ResampleImage2D(reader.GetOutput(), 256, update_progress) |
341 | - | |
345 | + | |
342 | 346 | #Stack images in Z axes |
343 | 347 | appender.AddInput(slice_imagedata) |
344 | 348 | #appender.AddObserver("ProgressEvent", lambda obj,evt:update_progress(appender)) |
345 | 349 | appender.Update() |
346 | - | |
350 | + | |
347 | 351 | # The zpacing is a DicomGroup property, so we need to set it |
348 | 352 | imagedata = vtk.vtkImageData() |
349 | 353 | imagedata.DeepCopy(appender.GetOutput()) |
350 | 354 | spacing = imagedata.GetSpacing() |
351 | - | |
355 | + | |
352 | 356 | imagedata.SetSpacing(spacing[0], spacing[1], zspacing) |
353 | - | |
357 | + | |
354 | 358 | imagedata.AddObserver("ProgressEvent", lambda obj,evt: |
355 | 359 | update_progress(imagedata,message)) |
356 | 360 | imagedata.Update() |
357 | - | |
361 | + | |
358 | 362 | return imagedata |
359 | 363 | """ |
360 | 364 | ... | ... |
invesalius/utils.py
... | ... | @@ -16,9 +16,11 @@ |
16 | 16 | # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais |
17 | 17 | # detalhes. |
18 | 18 | #-------------------------------------------------------------------------- |
19 | +import os | |
20 | +import platform | |
19 | 21 | import subprocess |
20 | 22 | import re |
21 | -import os | |
23 | +import sys | |
22 | 24 | |
23 | 25 | |
24 | 26 | def debug(error_str): |
... | ... | @@ -91,19 +93,73 @@ def frange(start, end=None, inc=None): |
91 | 93 | def PredictingMemory(qtd, x, y, p): |
92 | 94 | m = qtd * (x * y * p) |
93 | 95 | |
94 | - #314859200 = 350 MB | |
95 | - #house 25 MB increases the | |
96 | - #factor 0.4 | |
97 | - if (m >= 314859200): | |
98 | - porcent = 1.5 + (m - 314859200) / 26999999 * 0.04 | |
99 | - x = x/porcent | |
100 | - y = y/porcent | |
101 | - return x | |
96 | + if (sys.platform == 'win32'): | |
97 | + | |
98 | + physical_memory = GetWindowsInformation()[3] | |
99 | + | |
100 | + if (platform.architecture()[0] == '32bit'): | |
101 | + #(314859200 = 300 MB) | |
102 | + #(26999999 = 25 MB) | |
103 | + | |
104 | + #case occupy more than 300 MB image is reduced to 1.5, | |
105 | + #and 25 MB each image is resized 0.04. | |
106 | + if (m >= 314859200): | |
107 | + porcent = 1.5 + (m - 314859200) / 26999999 * 0.04 | |
108 | + else: | |
109 | + return (x, y) | |
110 | + else: #64 bits architecture | |
111 | + | |
112 | + if (physical_memory <= 2.0) and (qtd <= 1200): | |
113 | + porcent = 1.5 + (m - 314859200) / 26999999 * 0.02 | |
114 | + | |
115 | + elif(physical_memory <= 2.0) and (qtd > 1200): | |
116 | + porcent = 1.5 + (m - 314859200) / 26999999 * 0.03 | |
117 | + | |
118 | + elif(physical_memory > 2.0) and (physical_memory <= 4.0) and (qtd <= 1200): | |
119 | + porcent = 1.5 + (m - 314859200) / 26999999 * 0.01 | |
120 | + | |
121 | + else: | |
122 | + return (x,y) | |
123 | + | |
124 | + return (x/porcent, y/porcent) | |
102 | 125 | |
103 | - else: | |
104 | - return x | |
126 | + elif(sys.platform == 'linux2'): | |
127 | + | |
128 | + physical_memory = GetLinuxInformation()[2] | |
129 | + | |
130 | + if (platform.architecture()[0] == '32bit'): | |
131 | + # 839000000 = 800 MB | |
132 | + if (m <= 839000000) and (physical_memory <= 2.0): | |
133 | + return (x,y) | |
134 | + elif (m > 839000000) and (physical_memory <= 2.0) and (qtd <= 1200): | |
135 | + porcent = 1.5 + (m - 314859200) / 26999999 * 0.02 | |
136 | + else: | |
137 | + return (x,y) | |
138 | + | |
139 | + else: | |
140 | + | |
141 | + if (m <= 839000000) and (physical_memory <= 2.0): | |
142 | + return (x, y) | |
143 | + elif (m > 839000000) and (physical_memory <= 2.0) and (qtd <= 1200): | |
144 | + porcent = 1.5 + (m - 314859200) / 26999999 * 0.02 | |
145 | + else: | |
146 | + return (x,y) | |
147 | + | |
148 | + return (x/porcent, y/porcent) | |
149 | + | |
150 | + elif(sys.platform == 'darwin'): | |
151 | + | |
152 | + physical_memory = GetDarwinInformation() | |
153 | + | |
154 | + if (m <= 839000000) and (physical_memory <= 2.0): | |
155 | + return (x, y) | |
156 | + elif (m > 839000000) and (physical_memory <= 2.0) and (qtd <= 1200): | |
157 | + porcent = 1.5 + (m - 314859200) / 26999999 * 0.02 | |
158 | + else: | |
159 | + return (x, y) | |
160 | + | |
161 | + return (x/porcent,y/porcent) | |
105 | 162 | |
106 | - return x | |
107 | 163 | |
108 | 164 | |
109 | 165 | def BytesConvert(bytes): |
... | ... | @@ -155,6 +211,10 @@ def GetWindowsInformation(): |
155 | 211 | processor_clock, total_physical_memory, |
156 | 212 | available_physical_memory) |
157 | 213 | |
214 | +def GetDarwinInformation(): | |
215 | + memory = 2.0 | |
216 | + return (memory) | |
217 | + | |
158 | 218 | |
159 | 219 | def GetLinuxInformation(): |
160 | 220 | |
... | ... | @@ -169,8 +229,7 @@ def GetLinuxInformation(): |
169 | 229 | |
170 | 230 | |
171 | 231 | #processor_clock = float(re.findall('[0-9]+', processor_clock)[0]) |
172 | - print architecture | |
173 | - print processor_clock | |
232 | + return (architecture, processor_clock, 2.0) | |
174 | 233 | |
175 | 234 | |
176 | 235 | def LinuxCommand(command): | ... | ... |