Commit c020e9044bc39e052bad3910a09fd2ad783ec787
1 parent
f3bf4279
Exists in
master
and in
68 other branches
ENH: Import modularization and implementation, working both command line and int…
…erface (still working on slices preview)
Showing
7 changed files
with
268 additions
and
104 deletions
Show diff stats
invesalius/control.py
... | ... | @@ -9,6 +9,7 @@ import project as prj |
9 | 9 | import data.imagedata_utils as utils |
10 | 10 | import data.surface as surface |
11 | 11 | import data.volume as volume |
12 | +import reader.dicom_grouper | |
12 | 13 | import gui.dialogs as dialog |
13 | 14 | import reader.dicom_reader as dcm |
14 | 15 | import reader.analyze_reader as analyze |
... | ... | @@ -23,23 +24,125 @@ class Controller(): |
23 | 24 | self.__bind_events() |
24 | 25 | |
25 | 26 | def __bind_events(self): |
26 | - ps.Publisher().subscribe(self.ImportDirectory, 'Import directory') | |
27 | + ps.Publisher().subscribe(self.OnImportMedicalImages, 'Import directory') | |
27 | 28 | ps.Publisher().subscribe(self.StartImportPanel, "Load data to import panel") |
28 | 29 | ps.Publisher().subscribe(self.LoadRaycastingPreset, |
29 | 30 | 'Load raycasting preset') |
30 | 31 | ps.Publisher().subscribe(self.SaveRaycastingPreset, |
31 | 32 | 'Save raycasting preset') |
33 | + ps.Publisher().subscribe(self.OnOpenDicomGroup, | |
34 | + 'Open DICOM group') | |
32 | 35 | |
33 | 36 | def StartImportPanel(self, pubsub_evt): |
34 | 37 | # path to directory |
35 | 38 | path = pubsub_evt.data |
36 | 39 | |
37 | 40 | # retrieve DICOM files splited into groups |
38 | - dicom_series = dcm.GetDicomGroups(path) | |
39 | - ps.Publisher().sendMessage("Load import panel", dicom_series) | |
41 | + patient_series = dcm.GetDicomGroups(path) | |
42 | + ps.Publisher().sendMessage("Load import panel", patient_series) | |
43 | + first_patient = patient_series[0] | |
44 | + #ps.Publisher().sendMessage("Load dicom preview", first_patient) | |
45 | + | |
46 | + def OnImportMedicalImages(self, pubsub_evt): | |
47 | + directory = pubsub_evt.data | |
48 | + self.ImportMedicalImages(directory) | |
49 | + | |
50 | + def ImportMedicalImages(self, directory): | |
51 | + # OPTION 1: DICOM? | |
52 | + patients_groups = dcm.GetDicomGroups(directory) | |
53 | + if len(patients_groups): | |
54 | + group = dcm.SelectLargerDicomGroup(patients_groups) | |
55 | + imagedata, dicom = self.OpenDicomGroup(group, gui=False) | |
56 | + self.CreateDicomProject(imagedata, dicom) | |
57 | + # OPTION 2: ANALYZE? | |
58 | + else: | |
59 | + imagedata = analyze.ReadDirectory(directory) | |
60 | + if imagedata: | |
61 | + self.CreateAnalyzeProject(imagedata) | |
62 | + # OPTION 3: Nothing... | |
63 | + else: | |
64 | + print "No medical images found on given directory" | |
65 | + return | |
66 | + self.LoadProject() | |
67 | + | |
68 | + def LoadProject(self): | |
69 | + proj = prj.Project() | |
70 | + ps.Publisher().sendMessage('Set project name', proj.name) | |
71 | + ps.Publisher().sendMessage('Load slice to viewer', (proj.imagedata)) | |
72 | + self.LoadImagedataInfo() # TODO: where do we insert this <<<? | |
73 | + ps.Publisher().sendMessage('Bright and contrast adjustment image',\ | |
74 | + (proj.window, proj.level)) | |
75 | + ps.Publisher().sendMessage('Update window level value',\ | |
76 | + (proj.window, proj.level)) | |
77 | + ps.Publisher().sendMessage('Show content panel') | |
78 | + ps.Publisher().sendMessage('Update AUI') | |
79 | + | |
80 | + def CreateAnalyzeProject(self, imagedata): | |
81 | + proj = prj.Project() | |
82 | + proj.name = "Untitled" | |
83 | + proj.SetAcquisitionModality("MRI") | |
84 | + proj.imagedata = imagedata | |
85 | + #TODO: Verify if all Analyse are in AXIAL orientation | |
86 | + proj.original_orientation = const.AXIAL | |
87 | + proj.threshold_range = imagedata.GetScalarRange() | |
88 | + proj.window = proj.threshold_range[1] - proj.threshold_range[0] | |
89 | + proj.level (0.5 * (proj.threshold_range[1] + proj.threshold_range[0])) | |
90 | + | |
91 | + const.THRESHOLD_OUTVALUE = proj.threshold_range[0] | |
92 | + const.THRESHOLD_INVALUE = proj.threshold_range[1] | |
93 | + const.WINDOW_LEVEL['Default'] = (proj.window, proj.level) | |
94 | + const.WINDOW_LEVEL['Manual'] = (proj.window, proj.level) | |
40 | 95 | |
41 | - #ps.Publisher().sendMessage("Load dicom preview", series_preview) | |
42 | 96 | |
97 | + def CreateDicomProject(self, imagedata, dicom): | |
98 | + name_to_const = {"AXIAL":const.AXIAL, | |
99 | + "CORONAL":const.CORONAL, | |
100 | + "SAGITTAL":const.SAGITAL} | |
101 | + | |
102 | + proj = prj.Project() | |
103 | + proj.name = dicom.patient.name | |
104 | + proj.SetAcquisitionModality(dicom.acquisition.modality) | |
105 | + proj.imagedata = imagedata | |
106 | + proj.original_orientation =\ | |
107 | + name_to_const[dicom.image.orientation_label] | |
108 | + proj.window = float(dicom.image.window) | |
109 | + proj.level = float(dicom.image.level) | |
110 | + proj.threshold_range = imagedata.GetScalarRange() | |
111 | + | |
112 | + const.THRESHOLD_OUTVALUE = proj.threshold_range[0] | |
113 | + const.THRESHOLD_INVALUE = proj.threshold_range[1] | |
114 | + const.WINDOW_LEVEL['Default'] = (proj.window, proj.level) | |
115 | + const.WINDOW_LEVEL['Manual'] = (proj.window, proj.level) | |
116 | + | |
117 | + def OnOpenDicomGroup(self, pubsub_evt): | |
118 | + group = pubsub_evt.data | |
119 | + imagedata, dicom = self.OpenDicomGroup(group, gui=False) | |
120 | + self.CreateDicomProject(imagedata, dicom) | |
121 | + self.LoadProject() | |
122 | + | |
123 | + def OpenDicomGroup(self, dicom_group, gui=True): | |
124 | + | |
125 | + # Retrieve general DICOM headers | |
126 | + dicom = dicom_group.GetDicomSample() | |
127 | + | |
128 | + # Create imagedata | |
129 | + filelist = dicom_group.GetFilenameList() | |
130 | + zspacing = dicom_group.zspacing | |
131 | + imagedata = utils.CreateImageData(filelist, zspacing) | |
132 | + | |
133 | + # 1(a): Fix gantry tilt, if any | |
134 | + tilt_value = dicom.acquisition.tilt | |
135 | + if (tilt_value) and (gui): | |
136 | + # Tell user gantry tilt and fix, according to answer | |
137 | + message = "Fix gantry tilt applying the degrees bellow" | |
138 | + value = -1*tilt_value | |
139 | + tilt_value = dialog.ShowNumberDialog(message, value) | |
140 | + imagedata = utils.FixGantryTilt(imagedata, tilt_value) | |
141 | + elif (tilt_value) and not (gui): | |
142 | + tilt_value = -1*tilt_value | |
143 | + imagedata = utils.FixGantryTilt(imagedata, tilt_value) | |
144 | + | |
145 | + return imagedata, dicom | |
43 | 146 | |
44 | 147 | def ImportDirectory(self, pubsub_evt=None, dir_=None): |
45 | 148 | """ |
... | ... | @@ -84,19 +187,20 @@ class Controller(): |
84 | 187 | else: |
85 | 188 | "No DICOM files were found. Trying to read with ITK..." |
86 | 189 | imagedata = analyze.ReadDirectory(dir_) |
87 | - acquisition_modality = "MRI" | |
190 | + if imagedata: | |
191 | + acquisition_modality = "MRI" | |
88 | 192 | |
89 | - #TODO: Verify if all Analyse is AXIAL orientation | |
90 | - orientation = const.AXIAL | |
193 | + #TODO: Verify if all Analyse is AXIAL orientation | |
194 | + orientation = const.AXIAL | |
91 | 195 | |
92 | - proj.SetAcquisitionModality(acquisition_modality) | |
93 | - proj.imagedata = imagedata | |
94 | - proj.original_orientation = orientation | |
95 | - threshold_range = proj.imagedata.GetScalarRange() | |
96 | - proj.window = window = threshold_range[1] - threshold_range[0] | |
97 | - proj.level = level = (0.5 * (threshold_range[1] + threshold_range[0])) | |
196 | + proj.SetAcquisitionModality(acquisition_modality) | |
197 | + proj.imagedata = imagedata | |
198 | + proj.original_orientation = orientation | |
199 | + threshold_range = proj.imagedata.GetScalarRange() | |
200 | + proj.window = window = threshold_range[1] - threshold_range[0] | |
201 | + proj.level = level = (0.5 * (threshold_range[1] + threshold_range[0])) | |
98 | 202 | |
99 | - ps.Publisher().sendMessage('Update window level value',\ | |
203 | + ps.Publisher().sendMessage('Update window level value',\ | |
100 | 204 | (proj.window, proj.level)) |
101 | 205 | |
102 | 206 | if not imagedata: | ... | ... |
invesalius/data/imagedata_utils.py
1 | 1 | import math |
2 | 2 | import vtk |
3 | +import vtkgdcm | |
4 | + | |
5 | +import constants as const | |
3 | 6 | |
4 | 7 | # TODO: Test cases which are originally in sagittal/coronal orientation |
5 | 8 | # and have gantry |
... | ... | @@ -162,3 +165,52 @@ def ExtractVOI(imagedata,xi,xf,yi,yf,zi,zf): |
162 | 165 | voi.SetSampleRate(1, 1, 1) |
163 | 166 | voi.Update() |
164 | 167 | return voi.GetOutput() |
168 | + | |
169 | +def CreateImageData(filelist, zspacing): | |
170 | + | |
171 | + if not(const.REDUCE_IMAGEDATA_QUALITY): | |
172 | + array = vtk.vtkStringArray() | |
173 | + for x in xrange(len(filelist)): | |
174 | + array.InsertValue(x,filelist[x]) | |
175 | + | |
176 | + reader = vtkgdcm.vtkGDCMImageReader() | |
177 | + reader.SetFileNames(array) | |
178 | + reader.Update() | |
179 | + | |
180 | + # The zpacing is a DicomGroup property, so we need to set it | |
181 | + imagedata = vtk.vtkImageData() | |
182 | + imagedata.DeepCopy(reader.GetOutput()) | |
183 | + spacing = imagedata.GetSpacing() | |
184 | + imagedata.SetSpacing(spacing[0], spacing[1], zspacing) | |
185 | + else: | |
186 | + # Reformat each slice and future append them | |
187 | + appender = vtk.vtkImageAppend() | |
188 | + appender.SetAppendAxis(2) #Define Stack in Z | |
189 | + | |
190 | + # Reformat each slice | |
191 | + for x in xrange(len(filelist)): | |
192 | + # TODO: We need to check this automatically according | |
193 | + # to each computer's architecture | |
194 | + # If the resolution of the matrix is too large | |
195 | + reader = vtkgdcm.vtkGDCMImageReader() | |
196 | + reader.SetFileName(filelist[x]) | |
197 | + reader.Update() | |
198 | + | |
199 | + #Resample image in x,y dimension | |
200 | + slice_imagedata = ResampleImage2D(reader.GetOutput(), 256) | |
201 | + | |
202 | + #Stack images in Z axes | |
203 | + appender.AddInput(slice_imagedata) | |
204 | + appender.Update() | |
205 | + | |
206 | + # The zpacing is a DicomGroup property, so we need to set it | |
207 | + imagedata = vtk.vtkImageData() | |
208 | + imagedata.DeepCopy(appender.GetOutput()) | |
209 | + spacing = imagedata.GetSpacing() | |
210 | + | |
211 | + imagedata.SetSpacing(spacing[0], spacing[1], zspacing) | |
212 | + | |
213 | + imagedata.Update() | |
214 | + return imagedata | |
215 | + | |
216 | + | ... | ... |
invesalius/gui/dicom_preview_panel.py
... | ... | @@ -31,6 +31,27 @@ class SerieEvent(PreviewEvent): |
31 | 31 | def __init__(self , evtType, id): |
32 | 32 | super(SerieEvent, self).__init__(evtType, id) |
33 | 33 | |
34 | +class DicomImageData(object): | |
35 | + def __init__(self): | |
36 | + pass | |
37 | + | |
38 | + def SetInput(self, dicom): | |
39 | + reader = vtkgdcm.vtkGDCMImageReader() | |
40 | + reader.SetFileName(dicom.image.file) | |
41 | + imagedata = reader.GetOutput() | |
42 | + | |
43 | + scale = imagedata.GetScalarRange() | |
44 | + | |
45 | + cast = vtk.vtkImageMapToWindowLevelColors() | |
46 | + cast.SetInput(imagedata) | |
47 | + cast.SetWindow(float(dicom.image.window)) | |
48 | + cast.SetLevel(float(dicom.image.level)) | |
49 | + | |
50 | + self.imagedata = cast.GetOutput() | |
51 | + | |
52 | + def GetOutput(self): | |
53 | + return self.imagedata | |
54 | + | |
34 | 55 | |
35 | 56 | class DicomLoader(object): |
36 | 57 | """ |
... | ... | @@ -119,6 +140,15 @@ class Preview(wx.Panel): |
119 | 140 | def SetSubtitle(self, subtitle): |
120 | 141 | self.subtitle.SetLabel(subtitle) |
121 | 142 | |
143 | + def SetGroup(self, group): | |
144 | + self.SetTitle(group.title) | |
145 | + self.SetSubtitle("%d images"%(group.nslices)) | |
146 | + d = DicomImageData() | |
147 | + d.SetInput(group.dicom) | |
148 | + imagedata = d.GetOutput() | |
149 | + self.actor.SetInput(imagedata) | |
150 | + self.render.ResetCamera() | |
151 | + | |
122 | 152 | def SetImage(self, image_data): |
123 | 153 | """ |
124 | 154 | Set a Image to preview. |
... | ... | @@ -198,23 +228,23 @@ class DicomPreviewSeries(wx.Panel): |
198 | 228 | "%d Images" % len(self.series[i][0]), # Subtitle |
199 | 229 | i) for n, i in enumerate(self.series)] |
200 | 230 | |
201 | - def SetDicomSeries(self, files): | |
202 | - self.files = files | |
203 | - scroll_range = len(files)/5 | |
204 | - if scroll_range * 5 < len(files): | |
231 | + def SetDicomSeries(self, patient): | |
232 | + #self.files = files | |
233 | + ngroups = patient.ngroups | |
234 | + self.groups = patient.GetGroups() | |
235 | + | |
236 | + scroll_range = ngroups/5 | |
237 | + if scroll_range * 5 < ngroups: | |
205 | 238 | scroll_range +=1 |
206 | 239 | self.scroll.SetScrollbar(0, 3, scroll_range, 5) |
207 | 240 | self._display_previews() |
208 | 241 | |
209 | 242 | def _display_previews(self): |
210 | - initial = self.displayed_position * 5 | |
211 | - final = initial + 15 | |
212 | - for f, p in zip(self.files[initial:final], self.previews): | |
213 | - print "--------" | |
214 | - print "f:", f | |
215 | - print "p: ", p | |
216 | - p.SetImage(f) | |
217 | - p.Show() | |
243 | + begin = self.displayed_position * 5 | |
244 | + end = begin + 15 | |
245 | + for group, preview in zip(self.groups[begin:end], self.previews): | |
246 | + preview.SetGroup(group) | |
247 | + preview.Show() | |
218 | 248 | |
219 | 249 | def OnScroll(self, evt): |
220 | 250 | self.displayed_position = evt.GetPosition() | ... | ... |
invesalius/gui/frame.py
... | ... | @@ -80,6 +80,11 @@ class Frame(wx.Frame): |
80 | 80 | ps.Publisher().subscribe(self.UpdateAui, "Update AUI") |
81 | 81 | ps.Publisher().subscribe(self.ShowTask, 'Show task panel') |
82 | 82 | ps.Publisher().subscribe(self.HideTask, 'Hide task panel') |
83 | + ps.Publisher().subscribe(self.SetProjectName, 'Set project name') | |
84 | + | |
85 | + def SetProjectName(self, pubsub_evt): | |
86 | + proj_name = pubsub_evt.data | |
87 | + self.SetTitle("InVesalius 3 - %s"%(proj_name)) | |
83 | 88 | |
84 | 89 | def UpdateAui(self, pubsub_evt): |
85 | 90 | self.aui_manager.Update() |
... | ... | @@ -169,7 +174,9 @@ class Frame(wx.Frame): |
169 | 174 | |
170 | 175 | def ShowContentPanel(self, evt_pubsub): |
171 | 176 | aui_manager = self.aui_manager |
177 | + aui_manager.GetPane("Import").Show(0) | |
172 | 178 | aui_manager.GetPane("Data").Show(1) |
179 | + aui_manager.GetPane("Tasks").Show(1) | |
173 | 180 | aui_manager.Update() |
174 | 181 | |
175 | 182 | def OnSize(self, evt): | ... | ... |
invesalius/gui/import_panel.py
... | ... | @@ -130,21 +130,22 @@ class TextPanel(wx.Panel): |
130 | 130 | |
131 | 131 | tree.Expand(self.root) |
132 | 132 | |
133 | - tree.GetMainWindow().Bind(wx.EVT_RIGHT_UP, self.OnRightUp) | |
134 | 133 | tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivate) |
135 | 134 | |
136 | 135 | def OnActivate(self, evt): |
137 | 136 | print "OnActivate" |
138 | 137 | item = evt.GetItem() |
139 | - print self.tree.GetItemPyData(item) | |
140 | - | |
141 | - | |
142 | - def OnRightUp(self, evt): | |
143 | - pos = evt.GetPosition() | |
144 | - item, flags, col = self.tree.HitTest(pos) | |
145 | - if item: | |
146 | - print 'Flags: %s, Col:%s, Text: %s' %\ | |
147 | - (flags, col, self.tree.GetItemText(item, col)) | |
138 | + group = self.tree.GetItemPyData(item) | |
139 | + if group: | |
140 | + print "send" | |
141 | + ps.Publisher().sendMessage('Open DICOM group', | |
142 | + group) | |
143 | + | |
144 | + else: | |
145 | + if self.tree.IsExpanded(item): | |
146 | + self.tree.Collapse(item) | |
147 | + else: | |
148 | + self.tree.Expand(item) | |
148 | 149 | |
149 | 150 | def OnSize(self, evt): |
150 | 151 | self.tree.SetSize(self.GetSize()) | ... | ... |
invesalius/reader/dicom_grouper.py
... | ... | @@ -51,6 +51,8 @@ |
51 | 51 | # <dicom.image.number> and <dicom.acquisition.series_number> |
52 | 52 | # were swapped |
53 | 53 | |
54 | +import gdcm | |
55 | + | |
54 | 56 | ORIENT_MAP = {"SAGITTAL":0, "CORONAL":1, "AXIAL":2, "OBLIQUE":2} |
55 | 57 | |
56 | 58 | |
... | ... | @@ -96,7 +98,28 @@ class DicomGroup: |
96 | 98 | # (interpolated) |
97 | 99 | return self.slices_dict.values() |
98 | 100 | |
99 | - def GetSortedList(self): | |
101 | + def GetFilenameList(self): | |
102 | + # Should be called when user selects this group | |
103 | + # This list will be used to create the vtkImageData | |
104 | + # (interpolated) | |
105 | + | |
106 | + filelist = [dicom.image.file for dicom in | |
107 | + self.slices_dict.values()] | |
108 | + | |
109 | + # Sort slices using GDCM | |
110 | + if (self.dicom.image.orientation_label <> "CORONAL"): | |
111 | + #Organize reversed image | |
112 | + sorter = gdcm.IPPSorter() | |
113 | + sorter.SetComputeZSpacing(True) | |
114 | + sorter.SetZSpacingTolerance(1e-10) | |
115 | + sorter.Sort(filelist) | |
116 | + filelist = sorter.GetFilenames() | |
117 | + | |
118 | + #Getting organized image | |
119 | + return filelist | |
120 | + | |
121 | + | |
122 | + def GetHandSortedList(self): | |
100 | 123 | # This will be used to fix problem 1, after merging |
101 | 124 | # single DicomGroups of same study_id and orientation |
102 | 125 | list_ = self.slices_dict.values() |
... | ... | @@ -106,7 +129,7 @@ class DicomGroup: |
106 | 129 | return list_ |
107 | 130 | |
108 | 131 | def UpdateZSpacing(self): |
109 | - list_ = self.GetSortedList() | |
132 | + list_ = self.GetHandSortedList() | |
110 | 133 | |
111 | 134 | if (len(list_) > 1): |
112 | 135 | dicom = list_[0] |
... | ... | @@ -246,7 +269,7 @@ class PatientGroup: |
246 | 269 | group_counter = 0 |
247 | 270 | for group_key in dict_to_change: |
248 | 271 | # 2nd STEP: SORT |
249 | - sorted_list = dict_to_change[group_key].GetSortedList() | |
272 | + sorted_list = dict_to_change[group_key].GetHandSortedList() | |
250 | 273 | |
251 | 274 | # 3rd STEP: CHECK DIFFERENCES |
252 | 275 | axis = ORIENT_MAP[group_key[0]] # based on orientation | ... | ... |
invesalius/reader/dicom_reader.py
... | ... | @@ -28,32 +28,26 @@ import dicom |
28 | 28 | import dicom_grouper |
29 | 29 | import data.imagedata_utils as iu |
30 | 30 | |
31 | -def LoadImages(dir_): | |
31 | +def ReadDicomGroup(dir_): | |
32 | 32 | |
33 | 33 | patient_group = GetDicomGroups(dir_) |
34 | - filelist, dicom, zspacing = SelectLargerDicomGroup(patient_group) | |
35 | - filelist = SortFiles(filelist, dicom) | |
36 | - imagedata = CreateImageData(filelist, zspacing) | |
37 | - | |
38 | - return imagedata, dicom | |
34 | + if len(patient_group) > 0: | |
35 | + filelist, dicom, zspacing = SelectLargerDicomGroup(patient_group) | |
36 | + filelist = SortFiles(filelist, dicom) | |
37 | + imagedata = CreateImageData(filelist, zspacing) | |
38 | + return imagedata, dicom | |
39 | + else: | |
40 | + return False | |
39 | 41 | |
40 | 42 | |
41 | 43 | def SelectLargerDicomGroup(patient_group): |
42 | - nslices_old = 0 | |
44 | + maxslices = 0 | |
43 | 45 | for patient in patient_group: |
44 | 46 | group_list = patient.GetGroups() |
45 | 47 | for group in group_list: |
46 | - nslices = group.nslices | |
47 | - print "nslices:", nslices | |
48 | - if (nslices >= nslices_old): | |
49 | - dicoms = group.GetList() | |
50 | - zspacing = group.zspacing | |
51 | - nslices_old = nslices | |
52 | - | |
53 | - filelist = [] | |
54 | - for dicom in dicoms: | |
55 | - filelist.append(dicom.image.file) | |
56 | - return filelist, dicom, zspacing | |
48 | + if group.nslices > maxslices: | |
49 | + larger_group = group | |
50 | + return larger_group | |
57 | 51 | |
58 | 52 | def SortFiles(filelist, dicom): |
59 | 53 | # Sort slices |
... | ... | @@ -71,53 +65,6 @@ def SortFiles(filelist, dicom): |
71 | 65 | return filelist |
72 | 66 | |
73 | 67 | |
74 | -def CreateImageData(filelist, zspacing): | |
75 | - | |
76 | - if not(const.REDUCE_IMAGEDATA_QUALITY): | |
77 | - array = vtk.vtkStringArray() | |
78 | - for x in xrange(len(filelist)): | |
79 | - array.InsertValue(x,filelist[x]) | |
80 | - | |
81 | - reader = vtkgdcm.vtkGDCMImageReader() | |
82 | - reader.SetFileNames(array) | |
83 | - reader.Update() | |
84 | - | |
85 | - # The zpacing is a DicomGroup property, so we need to set it | |
86 | - imagedata = vtk.vtkImageData() | |
87 | - imagedata.DeepCopy(reader.GetOutput()) | |
88 | - spacing = imagedata.GetSpacing() | |
89 | - imagedata.SetSpacing(spacing[0], spacing[1], zspacing) | |
90 | - else: | |
91 | - # Reformat each slice and future append them | |
92 | - appender = vtk.vtkImageAppend() | |
93 | - appender.SetAppendAxis(2) #Define Stack in Z | |
94 | - | |
95 | - # Reformat each slice | |
96 | - for x in xrange(len(filelist)): | |
97 | - # TODO: We need to check this automatically according | |
98 | - # to each computer's architecture | |
99 | - # If the resolution of the matrix is too large | |
100 | - reader = vtkgdcm.vtkGDCMImageReader() | |
101 | - reader.SetFileName(filelist[x]) | |
102 | - reader.Update() | |
103 | - | |
104 | - #Resample image in x,y dimension | |
105 | - slice_imagedata = iu.ResampleImage2D(reader.GetOutput(), 256) | |
106 | - | |
107 | - #Stack images in Z axes | |
108 | - appender.AddInput(slice_imagedata) | |
109 | - appender.Update() | |
110 | - | |
111 | - # The zpacing is a DicomGroup property, so we need to set it | |
112 | - imagedata = vtk.vtkImageData() | |
113 | - imagedata.DeepCopy(appender.GetOutput()) | |
114 | - spacing = imagedata.GetSpacing() | |
115 | - | |
116 | - imagedata.SetSpacing(spacing[0], spacing[1], zspacing) | |
117 | - | |
118 | - imagedata.Update() | |
119 | - return imagedata | |
120 | - | |
121 | 68 | |
122 | 69 | def GetDicomGroups(directory, recursive=True): |
123 | 70 | """ | ... | ... |