Commit d4fcee3bc7ba924cd2335565bfd310b07ade0b0d
1 parent
2c2993a8
Exists in
master
and in
67 other branches
ENH: Optimized memory in DICOM importation window
Showing
3 changed files
with
57 additions
and
28 deletions
Show diff stats
invesalius/gui/dicom_preview_panel.py
| ... | ... | @@ -22,6 +22,7 @@ |
| 22 | 22 | |
| 23 | 23 | #TODO: To create a beautiful API |
| 24 | 24 | import time |
| 25 | +import tempfile | |
| 25 | 26 | |
| 26 | 27 | import wx |
| 27 | 28 | import vtk |
| ... | ... | @@ -34,6 +35,8 @@ from reader import dicom_reader |
| 34 | 35 | import data.vtk_utils as vtku |
| 35 | 36 | import utils |
| 36 | 37 | import vtkgdcm |
| 38 | + | |
| 39 | + | |
| 37 | 40 | NROWS = 3 |
| 38 | 41 | NCOLS = 6 |
| 39 | 42 | NUM_PREVIEWS = NCOLS*NROWS |
| ... | ... | @@ -102,31 +105,18 @@ class DicomInfo(object): |
| 102 | 105 | self.subtitle = subtitle |
| 103 | 106 | self._preview = None |
| 104 | 107 | self.selected = False |
| 108 | + self.filename = "" | |
| 105 | 109 | |
| 106 | 110 | @property |
| 107 | 111 | def preview(self): |
| 108 | - rdicom = vtkgdcm.vtkGDCMImageReader() | |
| 109 | - if self._preview: | |
| 110 | - return self._preview | |
| 111 | - else: | |
| 112 | - rdicom.SetFileName(self.dicom.image.file) | |
| 113 | - rdicom.Update() | |
| 114 | - | |
| 115 | - colorer = vtk.vtkImageMapToWindowLevelColors() | |
| 116 | - colorer.SetInput(rdicom.GetOutput()) | |
| 117 | - colorer.SetWindow(float(self.dicom.image.window)) | |
| 118 | - colorer.SetLevel(float(self.dicom.image.level)) | |
| 119 | - colorer.SetOutputFormatToRGB() | |
| 120 | - colorer.Update() | |
| 121 | - | |
| 122 | - width, height, z = colorer.GetOutput().GetDimensions() | |
| 123 | - | |
| 124 | - r = colorer.GetOutput().GetPointData().GetScalars() | |
| 125 | - ni = numpy_support.vtk_to_numpy(r) | |
| 126 | - self.img = wx.ImageFromBuffer(width, height, ni) | |
| 127 | - self._preview = self.img.Mirror(False) | |
| 128 | - return self._preview | |
| 129 | - | |
| 112 | + | |
| 113 | + if not self._preview: | |
| 114 | + bmp = wx.Bitmap(self.dicom.image.thumbnail_path, wx.BITMAP_TYPE_PNG) | |
| 115 | + self._preview = bmp.ConvertToImage() | |
| 116 | + return self._preview | |
| 117 | + | |
| 118 | + def release_thumbnail(self): | |
| 119 | + self._preview = None | |
| 130 | 120 | |
| 131 | 121 | class DicomPaintPanel(wx.Panel): |
| 132 | 122 | def __init__(self, parent): |
| ... | ... | @@ -238,6 +228,9 @@ class Preview(wx.Panel): |
| 238 | 228 | """ |
| 239 | 229 | Set a dicom to preview. |
| 240 | 230 | """ |
| 231 | + if self.dicom_info: | |
| 232 | + self.dicom_info.release_thumbnail() | |
| 233 | + | |
| 241 | 234 | self.dicom_info = dicom_info |
| 242 | 235 | self.SetTitle(dicom_info.title) |
| 243 | 236 | self.SetSubtitle(dicom_info.subtitle) |
| ... | ... | @@ -409,7 +402,6 @@ class DicomPreviewSeries(wx.Panel): |
| 409 | 402 | def _display_previews(self): |
| 410 | 403 | initial = self.displayed_position * NCOLS |
| 411 | 404 | final = initial + NUM_PREVIEWS |
| 412 | - | |
| 413 | 405 | if len(self.files) < final: |
| 414 | 406 | for i in xrange(final-len(self.files)): |
| 415 | 407 | try: |
| ... | ... | @@ -557,7 +549,6 @@ class DicomPreviewSlice(wx.Panel): |
| 557 | 549 | def _display_previews(self): |
| 558 | 550 | initial = self.displayed_position * NCOLS |
| 559 | 551 | final = initial + NUM_PREVIEWS |
| 560 | - | |
| 561 | 552 | if len(self.files) < final: |
| 562 | 553 | for i in xrange(final-len(self.files)): |
| 563 | 554 | try: | ... | ... |
invesalius/reader/dicom.py
| ... | ... | @@ -139,9 +139,10 @@ class Parser(): |
| 139 | 139 | # return None#self.vtkgdcm_reader.GetOutput() |
| 140 | 140 | |
| 141 | 141 | |
| 142 | - def SetDataImage(self, data_image, filename): | |
| 142 | + def SetDataImage(self, data_image, filename, thumbnail_path): | |
| 143 | 143 | self.data_image = data_image |
| 144 | 144 | self.filename = self.filepath = filename |
| 145 | + self.thumbnail_path = thumbnail_path | |
| 145 | 146 | |
| 146 | 147 | def __format_time(self,value): |
| 147 | 148 | sp1 = value.split(".") |
| ... | ... | @@ -1931,6 +1932,7 @@ class Image(object): |
| 1931 | 1932 | self.size = (parser.GetDimensionX(), parser.GetDimensionY()) |
| 1932 | 1933 | #self.imagedata = parser.GetImageData() |
| 1933 | 1934 | self.bits_allocad = parser._GetBitsAllocated() |
| 1935 | + self.thumbnail_path = parser.thumbnail_path | |
| 1934 | 1936 | |
| 1935 | 1937 | if (parser.GetImageThickness()): |
| 1936 | 1938 | try: | ... | ... |
invesalius/reader/dicom_reader.py
| ... | ... | @@ -19,10 +19,12 @@ |
| 19 | 19 | import os |
| 20 | 20 | import Queue |
| 21 | 21 | import threading |
| 22 | +import tempfile | |
| 22 | 23 | |
| 23 | 24 | from multiprocessing import cpu_count |
| 24 | 25 | |
| 25 | 26 | import vtk |
| 27 | +import vtkgdcm | |
| 26 | 28 | import gdcm |
| 27 | 29 | import wx.lib.pubsub as ps |
| 28 | 30 | |
| ... | ... | @@ -106,9 +108,8 @@ class LoadDicom(threading.Thread): |
| 106 | 108 | reader.SetFileName(str(filepath)) |
| 107 | 109 | |
| 108 | 110 | if (reader.Read()): |
| 109 | - | |
| 110 | 111 | file = reader.GetFile() |
| 111 | - | |
| 112 | + | |
| 112 | 113 | # Retrieve data set |
| 113 | 114 | dataSet = file.GetDataSet() |
| 114 | 115 | |
| ... | ... | @@ -173,6 +174,41 @@ class LoadDicom(threading.Thread): |
| 173 | 174 | data_dict[group][field] = "Invalid Character" |
| 174 | 175 | |
| 175 | 176 | |
| 177 | + | |
| 178 | + # -------------- To Create DICOM Thumbnail ----------- | |
| 179 | + rvtk = vtkgdcm.vtkGDCMImageReader() | |
| 180 | + rvtk.SetFileName(str(filepath)) | |
| 181 | + rvtk.Update() | |
| 182 | + | |
| 183 | + try: | |
| 184 | + data = data_dict['0028']['1050'] | |
| 185 | + level = [float(value) for value in data.split('\\')][0] | |
| 186 | + data = data_dict['0028']['1051'] | |
| 187 | + window = [float(value) for value in data.split('\\')][0] | |
| 188 | + except(KeyError): | |
| 189 | + level = 300.0 | |
| 190 | + window = 2000.0 | |
| 191 | + | |
| 192 | + colorer = vtk.vtkImageMapToWindowLevelColors() | |
| 193 | + colorer.SetInput(rvtk.GetOutput()) | |
| 194 | + colorer.SetWindow(float(window)) | |
| 195 | + colorer.SetLevel(float(level)) | |
| 196 | + colorer.SetOutputFormatToRGB() | |
| 197 | + colorer.Update() | |
| 198 | + | |
| 199 | + resample = vtk.vtkImageResample() | |
| 200 | + resample.SetInput(colorer.GetOutput()) | |
| 201 | + resample.SetAxisMagnificationFactor ( 0, 0.25 ) | |
| 202 | + resample.SetAxisMagnificationFactor ( 1, 0.25 ) | |
| 203 | + resample.SetAxisMagnificationFactor ( 2, 1 ) | |
| 204 | + resample.Update() | |
| 205 | + | |
| 206 | + thumbnail_path = tempfile.mktemp() | |
| 207 | + | |
| 208 | + write_png = vtk.vtkPNGWriter() | |
| 209 | + write_png.SetInput(resample.GetOutput()) | |
| 210 | + write_png.SetFileName(thumbnail_path) | |
| 211 | + write_png.Write() | |
| 176 | 212 | |
| 177 | 213 | # ---------- Refactory -------------------------------------- |
| 178 | 214 | data_dict['invesalius'] = {'orientation_label' : GetImageOrientationLabel(str(filepath))} |
| ... | ... | @@ -190,7 +226,7 @@ class LoadDicom(threading.Thread): |
| 190 | 226 | |
| 191 | 227 | if not(is_dicom_dir): |
| 192 | 228 | parser = dicom.Parser() |
| 193 | - parser.SetDataImage(dict_file[filepath], filepath) | |
| 229 | + parser.SetDataImage(dict_file[filepath], filepath, thumbnail_path) | |
| 194 | 230 | |
| 195 | 231 | dcm = dicom.Dicom() |
| 196 | 232 | self.l.acquire() | ... | ... |