def __init__(self, module_manager):
# call base constructor
ModuleBase.__init__(self, module_manager)
ColourDialogMixin.__init__(
self, module_manager.get_module_view_parent_window())
self._numDataInputs = self.NUM_INPUTS
# use list comprehension to create list keeping track of inputs
self._inputs = [{'Connected' : None, 'inputData' : None,
'vtkActor' : None, 'ipw' : None}
for i in range(self._numDataInputs)]
# then the window containing the renderwindows
self.threedFrame = None
# the renderers corresponding to the render windows
self._threedRenderer = None
self._outline_source = vtk.vtkOutlineSource()
om = vtk.vtkPolyDataMapper()
om.SetInputConnection(self._outline_source.GetOutputPort())
self._outline_actor = vtk.vtkActor()
self._outline_actor.SetMapper(om)
self._cube_axes_actor2d = vtk.vtkCubeAxesActor2D()
self._cube_axes_actor2d.SetFlyModeToOuterEdges()
#self._cube_axes_actor2d.SetFlyModeToClosestTriad()
# use box widget for VOI selection
self._voi_widget = vtk.vtkBoxWidget()
# we want to keep it aligned with the cubic volume, thanks
self._voi_widget.SetRotationEnabled(0)
self._voi_widget.AddObserver('InteractionEvent',
self.voiWidgetInteractionCallback)
self._voi_widget.AddObserver('EndInteractionEvent',
self.voiWidgetEndInteractionCallback)
self._voi_widget.NeedsPlacement = True
# also create the VTK construct for actually extracting VOI from data
#self._extractVOI = vtk.vtkExtractVOI()
self._currentVOI = 6 * [0]
# set the whole UI up!
self._create_window()
# our interactor styles (we could add joystick or something too)
self._cInteractorStyle = vtk.vtkInteractorStyleTrackballCamera()
# set the default
self.threedFrame.threedRWI.SetInteractorStyle(self._cInteractorStyle)
rwi = self.threedFrame.threedRWI
rwi.Unbind(wx.EVT_MOUSEWHEEL)
rwi.Bind(wx.EVT_MOUSEWHEEL, self._handler_mousewheel)
# initialise our sliceDirections, this will also setup the grid and
# bind all slice UI events
self.sliceDirections = sliceDirections(
self, self.controlFrame.sliceGrid)
self.selectedPoints = selectedPoints(
self, self.controlFrame.pointsGrid)
# we now have a wx.ListCtrl, let's abuse it
self._tdObjects = tdObjects(self,
self.controlFrame.objectsListGrid)
self._implicits = implicits(self,
self.controlFrame.implicitsGrid)
# setup orientation widget stuff
# NB NB NB: we switch interaction with this off later
# (InteractiveOff()), thus disabling direct translation and
# scaling. If we DON'T do this, interaction with software
# raycasters are greatly slowed down.
self._orientation_widget = vtk.vtkOrientationMarkerWidget()
self._annotated_cube_actor = aca = vtk.vtkAnnotatedCubeActor()
#aca.TextEdgesOff()
aca.GetXMinusFaceProperty().SetColor(1,0,0)
aca.GetXPlusFaceProperty().SetColor(1,0,0)
aca.GetYMinusFaceProperty().SetColor(0,1,0)
aca.GetYPlusFaceProperty().SetColor(0,1,0)
aca.GetZMinusFaceProperty().SetColor(0,0,1)
aca.GetZPlusFaceProperty().SetColor(0,0,1)
self._axes_actor = vtk.vtkAxesActor()
self._orientation_widget.SetInteractor(
self.threedFrame.threedRWI)
self._orientation_widget.SetOrientationMarker(
self._axes_actor)
self._orientation_widget.On()
# make sure interaction is off; when on, interaction with
# software raycasters is greatly slowed down!
self._orientation_widget.InteractiveOff()
coneMapper.SetInputConnection(cone.GetOutputPort())
coneActor = vtk.vtkActor()
coneActor.SetMapper(coneMapper)
# A renderer and render window
renderer = vtk.vtkRenderer()
renderer.SetBackground(0, 0, 1)
renderer.AddActor(coneActor)
renwin = vtk.vtkRenderWindow()
renwin.AddRenderer(renderer)
# An interactor
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(renwin)
# A Box widget
boxWidget = vtk.vtkBoxWidget()
boxWidget.SetInteractor(interactor)
boxWidget.SetProp3D(coneActor)
boxWidget.SetPlaceFactor( 1.25 ) # Make the box 1.25x larger than the actor
boxWidget.PlaceWidget()
boxWidget.On()
# Connect the event to a function
boxWidget.AddObserver("InteractionEvent", boxCallback)
# Start
interactor.Initialize()
interactor.Start()
def testBoxWidget(self):
# Demonstrate how to use the vtkBoxWidget.
# This script uses a 3D box widget to define a "clipping box" to clip some
# simple geometry (a mace). Make sure that you hit the "W" key to activate the widget.
# create a sphere source
#
sphere = vtk.vtkSphereSource()
cone = vtk.vtkConeSource()
glyph = vtk.vtkGlyph3D()
glyph.SetInputConnection(sphere.GetOutputPort())
glyph.SetSourceConnection(cone.GetOutputPort())
glyph.SetVectorModeToUseNormal()
glyph.SetScaleModeToScaleByVector()
glyph.SetScaleFactor(0.25)
apd = vtk.vtkAppendPolyData()
apd.AddInputConnection(glyph.GetOutputPort())
apd.AddInputConnection(sphere.GetOutputPort())
maceMapper = vtk.vtkPolyDataMapper()
maceMapper.SetInputConnection(apd.GetOutputPort())
maceActor = vtk.vtkLODActor()
maceActor.SetMapper(maceMapper)
maceActor.VisibilityOn()
planes = vtk.vtkPlanes()
clipper = vtk.vtkClipPolyData()
clipper.SetInputConnection(apd.GetOutputPort())
clipper.SetClipFunction(planes)
clipper.InsideOutOn()
selectMapper = vtk.vtkPolyDataMapper()
selectMapper.SetInputConnection(clipper.GetOutputPort())
selectActor = vtk.vtkLODActor()
selectActor.SetMapper(selectMapper)
selectActor.GetProperty().SetColor(0, 1, 0)
selectActor.VisibilityOff()
selectActor.SetScale(1.01, 1.01, 1.01)
# Create the RenderWindow, Renderer and both Actors
#
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
iRen = vtk.vtkRenderWindowInteractor()
iRen.SetRenderWindow(renWin);
boxWidget = vtk.vtkBoxWidget()
boxWidget.SetInteractor(iRen)
ren.AddActor(maceActor)
ren.AddActor(selectActor)
# Add the actors to the renderer, set the background and size
#
ren.SetBackground(0.1, 0.2, 0.4)
renWin.SetSize(300, 300)
def SelectPolygons(widget, event_string):
'''
The callback takes two parameters.
Parameters:
widget - the object that generates the event.
event_string - the event name (which is a string).
'''
boxWidget, selectActor
boxWidget.GetPlanes(planes)
selectActor.VisibilityOn()
# place the interactor initially
boxWidget.SetInputConnection(glyph.GetOutputPort())
boxWidget.PlaceWidget()
boxWidget.AddObserver("EndInteractionEvent", SelectPolygons)
# render and interact with data
renWin.Render()
img_file = "TestBoxWidget.png"
vtk.test.Testing.compareImage(iRen.GetRenderWindow(), vtk.test.Testing.getAbsImagePath(img_file), threshold=25)
vtk.test.Testing.interact()
def segmentFromSeeds(self, images, image_pos_pat, image_ori_pat, seeds, iren, xplane, yplane, zplane):
""" segmentFromSeeds: Extracts VOI from seeds
INPUTS:
=======
images: (vtkImageData) list of Input image to Transform
seeds: vtkPoints list of seeded coordinates from picker
OUTPUTS:
=======
transformed_image (vtkImageData) Transformed imaged mapped to dicom coords frame
transform (vtkTransform) Transform used
"""
for postS in range(1,len(images)):
print "\n Segmenting image post no : %s " % str(postS)
subimage = self.loadDisplay.subImage(images, postS)
# Proceed to build reference frame for display objects based on DICOM coords
[transformed_image, transform_cube] = self.loadDisplay.dicomTransform(subimage, image_pos_pat, image_ori_pat)
# Calculate the center of the volume
transformed_image.UpdateInformation()
print "\nBoxwidget placed..."
#################################################################
# The box widget observes the events invoked by the render window
# interactor. These events come from user interaction in the render
# window.
# Place the interactor initially. The output of the reader is used to
# place the box widget.
self.boxWidget = vtk.vtkBoxWidget()
self.boxWidget.SetInteractor(iren)
self.boxWidget.SetPlaceFactor(1)
self.boxWidget.SetInput(transformed_image)
if( self.boundsPlane_presel != []):
self.boxWidget.PlaceWidget( self.boundsPlane_presel )
# Construct a bounding box around the seeds
init_seedsBounds = [0,0,0,0,0,0]
seeds.GetBounds( init_seedsBounds )
if postS == 1:
# polygonal data --> image stencil:
# create a simple box VOI mask shape using previously found boundsPlane_preselected
VOIStencil = vtk.vtkROIStencilSource()
VOIStencil.SetShapeToBox()
VOIStencil.SetBounds( init_seedsBounds )
VOIStencil.SetInformationInput(transformed_image)
VOIStencil.Update()
# cut the corresponding VOI region and set the background:
extractVOI_imgstenc = vtk.vtkImageStencil()
extractVOI_imgstenc.SetInput(transformed_image)
extractVOI_imgstenc.SetStencil(VOIStencil.GetOutput())
extractVOI_imgstenc.ReverseStencilOff()
extractVOI_imgstenc.SetBackgroundValue(0.0)
extractVOI_imgstenc.Update()
allSeededIm = vtk.vtkImageData()
allSeededIm.DeepCopy( extractVOI_imgstenc.GetOutput() )
# Add some bounding box radius
self.boxWidget.PlaceWidget( init_seedsBounds )
self.boundsPlane_presel = init_seedsBounds
print "seeds.GetBounds"
print init_seedsBounds
self.boxWidget.AddObserver("InteractionEvent", self.SelectPolygons)
self.boxWidget.On()
# turn off planes
xplane.Off()
yplane.Off()
iren.Start()
self.boxWidget.Off()
# polygonal data --> image stencil:
print "\n Create vtkPolyDataToImageStencil with bounds:"
print self.boundsPlane_presel
# create a simple box VOI mask shape using previously found boundsPlane_preselected
VOIStencil = vtk.vtkROIStencilSource()
VOIStencil.SetShapeToBox()
VOIStencil.SetBounds( self.boundsPlane_presel )
VOIStencil.SetInformationInput(transformed_image)
VOIStencil.Update()
# cut the corresponding VOI region and set the background:
extractVOI_imgstenc = vtk.vtkImageStencil()
extractVOI_imgstenc.SetInput(transformed_image)
extractVOI_imgstenc.SetStencil(VOIStencil.GetOutput())
extractVOI_imgstenc.ReverseStencilOff()
extractVOI_imgstenc.SetBackgroundValue(0.0)
extractVOI_imgstenc.Update()
# add subsecuent VOI stencils
addsegROI = vtk.vtkImageMathematics()
addsegROI.SetInput(0, allSeededIm)
addsegROI.SetInput(1, extractVOI_imgstenc.GetOutput())
#.........这里部分代码省略.........
请发表评论