diff --git a/invesalius/data/volume.py b/invesalius/data/volume.py index 5ab2012..9ca58c5 100755 --- a/invesalius/data/volume.py +++ b/invesalius/data/volume.py @@ -19,14 +19,17 @@ import plistlib import os +import numpy import vtk import wx import wx.lib.pubsub as ps import constants as const -from data import vtk_utils import project as prj +from data import vtk_utils +from vtk.util import numpy_support + Kernels = { "Basic Smooth 5x5" : [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 4.0, 4.0, 4.0, 1.0, @@ -128,6 +131,7 @@ class Volume(): #ps.Publisher().sendMessage('Render volume viewer') else: self.LoadVolume() + self.CalculateHistogram() self.exist = 1 if (self.plane and self.plane_on): @@ -173,7 +177,7 @@ class Volume(): ww = self.ww + diff_ww wl = self.wl + diff_wl ps.Publisher().sendMessage('Set volume window and level text', - (ww, wl)) + (ww, wl)) self.SetWWWL(ww, wl) self.ww = ww self.wl = wl @@ -184,7 +188,6 @@ class Volume(): self.SetWWWL(ww,wl) def SetWWWL(self, ww, wl): - if self.config['advancedCLUT']: try: curve = self.config['16bitClutCurves'][self.curve] @@ -233,7 +236,6 @@ class Volume(): def Refresh(self, pubsub_evt): self.__update_colour_table() -#*************** def Create16bColorTable(self, scale): if self.color_transfer: color_transfer = self.color_transfer @@ -530,6 +532,18 @@ class Volume(): self.plane = CutPlane(self.final_imagedata, self.volume_mapper) + def CalculateHistogram(self): + proj = prj.Project() + image = proj.imagedata + r = image.GetScalarRange()[1] - image.GetScalarRange()[0] + accumulate = vtk.vtkImageAccumulate() + accumulate.SetInput(image) + accumulate.SetComponentExtent(0, r -1, 0, 0, 0, 0) + accumulate.SetComponentOrigin(image.GetScalarRange()[0], 0, 0) + accumulate.Update() + n_image = numpy_support.vtk_to_numpy(accumulate.GetOutput().GetPointData().GetScalars()) + ps.Publisher().sendMessage('Load histogram', (n_image, + image.GetScalarRange())) def TranslateScale(self, scale, value): #if value < 0: diff --git a/invesalius/gui/default_viewers.py b/invesalius/gui/default_viewers.py index 67d3519..4b09d89 100755 --- a/invesalius/gui/default_viewers.py +++ b/invesalius/gui/default_viewers.py @@ -237,8 +237,10 @@ class VolumeInteraction(wx.Panel): 'Hide raycasting widget') ps.Publisher().subscribe(self.OnSetRaycastPreset, 'Update raycasting preset') - ps.Publisher().subscribe( self.RefreshPoints, + ps.Publisher().subscribe(self.RefreshPoints, 'Refresh raycasting widget points') + ps.Publisher().subscribe(self.LoadHistogram, + 'Load histogram') def __update_curve_wwwl_text(self, curve): ww, wl = self.clut_raycasting.GetCurveWWWl(curve) @@ -283,6 +285,12 @@ class VolumeInteraction(wx.Panel): p.Hide() self.aui_manager.Update() + def LoadHistogram(self, pubsub_evt): + histogram = pubsub_evt.data[0] + init, end = pubsub_evt.data[1] + self.clut_raycasting.SetRange((init, end)) + self.clut_raycasting.SetHistogramArray(histogram, (init, end)) + def RefreshPoints(self, pubsub_evt): self.clut_raycasting.CalculatePixelPoints() self.clut_raycasting.Refresh() diff --git a/invesalius/gui/widgets/clut_raycasting.py b/invesalius/gui/widgets/clut_raycasting.py index 34b218f..c2901f6 100644 --- a/invesalius/gui/widgets/clut_raycasting.py +++ b/invesalius/gui/widgets/clut_raycasting.py @@ -51,6 +51,12 @@ class Curve(object): self.wl = self.nodes[0].graylevel + self.ww / 2.0 +class Histogram(object): + def __init__(self): + self.init = -1024 + self.end = 2000 + + class CLUTRaycastingWidget(wx.Panel): """ This class represents the frame where images is showed @@ -68,6 +74,7 @@ class CLUTRaycastingWidget(wx.Panel): self.curves = [] self.init = -1024 self.end = 2000 + self.Histogram = Histogram() self.padding = 5 self.previous_wl = 0 self.to_render = False @@ -484,14 +491,14 @@ class CLUTRaycastingWidget(wx.Panel): ctx.set_line_width(HISTOGRAM_LINE_WIDTH) for x,y in self.histogram_pixel_points: ctx.line_to(x,y) - ctx.line_to(x, height) - ctx.line_to(0, height) + ctx.set_source_rgb(*HISTOGRAM_LINE_COLOUR) + ctx.stroke_preserve() + ctx.line_to(x, height + self.padding) + ctx.line_to(self.HounsfieldToPixel(self.Histogram.init), height + self.padding) x,y = self.histogram_pixel_points[0] ctx.line_to(x, y) ctx.set_source_rgb(*HISTOGRAM_FILL_COLOUR) - ctx.fill_preserve() - ctx.set_source_rgb(*HISTOGRAM_LINE_COLOUR) - ctx.stroke() + ctx.fill() def _draw_selection_curve(self, ctx, height): for curve in self.curves: @@ -520,24 +527,23 @@ class CLUTRaycastingWidget(wx.Panel): self._draw_selected_point_text(ctx) def _build_histogram(self): - width, height= self.GetVirtualSizeTuple() + width, height = self.GetVirtualSizeTuple() width -= self.padding - height -= self.padding + height -= (self.padding * 2) + x_init = self.Histogram.init + x_end = self.Histogram.end y_init = 0 y_end = math.log(max(self.histogram_array)) - print y_end - proportion_x = width * 1.0 / (self.end - self.init) + proportion_x = width * 1.0 / (x_end - x_init) proportion_y = height * 1.0 / (y_end - y_init) - print ":) ", y_end, proportion_y self.histogram_pixel_points = [] for i in xrange(len(self.histogram_array)): if self.histogram_array[i]: y = math.log(self.histogram_array[i]) else: y = 0 - x = self.init+ i - x = (x + abs(self.init)) * proportion_x - y = height - y * proportion_y + x = self.HounsfieldToPixel(x_init + i) + y = height - y * proportion_y + self.padding self.histogram_pixel_points.append((x, y)) def __sort_pixel_points(self): @@ -627,8 +633,10 @@ class CLUTRaycastingWidget(wx.Panel): self.to_draw_points = 0 self.Refresh() - def SetHistrogramArray(self, h_array): + def SetHistogramArray(self, h_array, range): self.histogram_array = h_array + self.Histogram.init = range[0] + self.Histogram.end = range[1] def GetCurveWWWl(self, curve): return (self.curves[curve].ww, self.curves[curve].wl) -- libgit2 0.21.2