def rasArray(self, volumeNode, matrix=None, targetNode=None, debug=False): """ Returns a numpy array of the given node resampled into RAS space If given, use the passed matrix as a final RAS to RAS transform """ # get the transform from image space to world space volumeNode.GetIJKToRASMatrix(self.ijkToRAS) transformNode = volumeNode.GetParentTransformNode() if transformNode: self.scratchMatrix.Identity() transformNode.GetMatrixTransformToWorld(self.scratchMatrix) self.ijkToRAS.Multiply4x4(self.scratchMatrix, self.ijkToRAS, self.ijkToRAS) if matrix: self.ijkToRAS.Multiply4x4(matrix, self.ijkToRAS, self.ijkToRAS) self.rasToIJK.DeepCopy(self.ijkToRAS) self.rasToIJK.Invert() # use the matrix to extract the volume and convert it to an array self.reslice.SetInterpolationModeToLinear() self.reslice.InterpolateOn() self.resliceTransform.SetMatrix(self.rasToIJK) self.reslice.SetResliceTransform(self.resliceTransform) self.reslice.SetInputData( volumeNode.GetImageData() ) if targetNode: bounds = [0,]*6 targetNode.GetRASBounds(bounds) self.reslice.SetOutputExtent(0, int((bounds[1]-bounds[0])/self.sampleSpacing), 0, int((bounds[3]-bounds[2])/self.sampleSpacing), 0, int((bounds[5]-bounds[4])/self.sampleSpacing)) self.reslice.SetOutputOrigin(bounds[0],bounds[2],bounds[4]) self.reslice.SetOutputSpacing([self.sampleSpacing,]*3) self.reslice.UpdateWholeExtent() rasImage = self.reslice.GetOutput() shape = list(rasImage.GetDimensions()) shape.reverse() rasArray = vtk.util.numpy_support.vtk_to_numpy(rasImage.GetPointData().GetScalars()).reshape(shape) if debug: if not self.viewer: self.viewer = vtk.vtkImageViewer() self.viewer.SetSize(500,500) self.viewer.SetColorWindow( 128 ) self.viewer.SetColorLevel( 67 ) self.viewer.SetInputData( rasImage ) self.viewer.SetZSlice( rasArray.shape[2]/2 ) self.viewer.Render() slicer.modules.RegimaticWidget.rasArray = rasArray return rasArray
def __init__(self, scene=None): """ Do whatever is needed to reset the state - typically a scene clear will be enough. """ self.logic = ShaderComputationLogic() try: from vtkSlicerShadedActorModuleLogicPython import vtkOpenGLShaderComputation except ImportError: import vtkAddon vtkOpenGLShaderComputation = vtkAddon.vtkOpenGLShaderComputation self.shaderComputation = vtkOpenGLShaderComputation() self.shaderComputation.SetVertexShaderSource( self.logic.rayCastVertexShaderSource()) self.resultImage = vtk.vtkImageData() self.resultImage.SetDimensions(1024, 1024, 1) self.resultImage.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 4) self.shaderComputation.SetResultImageData(self.resultImage) self.imageViewer = vtk.vtkImageViewer() self.imageViewer.SetColorLevel(128) self.imageViewer.SetColorWindow(256) self.transformPointSource = "" # TODO: this is just an example self.volumePropertyNode = None # map of node IDs to instances of FieldSampler subclasses self.fieldSamplersByNodeID = {} if scene: self.scene = scene else: self.scene = slicer.mrmlScene self.sceneObserver = SceneObserver(self.scene) self.sceneObserver.addTrigger("ScalarVolume", "Added", self.onVolumeAdded) self.sceneObserver.addTrigger("ScalarVolume", "Removed", self.onVolumeRemoved) self.sceneObserver.addTrigger("ScalarVolume", "Modified", self.requestRender) self.sceneObserver.addTrigger("ScalarVolume", "ImageDataModified", self.requestRender) self.sceneObserver.addTrigger("LabelMapVolume", "Modified", self.requestRender) self.sceneObserver.addTrigger("LabelMapVolume", "ImageDataModified", self.requestRender) self.sceneObserver.addTrigger("Camera", "Modified", self.requestRender) self.sceneObserver.addTrigger("LinearTransform", "Modified", self.requestRender) self.sceneObserver.addTrigger("VolumeProperty", "Modified", self.requestRender) self.sceneObserver.addTrigger("MarkupsFiducial", "Modified", self.requestRender) self.renderPending = False
def __init__(self, scene=None): """ Do whatever is needed to reset the state - typically a scene clear will be enough. """ self.logic = ShaderComputationLogic() try: from vtkSlicerShadedActorModuleLogicPython import vtkOpenGLShaderComputation except ImportError: import vtkAddon vtkOpenGLShaderComputation=vtkAddon.vtkOpenGLShaderComputation self.shaderComputation=vtkOpenGLShaderComputation() self.shaderComputation.SetVertexShaderSource(self.logic.rayCastVertexShaderSource()) self.resultImage = vtk.vtkImageData() self.resultImage.SetDimensions(1024, 1024, 1) self.resultImage.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 4) self.shaderComputation.SetResultImageData(self.resultImage) self.imageViewer = vtk.vtkImageViewer() self.imageViewer.SetColorLevel(128) self.imageViewer.SetColorWindow(256) self.transformPointSource = "" ;# TODO: this is just an example self.volumePropertyNode = None # map of node IDs to instances of FieldSampler subclasses self.fieldSamplersByNodeID = {} if scene: self.scene = scene else: self.scene = slicer.mrmlScene self.sceneObserver = SceneObserver(self.scene) self.sceneObserver.addTrigger("ScalarVolume", "Added", self.onVolumeAdded) self.sceneObserver.addTrigger("ScalarVolume", "Removed", self.onVolumeRemoved) self.sceneObserver.addTrigger("ScalarVolume", "Modified", self.requestRender) self.sceneObserver.addTrigger("ScalarVolume", "ImageDataModified", self.requestRender) self.sceneObserver.addTrigger("LabelMapVolume", "Modified", self.requestRender) self.sceneObserver.addTrigger("LabelMapVolume", "ImageDataModified", self.requestRender) self.sceneObserver.addTrigger("Camera", "Modified", self.requestRender) self.sceneObserver.addTrigger("LinearTransform", "Modified", self.requestRender) self.sceneObserver.addTrigger("VolumeProperty", "Modified", self.requestRender) self.sceneObserver.addTrigger("MarkupsFiducial", "Modified", self.requestRender) self.renderPending = False
def previewOnIsograph(self, xy=(100, 100)): if not self.editUtil.getBackgroundImage( ) or not self.editUtil.getLabelImage(): return # # get the visible section of the background (pre-window/level) # to use as input to the shader code # sliceLogic = self.sliceWidget.sliceLogic() backgroundLogic = sliceLogic.GetBackgroundLayer() backgroundLogic.GetReslice().Update() backgroundImage = backgroundLogic.GetReslice().GetOutputDataObject(0) backgroundDimensions = backgroundImage.GetDimensions() self.backgroundTextureImage.SetImageData(backgroundImage) self.backgroundTextureImage.Activate(0) # make a result image to match dimensions and type self.resultImage = vtk.vtkImageData() self.resultImage.SetDimensions(backgroundDimensions) self.resultImage.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 4) self.shaderComputation.SetResultImageData(self.resultImage) fragmentShaderSource = """ #version 120 #define M_PI 3.1415926535897932384626433832795 #define M_2PI (2. * M_PI) #define UNITIALIZED -99 varying vec3 interpolatedTextureCoordinate; uniform sampler3D textureUnit0; // background void main() { vec3 referenceTextureCoordinate = vec3(%(referenceX)f, %(referenceY)f, .5); // mouse float minimumMetric = UNITIALIZED; float metric = 0.; float angleStep = M_2PI / %(rotationSteps)d; mat3 stepRotation = mat3(1); for (int step = 0; step < %(rotationSteps)d; step++) { float referenceSum = 0.; float angle = step * angleStep; stepRotation[0] = vec3( cos(angle), -sin(angle), 1); stepRotation[1] = vec3( sin(angle), cos(angle), 1); float summedDifference = 0; for (int offsetX = -%(kernelSize)d; offsetX <= %(kernelSize)d; offsetX++) { for (int offsetY = -%(kernelSize)d; offsetY <= %(kernelSize)d; offsetY++) { vec3 offset = vec3(offsetX * %(stepX)f, offsetY * %(stepY)f, 0); vec4 referenceSample = %(sampleScale)f * texture3D(textureUnit0, referenceTextureCoordinate + offset); referenceSum += referenceSample.r; offset = stepRotation * offset; vec4 stepSample = %(sampleScale)f * texture3D(textureUnit0, interpolatedTextureCoordinate + offset); summedDifference += abs(referenceSample.r - stepSample.r); } } // normalize to be a ratio compared to the mean value of the reference patch float sampleCount = pow(2. * %(kernelSize)f + 1, 2.); float normalizedDifference = summedDifference / sampleCount / referenceSum; if (normalizedDifference < minimumMetric || minimumMetric == UNITIALIZED) { minimumMetric = normalizedDifference; } } if (minimumMetric < %(similarityThreshold)f ) { metric = .75; } gl_FragColor = vec4(1,1,0,metric); } """ % { 'sampleScale': 500., 'similarityThreshold': .005, 'rotationSteps': 100, 'kernelSize': 3, 'stepX': 1. / float(backgroundDimensions[0]), 'stepY': 1. / float(backgroundDimensions[1]), 'referenceX': xy[0] / float(backgroundDimensions[0]), 'referenceY': xy[1] / float(backgroundDimensions[1]), } self.shaderComputation.AcquireResultRenderbuffer() self.shaderComputation.SetFragmentShaderSource(fragmentShaderSource) self.shaderComputation.Compute() self.shaderComputation.ReadResult() self.shaderComputation.ReleaseResultRenderbuffer() self.cursorMapper.SetInputDataObject(self.resultImage) self.cursorActor.VisibilityOn() self.sliceView.forceRender() if False: if not hasattr(self, 'imageViewer'): self.imageViewer = vtk.vtkImageViewer() self.imageViewer.SetColorWindow(256) self.imageViewer.SetColorLevel(128) self.imageViewer.SetInputData(self.resultImage) self.imageViewer.Render()
def test_ShadedModels1(self): """ Ideally you should have several levels of tests. At the lowest level tests should exercise the functionality of the logic with different inputs (both valid and invalid). At higher levels your tests should emulate the way the user would interact with your code and confirm that it still works the way you intended. One of the most important features of the tests is that it should alert other developers when their changes will have an impact on the behavior of your module. For example, if a developer removes a feature that you depend on, your test should break so they know that the feature is needed. """ self.delayDisplay("Starting the test") import SampleData sampleDataLogic = SampleData.SampleDataLogic() print("Getting MR Head Volume") mrHeadVolume = sampleDataLogic.downloadMRHead() resize = vtk.vtkImageResize() resize.SetInputDataObject(mrHeadVolume.GetImageData()) resize.SetOutputDimensions(256,256,128) resize.Update() tdw = slicer.qMRMLThreeDWidget() tdw.setMRMLScene(slicer.mrmlScene) tdw.setMRMLViewNode(slicer.util.getNode("*ViewNode*")) tdw.show() from vtkSlicerShadedActorModuleLogicPython import * shadedActor=vtkOpenGLShadedActor() tdv = tdw.threeDView() rw = tdv.renderWindow() rens = rw.GetRenderers() ren = rens.GetItemAsObject(0) ren.AddActor(shadedActor) mapper = vtk.vtkPolyDataMapper() shadedActor.SetMapper(mapper) shadedActor.SetVertexShaderSource(""" #version 120 attribute vec3 vertexAttribute; attribute vec2 textureCoordinateAttribute; varying vec4 interpolatedColor; varying vec3 interpolatedTextureCoordinate; void main() { interpolatedColor = vec4(0.5) + vec4(vertexAttribute, 1.); interpolatedTextureCoordinate = vec3(textureCoordinateAttribute, .5); gl_Position = vec4(vertexAttribute, 1.); } """) shadedActor.SetFragmentShaderSource(""" #version 120 varying vec4 interpolatedColor; varying vec3 interpolatedTextureCoordinate; uniform sampler3D volumeSampler; void main() { gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 ); gl_FragColor = interpolatedColor; vec4 volumeSample = texture3D(volumeSampler, interpolatedTextureCoordinate); volumeSample *= 100; gl_FragColor = mix( volumeSample, interpolatedColor, 0.5); vec4 integratedRay = vec4(0.); for (int i = 0; i < 256; i++) { vec3 samplePoint = vec3(interpolatedTextureCoordinate.st, i/256.); vec4 volumeSample = texture3D(volumeSampler, samplePoint); integratedRay += volumeSample; } gl_FragColor = integratedRay; } """) shadedActor.SetTextureImageData(resize.GetOutputDataObject(0)) #shadedActor.SetTextureImageData(mrHeadVolume.GetImageData()) sphereSource = vtk.vtkSphereSource() mapper.SetInputConnection(sphereSource.GetOutputPort()) actor = vtk.vtkActor() actor.SetScale(20,20,20) actor.SetMapper(mapper) ren.AddActor(actor) rw.Render() wti = vtk.vtkWindowToImageFilter() wti.SetInput(rw) iv = vtk.vtkImageViewer() iv.SetColorLevel(128) iv.SetColorWindow(256) iv.SetInputConnection(wti.GetOutputPort()) iv.Render() extensionManager = vtk.vtkOpenGLExtensionManager() extensionManager.SetRenderWindow(rw) extensionManager.Update() print(extensionManager) print(extensionManager.GetDriverGLVendor()) print(extensionManager.GetDriverGLVersion()) print(extensionManager.GetDriverGLRenderer()) slicer.modules.ShadedModelsWidget.tdw = tdw slicer.modules.ShadedModelsWidget.iv = iv
def test_ShadedModels1(self): """ Ideally you should have several levels of tests. At the lowest level tests should exercise the functionality of the logic with different inputs (both valid and invalid). At higher levels your tests should emulate the way the user would interact with your code and confirm that it still works the way you intended. One of the most important features of the tests is that it should alert other developers when their changes will have an impact on the behavior of your module. For example, if a developer removes a feature that you depend on, your test should break so they know that the feature is needed. """ self.delayDisplay("Starting the test") import SampleData sampleDataLogic = SampleData.SampleDataLogic() print("Getting MR Head Volume") mrHeadVolume = sampleDataLogic.downloadMRHead() resize = vtk.vtkImageResize() resize.SetInputDataObject(mrHeadVolume.GetImageData()) resize.SetOutputDimensions(256, 256, 128) resize.Update() tdw = slicer.qMRMLThreeDWidget() tdw.setMRMLScene(slicer.mrmlScene) tdw.setMRMLViewNode(slicer.util.getNode("*ViewNode*")) tdw.show() from vtkSlicerShadedActorModuleLogicPython import * shadedActor = vtkOpenGLShadedActor() tdv = tdw.threeDView() rw = tdv.renderWindow() rens = rw.GetRenderers() ren = rens.GetItemAsObject(0) ren.AddActor(shadedActor) mapper = vtk.vtkPolyDataMapper() shadedActor.SetMapper(mapper) shadedActor.SetVertexShaderSource(""" #version 120 attribute vec3 vertexAttribute; attribute vec2 textureCoordinateAttribute; varying vec4 interpolatedColor; varying vec3 interpolatedTextureCoordinate; void main() { interpolatedColor = vec4(0.5) + vec4(vertexAttribute, 1.); interpolatedTextureCoordinate = vec3(textureCoordinateAttribute, .5); gl_Position = vec4(vertexAttribute, 1.); } """) shadedActor.SetFragmentShaderSource(""" #version 120 varying vec4 interpolatedColor; varying vec3 interpolatedTextureCoordinate; uniform sampler3D volumeSampler; void main() { gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 ); gl_FragColor = interpolatedColor; vec4 volumeSample = texture3D(volumeSampler, interpolatedTextureCoordinate); volumeSample *= 100; gl_FragColor = mix( volumeSample, interpolatedColor, 0.5); vec4 integratedRay = vec4(0.); for (int i = 0; i < 256; i++) { vec3 samplePoint = vec3(interpolatedTextureCoordinate.st, i/256.); vec4 volumeSample = texture3D(volumeSampler, samplePoint); integratedRay += volumeSample; } gl_FragColor = integratedRay; } """) shadedActor.SetTextureImageData(resize.GetOutputDataObject(0)) #shadedActor.SetTextureImageData(mrHeadVolume.GetImageData()) sphereSource = vtk.vtkSphereSource() mapper.SetInputConnection(sphereSource.GetOutputPort()) actor = vtk.vtkActor() actor.SetScale(20, 20, 20) actor.SetMapper(mapper) ren.AddActor(actor) rw.Render() wti = vtk.vtkWindowToImageFilter() wti.SetInput(rw) iv = vtk.vtkImageViewer() iv.SetColorLevel(128) iv.SetColorWindow(256) iv.SetInputConnection(wti.GetOutputPort()) iv.Render() extensionManager = vtk.vtkOpenGLExtensionManager() extensionManager.SetRenderWindow(rw) extensionManager.Update() print(extensionManager) print(extensionManager.GetDriverGLVendor()) print(extensionManager.GetDriverGLVersion()) print(extensionManager.GetDriverGLRenderer()) slicer.modules.ShadedModelsWidget.tdw = tdw slicer.modules.ShadedModelsWidget.iv = iv
def previewOnIsograph(self, xy=(100,100)): if not self.editUtil.getBackgroundImage() or not self.editUtil.getLabelImage(): return # # get the visible section of the background (pre-window/level) # to use as input to the shader code # sliceLogic = self.sliceWidget.sliceLogic() backgroundLogic = sliceLogic.GetBackgroundLayer() backgroundLogic.GetReslice().Update() backgroundImage = backgroundLogic.GetReslice().GetOutputDataObject(0) backgroundDimensions = backgroundImage.GetDimensions() self.backgroundTextureImage.SetImageData(backgroundImage) self.backgroundTextureImage.Activate(0) # make a result image to match dimensions and type self.resultImage = vtk.vtkImageData() self.resultImage.SetDimensions(backgroundDimensions) self.resultImage.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 4) self.shaderComputation.SetResultImageData(self.resultImage) fragmentShaderSource = """ #version 120 #define M_PI 3.1415926535897932384626433832795 #define M_2PI (2. * M_PI) #define UNITIALIZED -99 varying vec3 interpolatedTextureCoordinate; uniform sampler3D textureUnit0; // background void main() { vec3 referenceTextureCoordinate = vec3(%(referenceX)f, %(referenceY)f, .5); // mouse float minimumMetric = UNITIALIZED; float metric = 0.; float angleStep = M_2PI / %(rotationSteps)d; mat3 stepRotation = mat3(1); for (int step = 0; step < %(rotationSteps)d; step++) { float referenceSum = 0.; float angle = step * angleStep; stepRotation[0] = vec3( cos(angle), -sin(angle), 1); stepRotation[1] = vec3( sin(angle), cos(angle), 1); float summedDifference = 0; for (int offsetX = -%(kernelSize)d; offsetX <= %(kernelSize)d; offsetX++) { for (int offsetY = -%(kernelSize)d; offsetY <= %(kernelSize)d; offsetY++) { vec3 offset = vec3(offsetX * %(stepX)f, offsetY * %(stepY)f, 0); vec4 referenceSample = %(sampleScale)f * texture3D(textureUnit0, referenceTextureCoordinate + offset); referenceSum += referenceSample.r; offset = stepRotation * offset; vec4 stepSample = %(sampleScale)f * texture3D(textureUnit0, interpolatedTextureCoordinate + offset); summedDifference += abs(referenceSample.r - stepSample.r); } } // normalize to be a ratio compared to the mean value of the reference patch float sampleCount = pow(2. * %(kernelSize)f + 1, 2.); float normalizedDifference = summedDifference / sampleCount / referenceSum; if (normalizedDifference < minimumMetric || minimumMetric == UNITIALIZED) { minimumMetric = normalizedDifference; } } if (minimumMetric < %(similarityThreshold)f ) { metric = .75; } gl_FragColor = vec4(1,1,0,metric); } """ % { 'sampleScale' : 500., 'similarityThreshold' : .005, 'rotationSteps' : 100, 'kernelSize' : 3, 'stepX' : 1. / float(backgroundDimensions[0]), 'stepY' : 1. / float(backgroundDimensions[1]), 'referenceX' : xy[0] / float(backgroundDimensions[0]), 'referenceY' : xy[1] / float(backgroundDimensions[1]), } self.shaderComputation.AcquireResultRenderbuffer() self.shaderComputation.SetFragmentShaderSource(fragmentShaderSource) self.shaderComputation.Compute() self.shaderComputation.ReadResult() self.shaderComputation.ReleaseResultRenderbuffer() self.cursorMapper.SetInputDataObject(self.resultImage) self.cursorActor.VisibilityOn() self.sliceView.forceRender() if False: if not hasattr(self,'imageViewer'): self.imageViewer = vtk.vtkImageViewer() self.imageViewer.SetColorWindow(256) self.imageViewer.SetColorLevel(128) self.imageViewer.SetInputData(self.resultImage) self.imageViewer.Render()