Commit ee5249f94690f62a2941e77293820c7e2335111a
1 parent
430896dc
Exists in
master
and in
68 other branches
STYLE: moved the methode that generates the image previews from dicom.py to a ne…
…w class, DicomInfo.py
Showing
2 changed files
with
269 additions
and
327 deletions
Show diff stats
invesalius/gui/dicom_preview_panel.py
| @@ -21,23 +21,25 @@ | @@ -21,23 +21,25 @@ | ||
| 21 | # -*- coding: UTF-8 -*- | 21 | # -*- coding: UTF-8 -*- |
| 22 | 22 | ||
| 23 | #TODO: To create a beautiful API | 23 | #TODO: To create a beautiful API |
| 24 | +import time | ||
| 25 | + | ||
| 24 | import wx | 26 | import wx |
| 25 | -import wx.lib.agw.buttonpanel as bp | ||
| 26 | import vtk | 27 | import vtk |
| 27 | -from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor | ||
| 28 | -import vtkgdcm | ||
| 29 | 28 | ||
| 29 | +from vtk.util import numpy_support | ||
| 30 | +from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor | ||
| 30 | 31 | ||
| 31 | import constants as const | 32 | import constants as const |
| 32 | from reader import dicom_reader | 33 | from reader import dicom_reader |
| 33 | import data.vtk_utils as vtku | 34 | import data.vtk_utils as vtku |
| 34 | -import time | ||
| 35 | - | ||
| 36 | 35 | ||
| 37 | NROWS = 3 | 36 | NROWS = 3 |
| 38 | NCOLS = 6 | 37 | NCOLS = 6 |
| 39 | -MAX_VALUE = NCOLS*NROWS | 38 | +NUM_PREVIEWS = NCOLS*NROWS |
| 39 | +PREVIEW_WIDTH = 70 | ||
| 40 | +PREVIEW_HEIGTH = 70 | ||
| 40 | 41 | ||
| 42 | +PREVIEW_BACKGROUND = (255, 255, 255) # White | ||
| 41 | 43 | ||
| 42 | STR_SIZE = _("Image size: %d x %d") | 44 | STR_SIZE = _("Image size: %d x %d") |
| 43 | STR_SPC = _("Spacing: %.2f") | 45 | STR_SPC = _("Spacing: %.2f") |
| @@ -45,6 +47,247 @@ STR_LOCAL = _("Location: %.2f") | @@ -45,6 +47,247 @@ STR_LOCAL = _("Location: %.2f") | ||
| 45 | STR_PATIENT = "%s\n%s" | 47 | STR_PATIENT = "%s\n%s" |
| 46 | STR_ACQ = _("%s %s\nMade in InVesalius") | 48 | STR_ACQ = _("%s %s\nMade in InVesalius") |
| 47 | 49 | ||
| 50 | +class DicomInfo(object): | ||
| 51 | + """ | ||
| 52 | + Keep the informations and the image used by preview. | ||
| 53 | + """ | ||
| 54 | + def __init__(self, id, dicom, title, subtitle): | ||
| 55 | + self.id = id | ||
| 56 | + self.dicom = dicom | ||
| 57 | + self.title = title | ||
| 58 | + self.subtitle = subtitle | ||
| 59 | + self._preview = None | ||
| 60 | + | ||
| 61 | + @property | ||
| 62 | + def preview(self): | ||
| 63 | + if self._preview: | ||
| 64 | + return self._preview | ||
| 65 | + else: | ||
| 66 | + colorer = vtk.vtkImageMapToWindowLevelColors() | ||
| 67 | + colorer.SetInput(self.dicom.image.imagedata) | ||
| 68 | + colorer.SetWindow(float(self.dicom.image.window)) | ||
| 69 | + colorer.SetLevel(float(self.dicom.image.level)) | ||
| 70 | + colorer.SetOutputFormatToRGB() | ||
| 71 | + colorer.Update() | ||
| 72 | + | ||
| 73 | + width, height, z = colorer.GetOutput().GetDimensions() | ||
| 74 | + | ||
| 75 | + r = colorer.GetOutput().GetPointData().GetScalars() | ||
| 76 | + ni = numpy_support.vtk_to_numpy(r) | ||
| 77 | + img = wx.ImageFromBuffer(width, height, ni) | ||
| 78 | + img = img.Rescale(PREVIEW_WIDTH, PREVIEW_HEIGTH).Mirror(False) | ||
| 79 | + self._preview = wx.BitmapFromImage(img) | ||
| 80 | + return self._preview | ||
| 81 | + | ||
| 82 | + | ||
| 83 | +class Preview(wx.Panel): | ||
| 84 | + """ | ||
| 85 | + The little previews. | ||
| 86 | + """ | ||
| 87 | + def __init__(self, parent): | ||
| 88 | + super(Preview, self).__init__(parent, style= wx.BORDER) | ||
| 89 | + # Will it be white? | ||
| 90 | + self.select_on = False | ||
| 91 | + self._init_ui() | ||
| 92 | + self._bind_events() | ||
| 93 | + | ||
| 94 | + def _init_ui(self): | ||
| 95 | + self.title = wx.StaticText(self, -1, _("Image"), | ||
| 96 | + style=wx.ALIGN_CENTER) | ||
| 97 | + self.subtitle = wx.StaticText(self, -1, _("Image"), | ||
| 98 | + style=wx.ALIGN_CENTER) | ||
| 99 | + self.image_viewer = wx.StaticBitmap(self, -1, size=(70, 70)) | ||
| 100 | + | ||
| 101 | + #self.panel = wx.Panel(self, -1) | ||
| 102 | + | ||
| 103 | + self.SetBackgroundColour(PREVIEW_BACKGROUND) | ||
| 104 | + | ||
| 105 | + sizer_image = wx.BoxSizer(wx.HORIZONTAL) | ||
| 106 | + sizer_image.Add(self.image_viewer, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL) | ||
| 107 | + | ||
| 108 | + self.sizer = wx.BoxSizer(wx.VERTICAL) | ||
| 109 | + self.sizer.AddSpacer(2) | ||
| 110 | + self.sizer.Add(self.title, 0, | ||
| 111 | + wx.GROW|wx.EXPAND|wx. ALIGN_CENTER_HORIZONTAL) | ||
| 112 | + self.sizer.Add(self.subtitle, 0, | ||
| 113 | + wx.GROW|wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL) | ||
| 114 | + self.sizer.Add(sizer_image, 5, wx.GROW|wx.EXPAND|wx.ALL, 4) | ||
| 115 | + self.sizer.Fit(self) | ||
| 116 | + | ||
| 117 | + self.SetSizer(self.sizer) | ||
| 118 | + | ||
| 119 | + self.Layout() | ||
| 120 | + self.Update() | ||
| 121 | + self.Fit() | ||
| 122 | + self.SetAutoLayout(1) | ||
| 123 | + | ||
| 124 | + def _bind_events(self): | ||
| 125 | + self.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | ||
| 126 | + #self.interactor.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | ||
| 127 | + #self.panel.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | ||
| 128 | + #self.title.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | ||
| 129 | + #self.subtitle.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | ||
| 130 | + | ||
| 131 | + self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | ||
| 132 | + #self.interactor.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | ||
| 133 | + #self.panel.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | ||
| 134 | + #self.title.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | ||
| 135 | + #self.subtitle.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | ||
| 136 | + | ||
| 137 | + self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | ||
| 138 | + #self.interactor.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | ||
| 139 | + #self.panel.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | ||
| 140 | + #self.title.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | ||
| 141 | + #self.subtitle.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | ||
| 142 | + | ||
| 143 | + self.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | ||
| 144 | + #self.interactor.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | ||
| 145 | + #self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | ||
| 146 | + #self.title.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | ||
| 147 | + #self.subtitle.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | ||
| 148 | + | ||
| 149 | + def SetDicomToPreview(self, dicom_info): | ||
| 150 | + """ | ||
| 151 | + Set a dicom to preview. | ||
| 152 | + """ | ||
| 153 | + self.SetTitle(dicom_info.title) | ||
| 154 | + self.SetSubtitle(dicom_info.subtitle) | ||
| 155 | + self.ID = dicom_info.id | ||
| 156 | + image = dicom_info.preview | ||
| 157 | + self.image_viewer.SetBitmap(image) | ||
| 158 | + self.data = dicom_info.id | ||
| 159 | + self.Update() | ||
| 160 | + | ||
| 161 | + def SetTitle(self, title): | ||
| 162 | + self.title.SetLabel(title) | ||
| 163 | + | ||
| 164 | + def SetSubtitle(self, subtitle): | ||
| 165 | + self.subtitle.SetLabel(subtitle) | ||
| 166 | + | ||
| 167 | + def OnEnter(self, evt): | ||
| 168 | + if not self.select_on: | ||
| 169 | + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHILIGHT) | ||
| 170 | + c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) | ||
| 171 | + self.SetBackgroundColour(c) | ||
| 172 | + | ||
| 173 | + def OnLeave(self, evt): | ||
| 174 | + if not self.select_on: | ||
| 175 | + c = (255,255,255) | ||
| 176 | + self.SetBackgroundColour(c) | ||
| 177 | + | ||
| 178 | + def OnSelect(self, evt): | ||
| 179 | + print "OnSelect" | ||
| 180 | + self.select_on = True | ||
| 181 | + ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNHIGHLIGHT) | ||
| 182 | + ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HOTLIGHT) | ||
| 183 | + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) | ||
| 184 | + ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRADIENTACTIVECAPTION) | ||
| 185 | + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW) | ||
| 186 | + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_ACTIVEBORDER) | ||
| 187 | + #*c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DLIGHT) | ||
| 188 | + #*c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHILIGHT) | ||
| 189 | + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHIGHLIGHT) | ||
| 190 | + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DDKSHADOW) | ||
| 191 | + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW) | ||
| 192 | + #self.SetBackgroundColour(c) | ||
| 193 | + self.Select() | ||
| 194 | + | ||
| 195 | + def Select(self, on=True): | ||
| 196 | + if self.select_on: | ||
| 197 | + c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) | ||
| 198 | + else: | ||
| 199 | + c = (255,255,255) | ||
| 200 | + self.SetBackgroundColour(c) | ||
| 201 | + self.Refresh() | ||
| 202 | + | ||
| 203 | + def OnDClick(self, evt): | ||
| 204 | + evt = PreviewEvent(myEVT_SELECT, self.GetId()) | ||
| 205 | + evt.SetSelectedID(self.ID) | ||
| 206 | + evt.SetItemData(self.data) | ||
| 207 | + self.GetEventHandler().ProcessEvent(evt) | ||
| 208 | + | ||
| 209 | + def ShowShadow(self): | ||
| 210 | + self._nImgSize = 16 | ||
| 211 | + nPadding = 4 | ||
| 212 | + print "ShowShadow" | ||
| 213 | + dc = wx.BufferedPaintDC(self) | ||
| 214 | + style = self.GetParent().GetWindowStyleFlag() | ||
| 215 | + | ||
| 216 | + backBrush = wx.WHITE_BRUSH | ||
| 217 | + if 1: #style & INB_BORDER: | ||
| 218 | + borderPen = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW)) | ||
| 219 | + #else: | ||
| 220 | + # borderPen = wx.TRANSPARENT_PEN | ||
| 221 | + | ||
| 222 | + size = self.GetSize() | ||
| 223 | + | ||
| 224 | + # Background | ||
| 225 | + dc.SetBrush(backBrush) | ||
| 226 | + | ||
| 227 | + borderPen.SetWidth(1) | ||
| 228 | + dc.SetPen(borderPen) | ||
| 229 | + dc.DrawRectangle(0, 0, size.x, size.y) | ||
| 230 | + #bUsePin = (style & INB_USE_PIN_BUTTON and [True] or [False])[0] | ||
| 231 | + | ||
| 232 | + borderPen = wx.BLACK_PEN | ||
| 233 | + borderPen.SetWidth(1) | ||
| 234 | + dc.SetPen(borderPen) | ||
| 235 | + dc.DrawLine(0, size.y, size.x, size.y) | ||
| 236 | + dc.DrawPoint(0, size.y) | ||
| 237 | + | ||
| 238 | + clientSize = 0 | ||
| 239 | + #bUseYcoord = (style & INB_RIGHT or style & INB_LEFT) | ||
| 240 | + bUseYcoord = 1 | ||
| 241 | + | ||
| 242 | + if bUseYcoord: | ||
| 243 | + clientSize = size.GetHeight() | ||
| 244 | + else: | ||
| 245 | + clientSize = size.GetWidth() | ||
| 246 | + | ||
| 247 | + if 1: | ||
| 248 | + # Default values for the surronounding rectangle | ||
| 249 | + # around a button | ||
| 250 | + rectWidth = self._nImgSize * 2 # To avoid the recangle to 'touch' the borders | ||
| 251 | + rectHeight = self._nImgSize * 2 | ||
| 252 | + | ||
| 253 | + # Incase the style requires non-fixed button (fit to text) | ||
| 254 | + # recalc the rectangle width | ||
| 255 | + if 1: | ||
| 256 | + #if style & INB_FIT_BUTTON and \ | ||
| 257 | + # not ((style & INB_LEFT) or (style & INB_RIGHT)) and \ | ||
| 258 | + # not self._pagesInfoVec[i].GetCaption() == "" and \ | ||
| 259 | + # not (style & INB_SHOW_ONLY_IMAGES): | ||
| 260 | + | ||
| 261 | + | ||
| 262 | + #rectWidth = ((textWidth + nPadding * 2) > rectWidth and [nPadding * 2 + textWidth] or [rectWidth])[0] | ||
| 263 | + | ||
| 264 | + rectWidth = ((nPadding * 2) > rectWidth and [nPadding * 2] or [rectWidth])[0] | ||
| 265 | + # Make the width an even number | ||
| 266 | + if rectWidth % 2 != 0: | ||
| 267 | + rectWidth += 1 | ||
| 268 | + | ||
| 269 | + # If Pin button is used, consider its space as well (applicable for top/botton style) | ||
| 270 | + # since in the left/right, its size is already considered in 'pos' | ||
| 271 | + #pinBtnSize = (bUsePin and [20] or [0])[0] | ||
| 272 | + | ||
| 273 | + #if pos + rectWidth + pinBtnSize > clientSize: | ||
| 274 | + # break | ||
| 275 | + | ||
| 276 | + # Calculate the button rectangle | ||
| 277 | + modRectWidth = rectWidth - 2# or [rectWidth])[0] | ||
| 278 | + modRectHeight = rectHeight# or [rectHeight - 2])[0] | ||
| 279 | + | ||
| 280 | + pos = rectWidth | ||
| 281 | + | ||
| 282 | + if bUseYcoord: | ||
| 283 | + buttonRect = wx.Rect(1, pos, modRectWidth, modRectHeight) | ||
| 284 | + else: | ||
| 285 | + buttonRect = wx.Rect(pos , 1, modRectWidth, modRectHeight) | ||
| 286 | + | ||
| 287 | + def ShowShadow2(self): | ||
| 288 | + pass | ||
| 289 | + | ||
| 290 | + | ||
| 48 | class SingleImagePreview(wx.Panel): | 291 | class SingleImagePreview(wx.Panel): |
| 49 | def __init__(self, parent): | 292 | def __init__(self, parent): |
| 50 | wx.Panel.__init__(self, parent, -1) | 293 | wx.Panel.__init__(self, parent, -1) |
| @@ -265,278 +508,6 @@ class SerieEvent(PreviewEvent): | @@ -265,278 +508,6 @@ class SerieEvent(PreviewEvent): | ||
| 265 | def __init__(self , evtType, id): | 508 | def __init__(self , evtType, id): |
| 266 | super(SerieEvent, self).__init__(evtType, id) | 509 | super(SerieEvent, self).__init__(evtType, id) |
| 267 | 510 | ||
| 268 | -class Preview(wx.Panel): | ||
| 269 | - """ | ||
| 270 | - Where the images will be showed. | ||
| 271 | - """ | ||
| 272 | - def __init__(self, parent): | ||
| 273 | - super(Preview, self).__init__(parent) | ||
| 274 | - # Will it be white? | ||
| 275 | - self.select_on = False | ||
| 276 | - self._init_ui() | ||
| 277 | - #self._init_vtk() | ||
| 278 | - #self._bind_events() | ||
| 279 | - | ||
| 280 | - def _init_ui(self): | ||
| 281 | - | ||
| 282 | - self.title = wx.StaticText(self, -1, _("Image"), | ||
| 283 | - style=wx.ALIGN_CENTER) | ||
| 284 | - | ||
| 285 | - self.subtitle = wx.StaticText(self, -1, _("Image"), | ||
| 286 | - style=wx.ALIGN_CENTER) | ||
| 287 | - | ||
| 288 | - self.image_viewer = wx.StaticBitmap(self, -1) | ||
| 289 | - | ||
| 290 | - #self.panel = wx.Panel(self, -1) | ||
| 291 | - | ||
| 292 | - self.SetBackgroundColour((255,255,255)) | ||
| 293 | - | ||
| 294 | - self.sizer = wx.BoxSizer(wx.VERTICAL) | ||
| 295 | - self.sizer.AddSpacer(2) | ||
| 296 | - self.sizer.Add(self.title, 1, | ||
| 297 | - wx.GROW|wx.EXPAND|wx. ALIGN_CENTER_HORIZONTAL) | ||
| 298 | - self.sizer.Add(self.subtitle, 1, | ||
| 299 | - wx.GROW|wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL) | ||
| 300 | - self.sizer.Add(self.image_viewer, 5, wx.GROW|wx.EXPAND|wx.ALL, 4) | ||
| 301 | - self.sizer.Fit(self) | ||
| 302 | - | ||
| 303 | - | ||
| 304 | - self.SetSizer(self.sizer) | ||
| 305 | - | ||
| 306 | - | ||
| 307 | - self.Layout() | ||
| 308 | - self.Update() | ||
| 309 | - self.Fit() | ||
| 310 | - self.SetAutoLayout(1) | ||
| 311 | - | ||
| 312 | - | ||
| 313 | - def _init_vtk(self): | ||
| 314 | - | ||
| 315 | - self.interactor = wxVTKRenderWindowInteractor(self.panel, -1, size=(70, 70)) | ||
| 316 | - | ||
| 317 | - sizer = wx.BoxSizer(wx.HORIZONTAL) | ||
| 318 | - sizer.Add(self.interactor, 1, wx.GROW|wx.EXPAND) | ||
| 319 | - sizer.Fit(self.panel) | ||
| 320 | - | ||
| 321 | - self.panel.SetSizer(sizer) | ||
| 322 | - | ||
| 323 | - self.panel.Layout() | ||
| 324 | - self.panel.Update() | ||
| 325 | - self.panel.SetAutoLayout(1) | ||
| 326 | - | ||
| 327 | - self.actor = vtk.vtkImageActor() | ||
| 328 | - | ||
| 329 | - self.render = vtk.vtkRenderer() | ||
| 330 | - self.render.AddActor(self.actor) | ||
| 331 | - | ||
| 332 | - self.interactor.SetInteractorStyle(None) | ||
| 333 | - self.interactor.GetRenderWindow().AddRenderer(self.render) | ||
| 334 | - | ||
| 335 | - | ||
| 336 | - def _bind_events(self): | ||
| 337 | - self.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | ||
| 338 | - self.interactor.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | ||
| 339 | - self.panel.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | ||
| 340 | - self.title.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | ||
| 341 | - self.subtitle.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) | ||
| 342 | - | ||
| 343 | - self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | ||
| 344 | - self.interactor.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | ||
| 345 | - self.panel.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | ||
| 346 | - self.title.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | ||
| 347 | - self.subtitle.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) | ||
| 348 | - | ||
| 349 | - self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | ||
| 350 | - self.interactor.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | ||
| 351 | - self.panel.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | ||
| 352 | - self.title.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | ||
| 353 | - self.subtitle.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) | ||
| 354 | - | ||
| 355 | - self.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | ||
| 356 | - self.interactor.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | ||
| 357 | - self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | ||
| 358 | - self.title.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | ||
| 359 | - self.subtitle.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) | ||
| 360 | - | ||
| 361 | - | ||
| 362 | - | ||
| 363 | - | ||
| 364 | - def OnEnter(self, evt): | ||
| 365 | - if not self.select_on: | ||
| 366 | - #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHILIGHT) | ||
| 367 | - c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) | ||
| 368 | - self.SetBackgroundColour(c) | ||
| 369 | - | ||
| 370 | - | ||
| 371 | - def OnLeave(self, evt): | ||
| 372 | - if not self.select_on: | ||
| 373 | - c = (255,255,255) | ||
| 374 | - self.SetBackgroundColour(c) | ||
| 375 | - | ||
| 376 | - def OnSelect(self, evt): | ||
| 377 | - self.select_on = True | ||
| 378 | - ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNHIGHLIGHT) | ||
| 379 | - ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HOTLIGHT) | ||
| 380 | - #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) | ||
| 381 | - ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRADIENTACTIVECAPTION) | ||
| 382 | - #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW) | ||
| 383 | - #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_ACTIVEBORDER) | ||
| 384 | - #*c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DLIGHT) | ||
| 385 | - #*c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHILIGHT) | ||
| 386 | - #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHIGHLIGHT) | ||
| 387 | - #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DDKSHADOW) | ||
| 388 | - #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW) | ||
| 389 | - #self.SetBackgroundColour(c) | ||
| 390 | - self.Select() | ||
| 391 | - | ||
| 392 | - def Select(self, on=True): | ||
| 393 | - self.select_on = on | ||
| 394 | - if on: | ||
| 395 | - c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHIGHLIGHT) | ||
| 396 | - else: | ||
| 397 | - c = (255,255,255) | ||
| 398 | - self.SetBackgroundColour(c) | ||
| 399 | - | ||
| 400 | - | ||
| 401 | - def OnDClick(self, evt): | ||
| 402 | - evt = PreviewEvent(myEVT_SELECT, self.GetId()) | ||
| 403 | - evt.SetSelectedID(self.ID) | ||
| 404 | - evt.SetItemData(self.data) | ||
| 405 | - self.GetEventHandler().ProcessEvent(evt) | ||
| 406 | - | ||
| 407 | - def SetTitle(self, title): | ||
| 408 | - self.title.SetLabel(title) | ||
| 409 | - | ||
| 410 | - def SetSubtitle(self, subtitle): | ||
| 411 | - self.subtitle.SetLabel(subtitle) | ||
| 412 | - | ||
| 413 | - def SetDicomToPreview(self, image_file): | ||
| 414 | - """ | ||
| 415 | - Set a Image to preview. | ||
| 416 | - """ | ||
| 417 | - self.SetTitle(image_file[3]) | ||
| 418 | - self.SetSubtitle(image_file[4]) | ||
| 419 | - | ||
| 420 | - self.Layout() | ||
| 421 | - self.Update() | ||
| 422 | - | ||
| 423 | - self.ID = image_file[5] | ||
| 424 | - | ||
| 425 | - #image_reader = vtkgdcm.vtkGDCMImageReader() | ||
| 426 | - #image_reader.SetFileName(image_file[0]) | ||
| 427 | - #image = image_reader.GetOutput() | ||
| 428 | - | ||
| 429 | - image = image_file[-1].image.jpeg_file | ||
| 430 | - #img = wx.Image(image, wx.BITMAP_TYPE_JPEG) | ||
| 431 | - #img.Rescale(70, 70) | ||
| 432 | - #bmp = wx.BitmapFromImage(img) | ||
| 433 | - self.image_viewer.SetBitmap(image) | ||
| 434 | - | ||
| 435 | - #scale = image.GetScalarRange() | ||
| 436 | - | ||
| 437 | - #cast = vtk.vtkImageMapToWindowLevelColors() | ||
| 438 | - ##cast.SetShift(abs(scale[0])) | ||
| 439 | - ##cast.SetScale(255.0/(scale[1] - scale[0])) | ||
| 440 | - ##cast.ClampOverflowOn() | ||
| 441 | - #cast.SetInput(image) | ||
| 442 | - ##cast.SetOutputScalarTypeToUnsignedChar() | ||
| 443 | - #try: | ||
| 444 | - # window = float(image_file[1]) | ||
| 445 | - # level = float(image_file[2]) | ||
| 446 | - #except TypeError: | ||
| 447 | - # #TODO: These values are good? | ||
| 448 | - # level = 230 | ||
| 449 | - # window = 150 | ||
| 450 | - | ||
| 451 | - #self.data = image_file[-1] | ||
| 452 | - | ||
| 453 | - #cast.SetWindow(window) | ||
| 454 | - #cast.SetLevel(level) | ||
| 455 | - #self.actor.SetInput(cast.GetOutput()) | ||
| 456 | - #self.render.ResetCamera() | ||
| 457 | - #self.interactor.Render() | ||
| 458 | - | ||
| 459 | - def ShowShadow(self): | ||
| 460 | - self._nImgSize = 16 | ||
| 461 | - nPadding = 4 | ||
| 462 | - print "ShowShadow" | ||
| 463 | - dc = wx.BufferedPaintDC(self) | ||
| 464 | - style = self.GetParent().GetWindowStyleFlag() | ||
| 465 | - | ||
| 466 | - backBrush = wx.WHITE_BRUSH | ||
| 467 | - if 1: #style & INB_BORDER: | ||
| 468 | - borderPen = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW)) | ||
| 469 | - #else: | ||
| 470 | - # borderPen = wx.TRANSPARENT_PEN | ||
| 471 | - | ||
| 472 | - size = self.GetSize() | ||
| 473 | - | ||
| 474 | - # Background | ||
| 475 | - dc.SetBrush(backBrush) | ||
| 476 | - | ||
| 477 | - borderPen.SetWidth(1) | ||
| 478 | - dc.SetPen(borderPen) | ||
| 479 | - dc.DrawRectangle(0, 0, size.x, size.y) | ||
| 480 | - #bUsePin = (style & INB_USE_PIN_BUTTON and [True] or [False])[0] | ||
| 481 | - | ||
| 482 | - borderPen = wx.BLACK_PEN | ||
| 483 | - borderPen.SetWidth(1) | ||
| 484 | - dc.SetPen(borderPen) | ||
| 485 | - dc.DrawLine(0, size.y, size.x, size.y) | ||
| 486 | - dc.DrawPoint(0, size.y) | ||
| 487 | - | ||
| 488 | - clientSize = 0 | ||
| 489 | - #bUseYcoord = (style & INB_RIGHT or style & INB_LEFT) | ||
| 490 | - bUseYcoord = 1 | ||
| 491 | - | ||
| 492 | - if bUseYcoord: | ||
| 493 | - clientSize = size.GetHeight() | ||
| 494 | - else: | ||
| 495 | - clientSize = size.GetWidth() | ||
| 496 | - | ||
| 497 | - | ||
| 498 | - if 1: | ||
| 499 | - # Default values for the surronounding rectangle | ||
| 500 | - # around a button | ||
| 501 | - rectWidth = self._nImgSize * 2 # To avoid the recangle to 'touch' the borders | ||
| 502 | - rectHeight = self._nImgSize * 2 | ||
| 503 | - | ||
| 504 | - # Incase the style requires non-fixed button (fit to text) | ||
| 505 | - # recalc the rectangle width | ||
| 506 | - if 1: | ||
| 507 | - #if style & INB_FIT_BUTTON and \ | ||
| 508 | - # not ((style & INB_LEFT) or (style & INB_RIGHT)) and \ | ||
| 509 | - # not self._pagesInfoVec[i].GetCaption() == "" and \ | ||
| 510 | - # not (style & INB_SHOW_ONLY_IMAGES): | ||
| 511 | - | ||
| 512 | - | ||
| 513 | - #rectWidth = ((textWidth + nPadding * 2) > rectWidth and [nPadding * 2 + textWidth] or [rectWidth])[0] | ||
| 514 | - | ||
| 515 | - rectWidth = ((nPadding * 2) > rectWidth and [nPadding * 2] or [rectWidth])[0] | ||
| 516 | - # Make the width an even number | ||
| 517 | - if rectWidth % 2 != 0: | ||
| 518 | - rectWidth += 1 | ||
| 519 | - | ||
| 520 | - # If Pin button is used, consider its space as well (applicable for top/botton style) | ||
| 521 | - # since in the left/right, its size is already considered in 'pos' | ||
| 522 | - #pinBtnSize = (bUsePin and [20] or [0])[0] | ||
| 523 | - | ||
| 524 | - #if pos + rectWidth + pinBtnSize > clientSize: | ||
| 525 | - # break | ||
| 526 | - | ||
| 527 | - # Calculate the button rectangle | ||
| 528 | - modRectWidth = rectWidth - 2# or [rectWidth])[0] | ||
| 529 | - modRectHeight = rectHeight# or [rectHeight - 2])[0] | ||
| 530 | - | ||
| 531 | - pos = rectWidth | ||
| 532 | - | ||
| 533 | - if bUseYcoord: | ||
| 534 | - buttonRect = wx.Rect(1, pos, modRectWidth, modRectHeight) | ||
| 535 | - else: | ||
| 536 | - buttonRect = wx.Rect(pos , 1, modRectWidth, modRectHeight) | ||
| 537 | - | ||
| 538 | - def ShowShadow2(self): | ||
| 539 | - pass | ||
| 540 | 511 | ||
| 541 | 512 | ||
| 542 | class DicomPreviewSeries(wx.Panel): | 513 | class DicomPreviewSeries(wx.Panel): |
| @@ -611,14 +582,18 @@ class DicomPreviewSeries(wx.Panel): | @@ -611,14 +582,18 @@ class DicomPreviewSeries(wx.Panel): | ||
| 611 | self.group_list = group_list | 582 | self.group_list = group_list |
| 612 | n = 0 | 583 | n = 0 |
| 613 | for group in group_list: | 584 | for group in group_list: |
| 614 | - info = (group.dicom.image, | ||
| 615 | - float(group.dicom.image.window), | ||
| 616 | - float(group.dicom.image.level), | ||
| 617 | - group.title, | ||
| 618 | - _("%d Images") %(group.nslices), | ||
| 619 | - n, | ||
| 620 | - group_list, | ||
| 621 | - group.dicom) | 585 | + #info = (group.dicom.image, |
| 586 | + # float(group.dicom.image.window), | ||
| 587 | + # float(group.dicom.image.level), | ||
| 588 | + # group.title, | ||
| 589 | + # _("%d Images") %(group.nslices), | ||
| 590 | + # n, | ||
| 591 | + # group_list, | ||
| 592 | + # group.dicom) | ||
| 593 | + info = DicomInfo(n, group.dicom, | ||
| 594 | + group.title, | ||
| 595 | + _("%d Images") %(group.nslices), | ||
| 596 | + ) | ||
| 622 | self.files.append(info) | 597 | self.files.append(info) |
| 623 | n+=1 | 598 | n+=1 |
| 624 | 599 | ||
| @@ -630,7 +605,7 @@ class DicomPreviewSeries(wx.Panel): | @@ -630,7 +605,7 @@ class DicomPreviewSeries(wx.Panel): | ||
| 630 | 605 | ||
| 631 | def _display_previews(self): | 606 | def _display_previews(self): |
| 632 | initial = self.displayed_position * NCOLS | 607 | initial = self.displayed_position * NCOLS |
| 633 | - final = initial + MAX_VALUE | 608 | + final = initial + NUM_PREVIEWS |
| 634 | 609 | ||
| 635 | if len(self.files) < final: | 610 | if len(self.files) < final: |
| 636 | for i in xrange(final-len(self.files)): | 611 | for i in xrange(final-len(self.files)): |
| @@ -733,13 +708,9 @@ class DicomPreview(wx.Panel): | @@ -733,13 +708,9 @@ class DicomPreview(wx.Panel): | ||
| 733 | dicom_files = group.GetHandSortedList() | 708 | dicom_files = group.GetHandSortedList() |
| 734 | n = 0 | 709 | n = 0 |
| 735 | for dicom in dicom_files: | 710 | for dicom in dicom_files: |
| 736 | - info = (dicom.image.imagedata, | ||
| 737 | - dicom.image.window, | ||
| 738 | - dicom.image.level, | ||
| 739 | - _("Image %d") % (dicom.image.number), | ||
| 740 | - "%.2f" % (dicom.image.position[2]), | ||
| 741 | - n, | ||
| 742 | - dicom) | 711 | + info = DicomInfo(n, dicom, |
| 712 | + _("Image %d") % (dicom.image.number), | ||
| 713 | + "%.2f" % (dicom.image.position[2])) | ||
| 743 | self.files.append(info) | 714 | self.files.append(info) |
| 744 | n+=1 | 715 | n+=1 |
| 745 | 716 | ||
| @@ -758,13 +729,10 @@ class DicomPreview(wx.Panel): | @@ -758,13 +729,10 @@ class DicomPreview(wx.Panel): | ||
| 758 | dicom_files = group.GetHandSortedList() | 729 | dicom_files = group.GetHandSortedList() |
| 759 | n = 0 | 730 | n = 0 |
| 760 | for dicom in dicom_files: | 731 | for dicom in dicom_files: |
| 761 | - info = (dicom.image, | ||
| 762 | - dicom.image.window, | ||
| 763 | - dicom.image.level, | 732 | + info = DicomInfo(n, dicom, |
| 764 | _("Image %d") % (dicom.image.number), | 733 | _("Image %d") % (dicom.image.number), |
| 765 | "%.2f" % (dicom.image.position[2]), | 734 | "%.2f" % (dicom.image.position[2]), |
| 766 | - n, | ||
| 767 | - dicom) | 735 | + ) |
| 768 | self.files.append(info) | 736 | self.files.append(info) |
| 769 | n+=1 | 737 | n+=1 |
| 770 | 738 | ||
| @@ -775,10 +743,9 @@ class DicomPreview(wx.Panel): | @@ -775,10 +743,9 @@ class DicomPreview(wx.Panel): | ||
| 775 | 743 | ||
| 776 | self._display_previews() | 744 | self._display_previews() |
| 777 | 745 | ||
| 778 | - | ||
| 779 | def _display_previews(self): | 746 | def _display_previews(self): |
| 780 | initial = self.displayed_position * NCOLS | 747 | initial = self.displayed_position * NCOLS |
| 781 | - final = initial + MAX_VALUE | 748 | + final = initial + NUM_PREVIEWS |
| 782 | print "len:", len(self.files) | 749 | print "len:", len(self.files) |
| 783 | 750 | ||
| 784 | if len(self.files) < final: | 751 | if len(self.files) < final: |
invesalius/reader/dicom.py
| @@ -20,12 +20,9 @@ | @@ -20,12 +20,9 @@ | ||
| 20 | import time | 20 | import time |
| 21 | 21 | ||
| 22 | import gdcm | 22 | import gdcm |
| 23 | -import Image | ||
| 24 | -import vtk | ||
| 25 | import vtkgdcm | 23 | import vtkgdcm |
| 26 | import wx | 24 | import wx |
| 27 | 25 | ||
| 28 | -from vtk.util import numpy_support | ||
| 29 | 26 | ||
| 30 | # In DICOM file format, if multiple values are present for the | 27 | # In DICOM file format, if multiple values are present for the |
| 31 | # "Window Center" (Level) and "Window Width", both attributes | 28 | # "Window Center" (Level) and "Window Width", both attributes |
| @@ -1839,7 +1836,7 @@ class Acquisition(object): | @@ -1839,7 +1836,7 @@ class Acquisition(object): | ||
| 1839 | class Image(object): | 1836 | class Image(object): |
| 1840 | 1837 | ||
| 1841 | def __init__(self): | 1838 | def __init__(self): |
| 1842 | - self._jpeg_file = None | 1839 | + pass |
| 1843 | 1840 | ||
| 1844 | def SetParser(self, parser): | 1841 | def SetParser(self, parser): |
| 1845 | self.level = parser.GetImageWindowLevel() | 1842 | self.level = parser.GetImageWindowLevel() |
| @@ -1873,25 +1870,3 @@ class Image(object): | @@ -1873,25 +1870,3 @@ class Image(object): | ||
| 1873 | spacing[1] = round(spacing[1],2) | 1870 | spacing[1] = round(spacing[1],2) |
| 1874 | spacing[2] = round(spacing[2],2) | 1871 | spacing[2] = round(spacing[2],2) |
| 1875 | self.spacing = spacing | 1872 | self.spacing = spacing |
| 1876 | - | ||
| 1877 | - @property | ||
| 1878 | - def jpeg_file(self): | ||
| 1879 | - if self._jpeg_file: | ||
| 1880 | - return self._jpeg_file | ||
| 1881 | - else: | ||
| 1882 | - colorer = vtk.vtkImageMapToWindowLevelColors() | ||
| 1883 | - colorer.SetInput(self.imagedata) | ||
| 1884 | - colorer.SetWindow(float(self.window)) | ||
| 1885 | - colorer.SetLevel(float(self.level)) | ||
| 1886 | - colorer.SetOutputFormatToRGB() | ||
| 1887 | - colorer.Update() | ||
| 1888 | - | ||
| 1889 | - width, height, z = colorer.GetOutput().GetDimensions() | ||
| 1890 | - | ||
| 1891 | - r = colorer.GetOutput().GetPointData().GetScalars() | ||
| 1892 | - ni = numpy_support.vtk_to_numpy(r) | ||
| 1893 | - #ni = ni.reshape(width, height, 3) | ||
| 1894 | - img = wx.ImageFromBuffer(width, height, ni) | ||
| 1895 | - img = img.Rescale(70, 70).Mirror(False) | ||
| 1896 | - self._jpeg_file = wx.BitmapFromImage(img) | ||
| 1897 | - return self._jpeg_file |