Commit aa9d1fe9629f689902ff165d734c3b7a6607b4f7

Authored by tfmoraes
1 parent 291b78c3

ADD: The histogram in the clut raycasting widget

invesalius/data/volume.py
... ... @@ -19,14 +19,17 @@
19 19 import plistlib
20 20 import os
21 21  
  22 +import numpy
22 23 import vtk
23 24 import wx
24 25 import wx.lib.pubsub as ps
25 26  
26 27 import constants as const
27   -from data import vtk_utils
28 28 import project as prj
29 29  
  30 +from data import vtk_utils
  31 +from vtk.util import numpy_support
  32 +
30 33 Kernels = {
31 34 "Basic Smooth 5x5" : [1.0, 1.0, 1.0, 1.0, 1.0,
32 35 1.0, 4.0, 4.0, 4.0, 1.0,
... ... @@ -128,6 +131,7 @@ class Volume():
128 131 #ps.Publisher().sendMessage('Render volume viewer')
129 132 else:
130 133 self.LoadVolume()
  134 + self.CalculateHistogram()
131 135 self.exist = 1
132 136  
133 137 if (self.plane and self.plane_on):
... ... @@ -173,7 +177,7 @@ class Volume():
173 177 ww = self.ww + diff_ww
174 178 wl = self.wl + diff_wl
175 179 ps.Publisher().sendMessage('Set volume window and level text',
176   - (ww, wl))
  180 + (ww, wl))
177 181 self.SetWWWL(ww, wl)
178 182 self.ww = ww
179 183 self.wl = wl
... ... @@ -184,7 +188,6 @@ class Volume():
184 188 self.SetWWWL(ww,wl)
185 189  
186 190 def SetWWWL(self, ww, wl):
187   -
188 191 if self.config['advancedCLUT']:
189 192 try:
190 193 curve = self.config['16bitClutCurves'][self.curve]
... ... @@ -233,7 +236,6 @@ class Volume():
233 236 def Refresh(self, pubsub_evt):
234 237 self.__update_colour_table()
235 238  
236   -#***************
237 239 def Create16bColorTable(self, scale):
238 240 if self.color_transfer:
239 241 color_transfer = self.color_transfer
... ... @@ -530,6 +532,18 @@ class Volume():
530 532 self.plane = CutPlane(self.final_imagedata,
531 533 self.volume_mapper)
532 534  
  535 + def CalculateHistogram(self):
  536 + proj = prj.Project()
  537 + image = proj.imagedata
  538 + r = image.GetScalarRange()[1] - image.GetScalarRange()[0]
  539 + accumulate = vtk.vtkImageAccumulate()
  540 + accumulate.SetInput(image)
  541 + accumulate.SetComponentExtent(0, r -1, 0, 0, 0, 0)
  542 + accumulate.SetComponentOrigin(image.GetScalarRange()[0], 0, 0)
  543 + accumulate.Update()
  544 + n_image = numpy_support.vtk_to_numpy(accumulate.GetOutput().GetPointData().GetScalars())
  545 + ps.Publisher().sendMessage('Load histogram', (n_image,
  546 + image.GetScalarRange()))
533 547  
534 548 def TranslateScale(self, scale, value):
535 549 #if value < 0:
... ...
invesalius/gui/default_viewers.py
... ... @@ -237,8 +237,10 @@ class VolumeInteraction(wx.Panel):
237 237 'Hide raycasting widget')
238 238 ps.Publisher().subscribe(self.OnSetRaycastPreset,
239 239 'Update raycasting preset')
240   - ps.Publisher().subscribe( self.RefreshPoints,
  240 + ps.Publisher().subscribe(self.RefreshPoints,
241 241 'Refresh raycasting widget points')
  242 + ps.Publisher().subscribe(self.LoadHistogram,
  243 + 'Load histogram')
242 244  
243 245 def __update_curve_wwwl_text(self, curve):
244 246 ww, wl = self.clut_raycasting.GetCurveWWWl(curve)
... ... @@ -283,6 +285,12 @@ class VolumeInteraction(wx.Panel):
283 285 p.Hide()
284 286 self.aui_manager.Update()
285 287  
  288 + def LoadHistogram(self, pubsub_evt):
  289 + histogram = pubsub_evt.data[0]
  290 + init, end = pubsub_evt.data[1]
  291 + self.clut_raycasting.SetRange((init, end))
  292 + self.clut_raycasting.SetHistogramArray(histogram, (init, end))
  293 +
286 294 def RefreshPoints(self, pubsub_evt):
287 295 self.clut_raycasting.CalculatePixelPoints()
288 296 self.clut_raycasting.Refresh()
... ...
invesalius/gui/widgets/clut_raycasting.py
... ... @@ -51,6 +51,12 @@ class Curve(object):
51 51 self.wl = self.nodes[0].graylevel + self.ww / 2.0
52 52  
53 53  
  54 +class Histogram(object):
  55 + def __init__(self):
  56 + self.init = -1024
  57 + self.end = 2000
  58 +
  59 +
54 60 class CLUTRaycastingWidget(wx.Panel):
55 61 """
56 62 This class represents the frame where images is showed
... ... @@ -68,6 +74,7 @@ class CLUTRaycastingWidget(wx.Panel):
68 74 self.curves = []
69 75 self.init = -1024
70 76 self.end = 2000
  77 + self.Histogram = Histogram()
71 78 self.padding = 5
72 79 self.previous_wl = 0
73 80 self.to_render = False
... ... @@ -484,14 +491,14 @@ class CLUTRaycastingWidget(wx.Panel):
484 491 ctx.set_line_width(HISTOGRAM_LINE_WIDTH)
485 492 for x,y in self.histogram_pixel_points:
486 493 ctx.line_to(x,y)
487   - ctx.line_to(x, height)
488   - ctx.line_to(0, height)
  494 + ctx.set_source_rgb(*HISTOGRAM_LINE_COLOUR)
  495 + ctx.stroke_preserve()
  496 + ctx.line_to(x, height + self.padding)
  497 + ctx.line_to(self.HounsfieldToPixel(self.Histogram.init), height + self.padding)
489 498 x,y = self.histogram_pixel_points[0]
490 499 ctx.line_to(x, y)
491 500 ctx.set_source_rgb(*HISTOGRAM_FILL_COLOUR)
492   - ctx.fill_preserve()
493   - ctx.set_source_rgb(*HISTOGRAM_LINE_COLOUR)
494   - ctx.stroke()
  501 + ctx.fill()
495 502  
496 503 def _draw_selection_curve(self, ctx, height):
497 504 for curve in self.curves:
... ... @@ -520,24 +527,23 @@ class CLUTRaycastingWidget(wx.Panel):
520 527 self._draw_selected_point_text(ctx)
521 528  
522 529 def _build_histogram(self):
523   - width, height= self.GetVirtualSizeTuple()
  530 + width, height = self.GetVirtualSizeTuple()
524 531 width -= self.padding
525   - height -= self.padding
  532 + height -= (self.padding * 2)
  533 + x_init = self.Histogram.init
  534 + x_end = self.Histogram.end
526 535 y_init = 0
527 536 y_end = math.log(max(self.histogram_array))
528   - print y_end
529   - proportion_x = width * 1.0 / (self.end - self.init)
  537 + proportion_x = width * 1.0 / (x_end - x_init)
530 538 proportion_y = height * 1.0 / (y_end - y_init)
531   - print ":) ", y_end, proportion_y
532 539 self.histogram_pixel_points = []
533 540 for i in xrange(len(self.histogram_array)):
534 541 if self.histogram_array[i]:
535 542 y = math.log(self.histogram_array[i])
536 543 else:
537 544 y = 0
538   - x = self.init+ i
539   - x = (x + abs(self.init)) * proportion_x
540   - y = height - y * proportion_y
  545 + x = self.HounsfieldToPixel(x_init + i)
  546 + y = height - y * proportion_y + self.padding
541 547 self.histogram_pixel_points.append((x, y))
542 548  
543 549 def __sort_pixel_points(self):
... ... @@ -627,8 +633,10 @@ class CLUTRaycastingWidget(wx.Panel):
627 633 self.to_draw_points = 0
628 634 self.Refresh()
629 635  
630   - def SetHistrogramArray(self, h_array):
  636 + def SetHistogramArray(self, h_array, range):
631 637 self.histogram_array = h_array
  638 + self.Histogram.init = range[0]
  639 + self.Histogram.end = range[1]
632 640  
633 641 def GetCurveWWWl(self, curve):
634 642 return (self.curves[curve].ww, self.curves[curve].wl)
... ...