Commit 0ce0c1ddee765505bde26017a4f55019c75cc0f0

Authored by Paulo Henrique Junqueira Amorim
1 parent febef67f

ENH: Choose the best image resolution in accordance with the amount of memory in…

…stalled, (Tested in the Windows) #76
invesalius/constants.py
@@ -227,12 +227,7 @@ WINDOW_LEVEL = {_("Abdomen"):(350,50), @@ -227,12 +227,7 @@ WINDOW_LEVEL = {_("Abdomen"):(350,50),
227 _("Vasculature - Hard"):(240,80), 227 _("Vasculature - Hard"):(240,80),
228 _("Vasculature - Soft"):(650,160)} 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 ICON_DIR = os.path.abspath(os.path.join('..', 'icons')) 232 ICON_DIR = os.path.abspath(os.path.join('..', 'icons'))
238 233
@@ -257,8 +252,8 @@ _("Black & White") @@ -257,8 +252,8 @@ _("Black & White")
257 _("Bone + Skin") 252 _("Bone + Skin")
258 _("Bone + Skin II") 253 _("Bone + Skin II")
259 _("Dark Bone") 254 _("Dark Bone")
260 -_("Glossy")  
261 -_("Glossy II") 255 +_("Glossy")
  256 +_("Glossy II")
262 _("Gold Bone") 257 _("Gold Bone")
263 _("High Contrast") 258 _("High Contrast")
264 _("Low Contrast") 259 _("Low Contrast")
@@ -339,7 +334,7 @@ FILETYPE_VRML = wx.NewId() @@ -339,7 +334,7 @@ FILETYPE_VRML = wx.NewId()
339 FILETYPE_OBJ = wx.NewId() 334 FILETYPE_OBJ = wx.NewId()
340 FILETYPE_VTP = wx.NewId() 335 FILETYPE_VTP = wx.NewId()
341 FILETYPE_PLY = wx.NewId() 336 FILETYPE_PLY = wx.NewId()
342 - 337 +
343 FILETYPE_IMAGEDATA = wx.NewId() 338 FILETYPE_IMAGEDATA = wx.NewId()
344 339
345 FILETYPE_BMP = wx.NewId() 340 FILETYPE_BMP = wx.NewId()
invesalius/data/imagedata_utils.py
@@ -49,16 +49,14 @@ def ResampleImage3D(imagedata, value): @@ -49,16 +49,14 @@ def ResampleImage3D(imagedata, value):
49 49
50 return resample.GetOutput() 50 return resample.GetOutput()
51 51
52 -def ResampleImage2D(imagedata, xy_dimension, 52 +def ResampleImage2D(imagedata, px, py,
53 update_progress = None): 53 update_progress = None):
54 """ 54 """
55 Resample vtkImageData matrix. 55 Resample vtkImageData matrix.
56 """ 56 """
57 extent = imagedata.GetExtent() 57 extent = imagedata.GetExtent()
58 - print "-----------------------------"  
59 - print "extent:", extent  
60 spacing = imagedata.GetSpacing() 58 spacing = imagedata.GetSpacing()
61 - print "spacing:", spacing 59 +
62 60
63 #if extent[1]==extent[3]: 61 #if extent[1]==extent[3]:
64 # f = extent[1] 62 # f = extent[1]
@@ -68,26 +66,24 @@ def ResampleImage2D(imagedata, xy_dimension, @@ -68,26 +66,24 @@ def ResampleImage2D(imagedata, xy_dimension,
68 # f = extent[3] 66 # f = extent[3]
69 67
70 if abs(extent[1]-extent[3]) < abs(extent[3]-extent[5]): 68 if abs(extent[1]-extent[3]) < abs(extent[3]-extent[5]):
71 - print 1  
72 f = extent[1] 69 f = extent[1]
73 elif abs(extent[1]-extent[5]) < abs(extent[1] - extent[3]): 70 elif abs(extent[1]-extent[5]) < abs(extent[1] - extent[3]):
74 - print 2  
75 f = extent[1] 71 f = extent[1]
76 elif abs(extent[3]-extent[5]) < abs(extent[1] - extent[3]): 72 elif abs(extent[3]-extent[5]) < abs(extent[1] - extent[3]):
77 - print 3  
78 f = extent[3] 73 f = extent[3]
79 else: 74 else:
80 - print 4  
81 f = extent[1] 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 resample = vtk.vtkImageResample() 82 resample = vtk.vtkImageResample()
87 resample.SetInput(imagedata) 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 if (update_progress): 87 if (update_progress):
92 message = "Generating multiplanar visualization..." 88 message = "Generating multiplanar visualization..."
93 resample.AddObserver("ProgressEvent", lambda obj, 89 resample.AddObserver("ProgressEvent", lambda obj,
@@ -189,7 +185,7 @@ def View(imagedata): @@ -189,7 +185,7 @@ def View(imagedata):
189 viewer.SetColorWindow(200) 185 viewer.SetColorWindow(200)
190 viewer.SetColorLevel(100) 186 viewer.SetColorLevel(100)
191 viewer.Render() 187 viewer.Render()
192 - 188 +
193 import time 189 import time
194 time.sleep(10) 190 time.sleep(10)
195 191
@@ -199,40 +195,50 @@ def ViewGDCM(imagedata): @@ -199,40 +195,50 @@ def ViewGDCM(imagedata):
199 viewer.SetColorWindow(500.) 195 viewer.SetColorWindow(500.)
200 viewer.SetColorLevel(50.) 196 viewer.SetColorLevel(50.)
201 viewer.Render() 197 viewer.Render()
202 - 198 +
203 import time 199 import time
204 time.sleep(5) 200 time.sleep(5)
205 201
206 202
207 - 203 +
208 def ExtractVOI(imagedata,xi,xf,yi,yf,zi,zf): 204 def ExtractVOI(imagedata,xi,xf,yi,yf,zi,zf):
209 """ 205 """
210 - Cropping the vtkImagedata according 206 + Cropping the vtkImagedata according
211 with values. 207 with values.
212 - """ 208 + """
213 voi = vtk.vtkExtractVOI() 209 voi = vtk.vtkExtractVOI()
214 voi.SetVOI(xi,xf,yi,yf,zi,zf) 210 voi.SetVOI(xi,xf,yi,yf,zi,zf)
215 voi.SetInput(imagedata) 211 voi.SetInput(imagedata)
216 voi.SetSampleRate(1, 1, 1) 212 voi.SetSampleRate(1, 1, 1)
217 - voi.Update() 213 + voi.Update()
218 return voi.GetOutput() 214 return voi.GetOutput()
219 215
220 def CreateImageData(filelist, zspacing, size, bits): 216 def CreateImageData(filelist, zspacing, size, bits):
221 message = "Generating multiplanar visualization..." 217 message = "Generating multiplanar visualization..."
222 - 218 +
223 if not const.VTK_WARNING: 219 if not const.VTK_WARNING:
224 fow = vtk.vtkFileOutputWindow() 220 fow = vtk.vtkFileOutputWindow()
225 fow.SetFileName('vtkoutput.txt') 221 fow.SetFileName('vtkoutput.txt')
226 ow = vtk.vtkOutputWindow() 222 ow = vtk.vtkOutputWindow()
227 ow.SetInstance(fow) 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 if not(const.REDUCE_IMAGEDATA_QUALITY): 235 if not(const.REDUCE_IMAGEDATA_QUALITY):
230 update_progress= vtk_utils.ShowProgress(1, dialog_type = "ProgressDialog") 236 update_progress= vtk_utils.ShowProgress(1, dialog_type = "ProgressDialog")
231 237
232 array = vtk.vtkStringArray() 238 array = vtk.vtkStringArray()
233 for x in xrange(len(filelist)): 239 for x in xrange(len(filelist)):
234 array.InsertValue(x,filelist[x]) 240 array.InsertValue(x,filelist[x])
235 - 241 +
236 reader = vtkgdcm.vtkGDCMImageReader() 242 reader = vtkgdcm.vtkGDCMImageReader()
237 reader.SetFileNames(array) 243 reader.SetFileNames(array)
238 reader.AddObserver("ProgressEvent", lambda obj,evt: 244 reader.AddObserver("ProgressEvent", lambda obj,evt:
@@ -245,16 +251,14 @@ def CreateImageData(filelist, zspacing, size, bits): @@ -245,16 +251,14 @@ def CreateImageData(filelist, zspacing, size, bits):
245 spacing = imagedata.GetSpacing() 251 spacing = imagedata.GetSpacing()
246 imagedata.SetSpacing(spacing[0], spacing[1], zspacing) 252 imagedata.SetSpacing(spacing[0], spacing[1], zspacing)
247 else: 253 else:
248 - 254 +
249 update_progress= vtk_utils.ShowProgress(2*len(filelist), 255 update_progress= vtk_utils.ShowProgress(2*len(filelist),
250 dialog_type = "ProgressDialog") 256 dialog_type = "ProgressDialog")
251 257
252 # Reformat each slice and future append them 258 # Reformat each slice and future append them
253 appender = vtk.vtkImageAppend() 259 appender = vtk.vtkImageAppend()
254 appender.SetAppendAxis(2) #Define Stack in Z 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 # Reformat each slice 263 # Reformat each slice
260 for x in xrange(len(filelist)): 264 for x in xrange(len(filelist)):
@@ -266,9 +270,9 @@ def CreateImageData(filelist, zspacing, size, bits): @@ -266,9 +270,9 @@ def CreateImageData(filelist, zspacing, size, bits):
266 reader.AddObserver("ProgressEvent", lambda obj,evt: 270 reader.AddObserver("ProgressEvent", lambda obj,evt:
267 update_progress(reader,message)) 271 update_progress(reader,message))
268 reader.Update() 272 reader.Update()
269 - 273 +
270 #Resample image in x,y dimension 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 #Stack images in Z axes 276 #Stack images in Z axes
273 appender.AddInput(slice_imagedata) 277 appender.AddInput(slice_imagedata)
274 #appender.AddObserver("ProgressEvent", lambda obj,evt:update_progress(appender)) 278 #appender.AddObserver("ProgressEvent", lambda obj,evt:update_progress(appender))
@@ -284,7 +288,7 @@ def CreateImageData(filelist, zspacing, size, bits): @@ -284,7 +288,7 @@ def CreateImageData(filelist, zspacing, size, bits):
284 imagedata.AddObserver("ProgressEvent", lambda obj,evt: 288 imagedata.AddObserver("ProgressEvent", lambda obj,evt:
285 update_progress(imagedata,message)) 289 update_progress(imagedata,message))
286 imagedata.Update() 290 imagedata.Update()
287 - 291 +
288 return imagedata 292 return imagedata
289 293
290 294
@@ -292,25 +296,25 @@ def CreateImageData(filelist, zspacing, size, bits): @@ -292,25 +296,25 @@ def CreateImageData(filelist, zspacing, size, bits):
292 class ImageCreator: 296 class ImageCreator:
293 def __init__(self): 297 def __init__(self):
294 ps.Publisher().sendMessage("Cancel imagedata load", self.CancelImageDataLoad) 298 ps.Publisher().sendMessage("Cancel imagedata load", self.CancelImageDataLoad)
295 - 299 +
296 def CancelImageDataLoad(self, evt_pusub): 300 def CancelImageDataLoad(self, evt_pusub):
297 self.running = evt_pusub.data 301 self.running = evt_pusub.data
298 - 302 +
299 def CreateImageData(filelist, zspacing): 303 def CreateImageData(filelist, zspacing):
300 message = "Generating multiplanar visualization..." 304 message = "Generating multiplanar visualization..."
301 if not(const.REDUCE_IMAGEDATA_QUALITY): 305 if not(const.REDUCE_IMAGEDATA_QUALITY):
302 update_progress= vtk_utils.ShowProgress(1) 306 update_progress= vtk_utils.ShowProgress(1)
303 - 307 +
304 array = vtk.vtkStringArray() 308 array = vtk.vtkStringArray()
305 for x in xrange(len(filelist)): 309 for x in xrange(len(filelist)):
306 array.InsertValue(x,filelist[x]) 310 array.InsertValue(x,filelist[x])
307 - 311 +
308 reader = vtkgdcm.vtkGDCMImageReader() 312 reader = vtkgdcm.vtkGDCMImageReader()
309 reader.SetFileNames(array) 313 reader.SetFileNames(array)
310 reader.AddObserver("ProgressEvent", lambda obj,evt: 314 reader.AddObserver("ProgressEvent", lambda obj,evt:
311 update_progress(reader,message)) 315 update_progress(reader,message))
312 reader.Update() 316 reader.Update()
313 - 317 +
314 # The zpacing is a DicomGroup property, so we need to set it 318 # The zpacing is a DicomGroup property, so we need to set it
315 imagedata = vtk.vtkImageData() 319 imagedata = vtk.vtkImageData()
316 imagedata.DeepCopy(reader.GetOutput()) 320 imagedata.DeepCopy(reader.GetOutput())
@@ -319,11 +323,11 @@ class ImageCreator: @@ -319,11 +323,11 @@ class ImageCreator:
319 else: 323 else:
320 update_progress= vtk_utils.ShowProgress(2*len(filelist), 324 update_progress= vtk_utils.ShowProgress(2*len(filelist),
321 dialog_type = "ProgressDialog") 325 dialog_type = "ProgressDialog")
322 - 326 +
323 # Reformat each slice and future append them 327 # Reformat each slice and future append them
324 appender = vtk.vtkImageAppend() 328 appender = vtk.vtkImageAppend()
325 appender.SetAppendAxis(2) #Define Stack in Z 329 appender.SetAppendAxis(2) #Define Stack in Z
326 - 330 +
327 # Reformat each slice 331 # Reformat each slice
328 for x in xrange(len(filelist)): 332 for x in xrange(len(filelist)):
329 # TODO: We need to check this automatically according 333 # TODO: We need to check this automatically according
@@ -334,27 +338,27 @@ class ImageCreator: @@ -334,27 +338,27 @@ class ImageCreator:
334 reader.AddObserver("ProgressEvent", lambda obj,evt: 338 reader.AddObserver("ProgressEvent", lambda obj,evt:
335 update_progress(reader,message)) 339 update_progress(reader,message))
336 reader.Update() 340 reader.Update()
337 - 341 +
338 #Resample image in x,y dimension 342 #Resample image in x,y dimension
339 - 343 +
340 slice_imagedata = ResampleImage2D(reader.GetOutput(), 256, update_progress) 344 slice_imagedata = ResampleImage2D(reader.GetOutput(), 256, update_progress)
341 - 345 +
342 #Stack images in Z axes 346 #Stack images in Z axes
343 appender.AddInput(slice_imagedata) 347 appender.AddInput(slice_imagedata)
344 #appender.AddObserver("ProgressEvent", lambda obj,evt:update_progress(appender)) 348 #appender.AddObserver("ProgressEvent", lambda obj,evt:update_progress(appender))
345 appender.Update() 349 appender.Update()
346 - 350 +
347 # The zpacing is a DicomGroup property, so we need to set it 351 # The zpacing is a DicomGroup property, so we need to set it
348 imagedata = vtk.vtkImageData() 352 imagedata = vtk.vtkImageData()
349 imagedata.DeepCopy(appender.GetOutput()) 353 imagedata.DeepCopy(appender.GetOutput())
350 spacing = imagedata.GetSpacing() 354 spacing = imagedata.GetSpacing()
351 - 355 +
352 imagedata.SetSpacing(spacing[0], spacing[1], zspacing) 356 imagedata.SetSpacing(spacing[0], spacing[1], zspacing)
353 - 357 +
354 imagedata.AddObserver("ProgressEvent", lambda obj,evt: 358 imagedata.AddObserver("ProgressEvent", lambda obj,evt:
355 update_progress(imagedata,message)) 359 update_progress(imagedata,message))
356 imagedata.Update() 360 imagedata.Update()
357 - 361 +
358 return imagedata 362 return imagedata
359 """ 363 """
360 364
invesalius/utils.py
@@ -16,9 +16,11 @@ @@ -16,9 +16,11 @@
16 # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais 16 # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais
17 # detalhes. 17 # detalhes.
18 #-------------------------------------------------------------------------- 18 #--------------------------------------------------------------------------
  19 +import os
  20 +import platform
19 import subprocess 21 import subprocess
20 import re 22 import re
21 -import os 23 +import sys
22 24
23 25
24 def debug(error_str): 26 def debug(error_str):
@@ -91,19 +93,73 @@ def frange(start, end=None, inc=None): @@ -91,19 +93,73 @@ def frange(start, end=None, inc=None):
91 def PredictingMemory(qtd, x, y, p): 93 def PredictingMemory(qtd, x, y, p):
92 m = qtd * (x * y * p) 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 def BytesConvert(bytes): 165 def BytesConvert(bytes):
@@ -155,6 +211,10 @@ def GetWindowsInformation(): @@ -155,6 +211,10 @@ def GetWindowsInformation():
155 processor_clock, total_physical_memory, 211 processor_clock, total_physical_memory,
156 available_physical_memory) 212 available_physical_memory)
157 213
  214 +def GetDarwinInformation():
  215 + memory = 2.0
  216 + return (memory)
  217 +
158 218
159 def GetLinuxInformation(): 219 def GetLinuxInformation():
160 220
@@ -169,8 +229,7 @@ def GetLinuxInformation(): @@ -169,8 +229,7 @@ def GetLinuxInformation():
169 229
170 230
171 #processor_clock = float(re.findall('[0-9]+', processor_clock)[0]) 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 def LinuxCommand(command): 235 def LinuxCommand(command):