Commit cd0cef0954f13add478e94eb9795808562db9a0c
Committed by
GitHub
1 parent
8ba6ba8d
Exists in
master
Remove vtkgdcm (#201)
* generating thumbs only using gdcm + numpy * applying intercept slop * generating thumbnails and slices without vtkgdcmreader * Using numpy and gdcm in dicom_preview_panel * loading multiframe dicom * working with rgb dicoms * little improvements * removed all vtkgdcm importing * getting spacing from gdcmimagereader
Showing
7 changed files
with
114 additions
and
318 deletions
Show diff stats
invesalius/control.py
... | ... | @@ -824,7 +824,6 @@ class Controller(): |
824 | 824 | self.matrix, scalar_range, self.filename = image_utils.dcm2memmap(filelist, size, |
825 | 825 | orientation, resolution_percentage) |
826 | 826 | |
827 | - print(xyspacing, zspacing) | |
828 | 827 | if orientation == 'AXIAL': |
829 | 828 | spacing = xyspacing[0], xyspacing[1], zspacing |
830 | 829 | elif orientation == 'CORONAL': |
... | ... | @@ -832,7 +831,10 @@ class Controller(): |
832 | 831 | elif orientation == 'SAGITTAL': |
833 | 832 | spacing = zspacing, xyspacing[1], xyspacing[0] |
834 | 833 | else: |
835 | - self.matrix, spacing, scalar_range, self.filename = image_utils.dcmmf2memmap(filelist[0], orientation) | |
834 | + print(">>>>>> filelist", filelist) | |
835 | + self.matrix, scalar_range, spacing, self.filename = image_utils.dcmmf2memmap(filelist[0], orientation) | |
836 | + | |
837 | + print(">>>>>> spacing", spacing) | |
836 | 838 | |
837 | 839 | self.Slice = sl.Slice() |
838 | 840 | self.Slice.matrix = self.matrix | ... | ... |
invesalius/data/converters.py
... | ... | @@ -17,10 +17,13 @@ |
17 | 17 | # detalhes. |
18 | 18 | #-------------------------------------------------------------------------- |
19 | 19 | |
20 | -import numpy | |
20 | +import gdcm | |
21 | +import numpy as np | |
21 | 22 | import vtk |
23 | + | |
22 | 24 | from vtk.util import numpy_support |
23 | 25 | |
26 | + | |
24 | 27 | def to_vtk(n_array, spacing, slice_number, orientation, origin=(0, 0, 0), padding=(0, 0, 0)): |
25 | 28 | |
26 | 29 | if orientation == "SAGITTAL": |
... | ... | @@ -84,3 +87,40 @@ def np_rgba_to_vtk(n_array, spacing=(1.0, 1.0, 1.0)): |
84 | 87 | image.GetPointData().SetScalars(v_image) |
85 | 88 | |
86 | 89 | return image |
90 | + | |
91 | + | |
92 | +# Based on http://gdcm.sourceforge.net/html/ConvertNumpy_8py-example.html | |
93 | +def gdcm_to_numpy(image, apply_intercep_scale=True): | |
94 | + map_gdcm_np = { | |
95 | + gdcm.PixelFormat.UINT8 :np.uint8, | |
96 | + gdcm.PixelFormat.INT8 :np.int8, | |
97 | + #gdcm.PixelFormat.UINT12 :np.uint12, | |
98 | + #gdcm.PixelFormat.INT12 :np.int12, | |
99 | + gdcm.PixelFormat.UINT16 :np.uint16, | |
100 | + gdcm.PixelFormat.INT16 :np.int16, | |
101 | + gdcm.PixelFormat.UINT32 :np.uint32, | |
102 | + gdcm.PixelFormat.INT32 :np.int32, | |
103 | + #gdcm.PixelFormat.FLOAT16:np.float16, | |
104 | + gdcm.PixelFormat.FLOAT32:np.float32, | |
105 | + gdcm.PixelFormat.FLOAT64:np.float64, | |
106 | + } | |
107 | + | |
108 | + pf = image.GetPixelFormat() | |
109 | + if image.GetNumberOfDimensions() == 3: | |
110 | + shape = image.GetDimension(2), image.GetDimension(1), image.GetDimension(0), pf.GetSamplesPerPixel() | |
111 | + else: | |
112 | + shape = image.GetDimension(1), image.GetDimension(0), pf.GetSamplesPerPixel() | |
113 | + dtype = map_gdcm_np[pf.GetScalarType()] | |
114 | + gdcm_array = image.GetBuffer() | |
115 | + np_array = np.frombuffer(gdcm_array.encode('utf-8', errors="surrogateescape"), dtype=dtype) | |
116 | + np_array.shape = shape | |
117 | + np_array = np_array.squeeze() | |
118 | + | |
119 | + if apply_intercep_scale: | |
120 | + shift = image.GetIntercept() | |
121 | + scale = image.GetSlope() | |
122 | + output = np.empty_like(np_array, np.int16) | |
123 | + output[:] = scale * np_array + shift | |
124 | + return output | |
125 | + else: | |
126 | + return np_array | ... | ... |
invesalius/data/imagedata_utils.py
... | ... | @@ -23,9 +23,10 @@ import sys |
23 | 23 | import tempfile |
24 | 24 | |
25 | 25 | import gdcm |
26 | +import imageio | |
26 | 27 | import numpy |
28 | +import numpy as np | |
27 | 29 | import vtk |
28 | -import vtkgdcm | |
29 | 30 | from wx.lib.pubsub import pub as Publisher |
30 | 31 | |
31 | 32 | from scipy.ndimage import shift, zoom |
... | ... | @@ -124,20 +125,15 @@ def resize_slice(im_array, resolution_percentage): |
124 | 125 | return out |
125 | 126 | |
126 | 127 | |
127 | -def read_dcm_slice_as_np(filename, resolution_percentage=1.0): | |
128 | - """ | |
129 | - read a dicom slice file and return the slice as numpy ndarray | |
130 | - """ | |
131 | - dcm_reader = vtkgdcm.vtkGDCMImageReader() | |
132 | - dcm_reader.SetFileName(filename) | |
133 | - dcm_reader.Update() | |
134 | - image = dcm_reader.GetOutput() | |
128 | +def read_dcm_slice_as_np2(filename, resolution_percentage=1.0): | |
129 | + reader = gdcm.ImageReader() | |
130 | + reader.SetFileName(filename) | |
131 | + reader.Read() | |
132 | + image = reader.GetImage() | |
133 | + output = converters.gdcm_to_numpy(image) | |
135 | 134 | if resolution_percentage < 1.0: |
136 | - image = ResampleImage2D(image, resolution_percentage=resolution_percentage) | |
137 | - dx, dy, dz = image.GetDimensions() | |
138 | - im_array = numpy_support.vtk_to_numpy(image.GetPointData().GetScalars()) | |
139 | - im_array.shape = dy, dx | |
140 | - return im_array | |
135 | + output = zoom(output, resolution_percentage) | |
136 | + return output | |
141 | 137 | |
142 | 138 | |
143 | 139 | def FixGantryTilt(matrix, spacing, tilt): |
... | ... | @@ -240,17 +236,6 @@ def View(imagedata): |
240 | 236 | import time |
241 | 237 | time.sleep(10) |
242 | 238 | |
243 | -def ViewGDCM(imagedata): | |
244 | - viewer = vtkgdcm.vtkImageColorViewer() | |
245 | - viewer.SetInput(reader.GetOutput()) | |
246 | - viewer.SetColorWindow(500.) | |
247 | - viewer.SetColorLevel(50.) | |
248 | - viewer.Render() | |
249 | - | |
250 | - import time | |
251 | - time.sleep(5) | |
252 | - | |
253 | - | |
254 | 239 | |
255 | 240 | def ExtractVOI(imagedata,xi,xf,yi,yf,zi,zf): |
256 | 241 | """ |
... | ... | @@ -265,267 +250,33 @@ def ExtractVOI(imagedata,xi,xf,yi,yf,zi,zf): |
265 | 250 | return voi.GetOutput() |
266 | 251 | |
267 | 252 | |
268 | -def create_dicom_thumbnails(filename, window=None, level=None): | |
269 | - rvtk = vtkgdcm.vtkGDCMImageReader() | |
270 | - rvtk.SetFileName(utils.encode(filename, const.FS_ENCODE)) | |
271 | - rvtk.Update() | |
272 | - | |
273 | - img = rvtk.GetOutput() | |
253 | +def create_dicom_thumbnails(image, window=None, level=None): | |
254 | + pf = image.GetPixelFormat() | |
255 | + np_image = converters.gdcm_to_numpy(image, pf.GetSamplesPerPixel() == 1) | |
274 | 256 | if window is None or level is None: |
275 | - _min, _max = img.GetScalarRange() | |
257 | + _min, _max = np_image.min(), np_image.max() | |
276 | 258 | window = _max - _min |
277 | 259 | level = _min + window / 2 |
278 | 260 | |
279 | - dx, dy, dz = img.GetDimensions() | |
280 | - | |
281 | - if dz > 1: | |
261 | + if image.GetNumberOfDimensions() >= 3: | |
282 | 262 | thumbnail_paths = [] |
283 | - for i in range(dz): | |
284 | - img_slice = ExtractVOI(img, 0, dx-1, 0, dy-1, i, i+1) | |
285 | - | |
286 | - colorer = vtk.vtkImageMapToWindowLevelColors() | |
287 | - colorer.SetInputData(img_slice) | |
288 | - colorer.SetWindow(window) | |
289 | - colorer.SetLevel(level) | |
290 | - colorer.SetOutputFormatToRGB() | |
291 | - colorer.Update() | |
292 | - | |
293 | - resample = vtk.vtkImageResample() | |
294 | - resample.SetInputData(colorer.GetOutput()) | |
295 | - resample.SetAxisMagnificationFactor ( 0, 0.25 ) | |
296 | - resample.SetAxisMagnificationFactor ( 1, 0.25 ) | |
297 | - resample.SetAxisMagnificationFactor ( 2, 1 ) | |
298 | - resample.Update() | |
299 | - | |
300 | - thumbnail_path = tempfile.mktemp() | |
301 | - | |
302 | - write_png = vtk.vtkPNGWriter() | |
303 | - write_png.SetInputData(resample.GetOutput()) | |
304 | - write_png.SetFileName(thumbnail_path) | |
305 | - write_png.Write() | |
306 | - | |
263 | + for i in range(np_image.shape[0]): | |
264 | + thumb_image = zoom(np_image[i], 0.25) | |
265 | + thumb_image = np.array(get_LUT_value_255(thumb_image, window, level), dtype=np.uint8) | |
266 | + thumbnail_path = tempfile.mktemp(prefix='thumb_', suffix='.png') | |
267 | + imageio.imsave(thumbnail_path, thumb_image) | |
307 | 268 | thumbnail_paths.append(thumbnail_path) |
308 | - | |
309 | 269 | return thumbnail_paths |
310 | 270 | else: |
311 | - colorer = vtk.vtkImageMapToWindowLevelColors() | |
312 | - colorer.SetInputData(img) | |
313 | - colorer.SetWindow(window) | |
314 | - colorer.SetLevel(level) | |
315 | - colorer.SetOutputFormatToRGB() | |
316 | - colorer.Update() | |
317 | - | |
318 | - resample = vtk.vtkImageResample() | |
319 | - resample.SetInputData(colorer.GetOutput()) | |
320 | - resample.SetAxisMagnificationFactor ( 0, 0.25 ) | |
321 | - resample.SetAxisMagnificationFactor ( 1, 0.25 ) | |
322 | - resample.SetAxisMagnificationFactor ( 2, 1 ) | |
323 | - resample.Update() | |
324 | - | |
325 | - thumbnail_path = tempfile.mktemp() | |
326 | - | |
327 | - write_png = vtk.vtkPNGWriter() | |
328 | - write_png.SetInputData(resample.GetOutput()) | |
329 | - write_png.SetFileName(thumbnail_path) | |
330 | - write_png.Write() | |
331 | - | |
332 | - return thumbnail_path | |
333 | - | |
334 | - | |
335 | -def CreateImageData(filelist, zspacing, xyspacing,size, | |
336 | - bits, use_dcmspacing): | |
337 | - message = _("Generating multiplanar visualization...") | |
338 | - | |
339 | - if not const.VTK_WARNING: | |
340 | - log_path = os.path.join(inv_paths.USER_LOG_DIR, 'vtkoutput.txt') | |
341 | - fow = vtk.vtkFileOutputWindow() | |
342 | - fow.SetFileName(log_path) | |
343 | - ow = vtk.vtkOutputWindow() | |
344 | - ow.SetInstance(fow) | |
345 | - | |
346 | - x,y = size | |
347 | - px, py = utils.predict_memory(len(filelist), x, y, bits) | |
348 | - | |
349 | - utils.debug("Image Resized to >>> %f x %f" % (px, py)) | |
350 | - | |
351 | - if (x == px) and (y == py): | |
352 | - const.REDUCE_IMAGEDATA_QUALITY = 0 | |
353 | - else: | |
354 | - const.REDUCE_IMAGEDATA_QUALITY = 1 | |
355 | - | |
356 | - if not(const.REDUCE_IMAGEDATA_QUALITY): | |
357 | - update_progress= vtk_utils.ShowProgress(1, dialog_type = "ProgressDialog") | |
358 | - | |
359 | - array = vtk.vtkStringArray() | |
360 | - for x in range(len(filelist)): | |
361 | - array.InsertValue(x,filelist[x]) | |
362 | - | |
363 | - reader = vtkgdcm.vtkGDCMImageReader() | |
364 | - reader.SetFileNames(array) | |
365 | - reader.AddObserver("ProgressEvent", lambda obj,evt: | |
366 | - update_progress(reader,message)) | |
367 | - reader.Update() | |
368 | - | |
369 | - # The zpacing is a DicomGroup property, so we need to set it | |
370 | - imagedata = vtk.vtkImageData() | |
371 | - imagedata.DeepCopy(reader.GetOutput()) | |
372 | - if (use_dcmspacing): | |
373 | - spacing = xyspacing | |
374 | - spacing[2] = zspacing | |
375 | - else: | |
376 | - spacing = imagedata.GetSpacing() | |
377 | - | |
378 | - imagedata.SetSpacing(spacing[0], spacing[1], zspacing) | |
379 | - else: | |
380 | - | |
381 | - update_progress= vtk_utils.ShowProgress(2*len(filelist), | |
382 | - dialog_type = "ProgressDialog") | |
383 | - | |
384 | - # Reformat each slice and future append them | |
385 | - appender = vtk.vtkImageAppend() | |
386 | - appender.SetAppendAxis(2) #Define Stack in Z | |
387 | - | |
388 | - | |
389 | - # Reformat each slice | |
390 | - for x in range(len(filelist)): | |
391 | - # TODO: We need to check this automatically according | |
392 | - # to each computer's architecture | |
393 | - # If the resolution of the matrix is too large | |
394 | - reader = vtkgdcm.vtkGDCMImageReader() | |
395 | - reader.SetFileName(filelist[x]) | |
396 | - reader.AddObserver("ProgressEvent", lambda obj,evt: | |
397 | - update_progress(reader,message)) | |
398 | - reader.Update() | |
399 | - | |
400 | - if (use_dcmspacing): | |
401 | - spacing = xyspacing | |
402 | - spacing[2] = zspacing | |
403 | - else: | |
404 | - spacing = reader.GetOutput().GetSpacing() | |
405 | - | |
406 | - tmp_image = vtk.vtkImageData() | |
407 | - tmp_image.DeepCopy(reader.GetOutput()) | |
408 | - tmp_image.SetSpacing(spacing[0], spacing[1], zspacing) | |
409 | - tmp_image.Update() | |
410 | - | |
411 | - #Resample image in x,y dimension | |
412 | - slice_imagedata = ResampleImage2D(tmp_image, px, py, update_progress) | |
413 | - #Stack images in Z axes | |
414 | - appender.AddInput(slice_imagedata) | |
415 | - #appender.AddObserver("ProgressEvent", lambda obj,evt:update_progress(appender)) | |
416 | - appender.Update() | |
417 | - | |
418 | - spacing = appender.GetOutput().GetSpacing() | |
419 | - | |
420 | - # The zpacing is a DicomGroup property, so we need to set it | |
421 | - imagedata = vtk.vtkImageData() | |
422 | - imagedata.DeepCopy(appender.GetOutput()) | |
423 | - imagedata.SetSpacing(spacing[0], spacing[1], zspacing) | |
424 | - | |
425 | - imagedata.AddObserver("ProgressEvent", lambda obj,evt: | |
426 | - update_progress(imagedata,message)) | |
427 | - imagedata.Update() | |
428 | - | |
429 | - return imagedata | |
430 | - | |
431 | - | |
432 | -class ImageCreator: | |
433 | - def __init__(self): | |
434 | - self.running = True | |
435 | - Publisher.subscribe(self.CancelImageDataLoad, "Cancel DICOM load") | |
436 | - | |
437 | - def CancelImageDataLoad(self, evt_pusub): | |
438 | - utils.debug("Canceling") | |
439 | - self.running = False | |
440 | - | |
441 | - def CreateImageData(self, filelist, zspacing, size, bits): | |
442 | - message = _("Generating multiplanar visualization...") | |
443 | - | |
444 | - if not const.VTK_WARNING: | |
445 | - log_path = os.path.join(inv_paths.USER_LOG_DIR, 'vtkoutput.txt') | |
446 | - fow = vtk.vtkFileOutputWindow() | |
447 | - fow.SetFileName(log_path) | |
448 | - ow = vtk.vtkOutputWindow() | |
449 | - ow.SetInstance(fow) | |
450 | - | |
451 | - x,y = size | |
452 | - px, py = utils.predict_memory(len(filelist), x, y, bits) | |
453 | - utils.debug("Image Resized to >>> %f x %f" % (px, py)) | |
454 | - | |
455 | - if (x == px) and (y == py): | |
456 | - const.REDUCE_IMAGEDATA_QUALITY = 0 | |
271 | + thumbnail_path = tempfile.mktemp(prefix='thumb_', suffix='.png') | |
272 | + if pf.GetSamplesPerPixel() == 1: | |
273 | + thumb_image = zoom(np_image, 0.25) | |
274 | + thumb_image = np.array(get_LUT_value_255(thumb_image, window, level), dtype=np.uint8) | |
457 | 275 | else: |
458 | - const.REDUCE_IMAGEDATA_QUALITY = 1 | |
459 | - | |
460 | - if not(const.REDUCE_IMAGEDATA_QUALITY): | |
461 | - update_progress= vtk_utils.ShowProgress(1, dialog_type = "ProgressDialog") | |
462 | - | |
463 | - array = vtk.vtkStringArray() | |
464 | - for x in range(len(filelist)): | |
465 | - if not self.running: | |
466 | - return False | |
467 | - array.InsertValue(x,filelist[x]) | |
468 | - | |
469 | - if not self.running: | |
470 | - return False | |
471 | - reader = vtkgdcm.vtkGDCMImageReader() | |
472 | - reader.SetFileNames(array) | |
473 | - reader.AddObserver("ProgressEvent", lambda obj,evt: | |
474 | - update_progress(reader,message)) | |
475 | - reader.Update() | |
476 | - | |
477 | - if not self.running: | |
478 | - reader.AbortExecuteOn() | |
479 | - return False | |
480 | - # The zpacing is a DicomGroup property, so we need to set it | |
481 | - imagedata = vtk.vtkImageData() | |
482 | - imagedata.DeepCopy(reader.GetOutput()) | |
483 | - spacing = imagedata.GetSpacing() | |
484 | - imagedata.SetSpacing(spacing[0], spacing[1], zspacing) | |
485 | - else: | |
486 | - | |
487 | - update_progress= vtk_utils.ShowProgress(2*len(filelist), | |
488 | - dialog_type = "ProgressDialog") | |
489 | - | |
490 | - # Reformat each slice and future append them | |
491 | - appender = vtk.vtkImageAppend() | |
492 | - appender.SetAppendAxis(2) #Define Stack in Z | |
493 | - | |
494 | - | |
495 | - # Reformat each slice | |
496 | - for x in range(len(filelist)): | |
497 | - # TODO: We need to check this automatically according | |
498 | - # to each computer's architecture | |
499 | - # If the resolution of the matrix is too large | |
500 | - if not self.running: | |
501 | - return False | |
502 | - reader = vtkgdcm.vtkGDCMImageReader() | |
503 | - reader.SetFileName(filelist[x]) | |
504 | - reader.AddObserver("ProgressEvent", lambda obj,evt: | |
505 | - update_progress(reader,message)) | |
506 | - reader.Update() | |
507 | - | |
508 | - #Resample image in x,y dimension | |
509 | - slice_imagedata = ResampleImage2D(reader.GetOutput(), px, py, update_progress) | |
510 | - #Stack images in Z axes | |
511 | - appender.AddInput(slice_imagedata) | |
512 | - #appender.AddObserver("ProgressEvent", lambda obj,evt:update_progress(appender)) | |
513 | - appender.Update() | |
514 | - | |
515 | - # The zpacing is a DicomGroup property, so we need to set it | |
516 | - if not self.running: | |
517 | - return False | |
518 | - imagedata = vtk.vtkImageData() | |
519 | - imagedata.DeepCopy(appender.GetOutput()) | |
520 | - spacing = imagedata.GetSpacing() | |
521 | - | |
522 | - imagedata.SetSpacing(spacing[0], spacing[1], zspacing) | |
523 | - | |
524 | - imagedata.AddObserver("ProgressEvent", lambda obj,evt: | |
525 | - update_progress(imagedata,message)) | |
526 | - imagedata.Update() | |
276 | + thumb_image = zoom(np_image, (0.25, 0.25, 1)) | |
277 | + imageio.imsave(thumbnail_path, thumb_image) | |
278 | + return thumbnail_path | |
527 | 279 | |
528 | - return imagedata | |
529 | 280 | |
530 | 281 | def bitmap2memmap(files, slice_size, orientation, spacing, resolution_percentage): |
531 | 282 | """ |
... | ... | @@ -626,7 +377,6 @@ def bitmap2memmap(files, slice_size, orientation, spacing, resolution_percentage |
626 | 377 | return matrix, scalar_range, temp_file |
627 | 378 | |
628 | 379 | |
629 | - | |
630 | 380 | def dcm2memmap(files, slice_size, orientation, resolution_percentage): |
631 | 381 | """ |
632 | 382 | From a list of dicom files it creates memmap file in the temp folder and |
... | ... | @@ -635,7 +385,7 @@ def dcm2memmap(files, slice_size, orientation, resolution_percentage): |
635 | 385 | message = _("Generating multiplanar visualization...") |
636 | 386 | update_progress= vtk_utils.ShowProgress(len(files) - 1, dialog_type = "ProgressDialog") |
637 | 387 | |
638 | - first_slice = read_dcm_slice_as_np(files[0], resolution_percentage) | |
388 | + first_slice = read_dcm_slice_as_np2(files[0], resolution_percentage) | |
639 | 389 | slice_size = first_slice.shape[::-1] |
640 | 390 | |
641 | 391 | temp_file = tempfile.mktemp() |
... | ... | @@ -649,7 +399,7 @@ def dcm2memmap(files, slice_size, orientation, resolution_percentage): |
649 | 399 | |
650 | 400 | matrix = numpy.memmap(temp_file, mode='w+', dtype='int16', shape=shape) |
651 | 401 | for n, f in enumerate(files): |
652 | - im_array = read_dcm_slice_as_np(f, resolution_percentage) | |
402 | + im_array = read_dcm_slice_as_np2(f, resolution_percentage)[::-1] | |
653 | 403 | |
654 | 404 | if orientation == 'CORONAL': |
655 | 405 | matrix[:, shape[1] - n - 1, :] = im_array |
... | ... | @@ -669,37 +419,35 @@ def dcm2memmap(files, slice_size, orientation, resolution_percentage): |
669 | 419 | |
670 | 420 | |
671 | 421 | def dcmmf2memmap(dcm_file, orientation): |
672 | - r = vtkgdcm.vtkGDCMImageReader() | |
673 | - r.SetFileName(dcm_file) | |
674 | - r.Update() | |
675 | - | |
422 | + reader = gdcm.ImageReader() | |
423 | + reader.SetFileName(dcm_file) | |
424 | + reader.Read() | |
425 | + image = reader.GetImage() | |
426 | + xs, ys, zs = image.GetSpacing() | |
427 | + pf = image.GetPixelFormat() | |
428 | + np_image = converters.gdcm_to_numpy(image, pf.GetSamplesPerPixel() == 1) | |
676 | 429 | temp_file = tempfile.mktemp() |
677 | - | |
678 | - o = r.GetOutput() | |
679 | - x, y, z = o.GetDimensions() | |
680 | - spacing = o.GetSpacing() | |
681 | - | |
682 | - matrix = numpy.memmap(temp_file, mode='w+', dtype='int16', shape=(z, y, x)) | |
683 | - | |
684 | - d = numpy_support.vtk_to_numpy(o.GetPointData().GetScalars()) | |
685 | - d.shape = z, y, x | |
430 | + matrix = numpy.memmap(temp_file, mode='w+', dtype='int16', shape=np_image.shape) | |
431 | + print("Number of dimensions", np_image.shape) | |
432 | + z, y, x = np_image.shape | |
686 | 433 | if orientation == 'CORONAL': |
434 | + spacing = xs, zs, ys | |
687 | 435 | matrix.shape = y, z, x |
688 | 436 | for n in range(z): |
689 | - matrix[:, n, :] = d[n] | |
437 | + matrix[:, n, :] = np_image[n][::-1] | |
690 | 438 | elif orientation == 'SAGITTAL': |
691 | - matrix.shape = x, z, y | |
439 | + spacing = zs, ys, xs | |
440 | + matrix.shape = y, x, z | |
692 | 441 | for n in range(z): |
693 | - matrix[:, :, n] = d[n] | |
442 | + matrix[:, :, n] = np_image[n][::-1] | |
694 | 443 | else: |
695 | - matrix[:] = d | |
444 | + spacing = xs, ys, zs | |
445 | + matrix[:] = np_image[:, ::-1, :] | |
696 | 446 | |
697 | 447 | matrix.flush() |
698 | 448 | scalar_range = matrix.min(), matrix.max() |
699 | 449 | |
700 | - print("ORIENTATION", orientation) | |
701 | - | |
702 | - return matrix, spacing, scalar_range, temp_file | |
450 | + return matrix, scalar_range, spacing, temp_file | |
703 | 451 | |
704 | 452 | |
705 | 453 | def img2memmap(group): |
... | ... | @@ -753,3 +501,14 @@ def imgnormalize(data, srange=(0, 255)): |
753 | 501 | datan = datan.astype(numpy.int16) |
754 | 502 | |
755 | 503 | return datan |
504 | + | |
505 | + | |
506 | +def get_LUT_value_255(data, window, level): | |
507 | + shape = data.shape | |
508 | + data_ = data.ravel() | |
509 | + data = np.piecewise(data_, | |
510 | + [data_ <= (level - 0.5 - (window-1)/2), | |
511 | + data_ > (level - 0.5 + (window-1)/2)], | |
512 | + [0, 255, lambda data_: ((data_ - (level - 0.5))/(window-1) + 0.5)*(255)]) | |
513 | + data.shape = shape | |
514 | + return data | ... | ... |
invesalius/gui/bitmap_preview_panel.py
invesalius/gui/dicom_preview_panel.py
... | ... | @@ -35,7 +35,8 @@ import invesalius.constants as const |
35 | 35 | import invesalius.reader.dicom_reader as dicom_reader |
36 | 36 | import invesalius.data.vtk_utils as vtku |
37 | 37 | import invesalius.utils as utils |
38 | -import vtkgdcm | |
38 | +from invesalius.data import imagedata_utils | |
39 | +from invesalius.data import converters | |
39 | 40 | |
40 | 41 | if sys.platform == 'win32': |
41 | 42 | try: |
... | ... | @@ -890,20 +891,20 @@ class SingleImagePreview(wx.Panel): |
890 | 891 | reader.Update() |
891 | 892 | |
892 | 893 | image = reader.GetOutput() |
893 | - | |
894 | 894 | else: |
895 | - rdicom = vtkgdcm.vtkGDCMImageReader() | |
895 | + filename = dicom.image.file | |
896 | 896 | if _has_win32api: |
897 | - rdicom.SetFileName(win32api.GetShortPathName(dicom.image.file).encode(const.FS_ENCODE)) | |
898 | - else: | |
899 | - rdicom.SetFileName(dicom.image.file) | |
900 | - rdicom.Update() | |
897 | + filename = win32api.GetShortPathName(filename).encode(const.FS_ENCODE) | |
898 | + | |
899 | + np_image = imagedata_utils.read_dcm_slice_as_np2(filename) | |
900 | + print(">>> spacing", dicom.image.spacing) | |
901 | + vtk_image = converters.to_vtk(np_image, dicom.image.spacing, 0, 'AXIAL') | |
901 | 902 | |
902 | 903 | # ADJUST CONTRAST |
903 | 904 | window_level = dicom.image.level |
904 | 905 | window_width = dicom.image.window |
905 | 906 | colorer = vtk.vtkImageMapToWindowLevelColors() |
906 | - colorer.SetInputConnection(rdicom.GetOutputPort()) | |
907 | + colorer.SetInputData(vtk_image) | |
907 | 908 | colorer.SetWindow(float(window_width)) |
908 | 909 | colorer.SetLevel(float(window_level)) |
909 | 910 | colorer.Update() | ... | ... |
invesalius/reader/dicom.py
invesalius/reader/dicom_reader.py
... | ... | @@ -24,7 +24,6 @@ import sys |
24 | 24 | from multiprocessing import cpu_count |
25 | 25 | |
26 | 26 | import vtk |
27 | -import vtkgdcm | |
28 | 27 | import gdcm |
29 | 28 | from wx.lib.pubsub import pub as Publisher |
30 | 29 | |
... | ... | @@ -202,14 +201,11 @@ class LoadDicom: |
202 | 201 | level = None |
203 | 202 | window = None |
204 | 203 | |
205 | - if _has_win32api: | |
206 | - thumbnail_path = imagedata_utils.create_dicom_thumbnails(win32api.GetShortPathName(self.filepath), window, level) | |
207 | - else: | |
208 | - thumbnail_path = imagedata_utils.create_dicom_thumbnails(self.filepath, window, level) | |
204 | + img = reader.GetImage() | |
205 | + thumbnail_path = imagedata_utils.create_dicom_thumbnails(img, window, level) | |
209 | 206 | |
210 | 207 | #------ Verify the orientation -------------------------------- |
211 | 208 | |
212 | - img = reader.GetImage() | |
213 | 209 | direc_cosines = img.GetDirectionCosines() |
214 | 210 | orientation = gdcm.Orientation() |
215 | 211 | try: | ... | ... |