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() | ... | ... |