示例#1
0
  def maskVolume(self, volumeIn, roiNode, inPlace=False):
    # Clone input volume, unless inPlace
    inPlace = False # TODO: make this work
    
    nameout = volumeIn.GetName()
    if not "masked" in nameout:
        nameout += " masked"
    
    if inPlace:
        outData = vtk.vtkImageData()
        volumeIn.SetName(volumeIn.GetName() + " masked")
    else:
        volumeOut = slicer.modules.volumes.logic().CloneVolume(volumeIn, nameout)
        outData = volumeOut.GetImageData()

    # Get transform into image space
    IJKtoRAS = vtk.vtkMatrix4x4()
    volumeIn.GetIJKToRASMatrix(IJKtoRAS)

    # Get ROI to image transform
    ROItoImage = vtk.vtkMatrix4x4()
    ROItoImage.Identity()
    parentNode = roiNode.GetParentTransformNode()
    if parentNode is None and volumeIn.GetParentTransformNode():
      volumeIn.GetParentTransformNode().GetMatrixTransformToWorld(ROItoImage)
      # don't invert here, this is already the proper direction.
    if parentNode is not None:
      parentNode.GetMatrixTransformToNode(volumeIn.GetParentTransformNode(), ROItoImage)
      ROItoImage.Invert()
    
    # Transformations
    tfm = vtk.vtkTransform()
    tfm.SetMatrix(IJKtoRAS)
    tfm.PostMultiply()
    tfm.Concatenate(ROItoImage)

    # Get planes and apply transform
    planes = vtk.vtkPlanes()
    roiNode.GetTransformedPlanes(planes)
    planes.SetTransform(tfm)

    # Blot out selected region
    tostencil = vtk.vtkImplicitFunctionToImageStencil()
    tostencil.SetInput(planes)
    imgstencil = vtk.vtkImageStencil()
    imgstencil.SetInput(volumeIn.GetImageData())
    imgstencil.SetStencil(tostencil.GetOutput())
    imgstencil.SetBackgroundValue(0)
    imgstencil.ReverseStencilOn()

    # Write the changes
    imgstencil.SetOutput(outData)
    imgstencil.Update()
    def clipVolumeWithRoi(self, roiNode, volumeNode, fillValue,
                          clipOutsideSurface, outputVolume):

        # Create a box implicit function that will be used as a stencil to fill the volume

        roiBox = vtk.vtkBox()
        roiCenter = [0, 0, 0]
        roiNode.GetXYZ(roiCenter)
        roiRadius = [0, 0, 0]
        roiNode.GetRadiusXYZ(roiRadius)
        roiBox.SetBounds(roiCenter[0] - roiRadius[0],
                         roiCenter[0] + roiRadius[0],
                         roiCenter[1] - roiRadius[1],
                         roiCenter[1] + roiRadius[1],
                         roiCenter[2] - roiRadius[2],
                         roiCenter[2] + roiRadius[2])

        # Determine the transform between the box and the image IJK coordinate systems

        rasToBox = vtk.vtkMatrix4x4()
        if roiNode.GetTransformNodeID() != None:
            roiBoxTransformNode = slicer.mrmlScene.GetNodeByID(
                roiNode.GetTransformNodeID())
            boxToRas = vtk.vtkMatrix4x4()
            roiBoxTransformNode.GetMatrixTransformToWorld(boxToRas)
            rasToBox.DeepCopy(boxToRas)
            rasToBox.Invert()

        ijkToRas = vtk.vtkMatrix4x4()
        volumeNode.GetIJKToRASMatrix(ijkToRas)

        ijkToBox = vtk.vtkMatrix4x4()
        vtk.vtkMatrix4x4.Multiply4x4(rasToBox, ijkToRas, ijkToBox)
        ijkToBoxTransform = vtk.vtkTransform()
        ijkToBoxTransform.SetMatrix(ijkToBox)
        roiBox.SetTransform(ijkToBoxTransform)

        # Use the stencil to fill the volume

        imageData = volumeNode.GetImageData()

        # Convert the implicit function to a stencil
        functionToStencil = vtk.vtkImplicitFunctionToImageStencil()
        functionToStencil.SetInput(roiBox)
        functionToStencil.SetOutputOrigin(imageData.GetOrigin())
        functionToStencil.SetOutputSpacing(imageData.GetSpacing())
        functionToStencil.SetOutputWholeExtent(imageData.GetExtent())
        functionToStencil.Update()

        # Apply the stencil to the volume
        stencilToImage = vtk.vtkImageStencil()
        stencilToImage.SetInputData(imageData)
        stencilToImage.SetStencilData(functionToStencil.GetOutput())
        if clipOutsideSurface:
            stencilToImage.ReverseStencilOff()
        else:
            stencilToImage.ReverseStencilOn()
        stencilToImage.SetBackgroundValue(fillValue)
        stencilToImage.Update()

        # Update the volume with the stencil operation result
        outputImageData = vtk.vtkImageData()
        outputImageData.DeepCopy(stencilToImage.GetOutput())

        outputVolume.SetAndObserveImageData(outputImageData)
        outputVolume.SetIJKToRASMatrix(ijkToRas)

        # Add a default display node to output volume node if it does not exist yet
        if not outputVolume.GetDisplayNode:
            displayNode = slicer.vtkMRMLScalarVolumeDisplayNode()
            displayNode.SetAndObserveColorNodeID("vtkMRMLColorTableNodeGrey")
            slicer.mrmlScene.AddNode(displayNode)
            outputVolume.SetAndObserveDisplayNodeID(displayNode.GetID())
示例#3
0
    def clipVolumeWithModel(self, inputVolume, clippingModel,
                            clipOutsideSurface, fillOutsideValue,
                            clipInsideSurface, fillInsideValue, outputVolume):
        """
    Fill voxels of the input volume inside/outside the clipping model with the provided fill value
    """

        # Determine the transform between the box and the image IJK coordinate systems

        rasToModel = vtk.vtkMatrix4x4()
        if clippingModel.GetTransformNodeID() != None:
            modelTransformNode = slicer.mrmlScene.GetNodeByID(
                clippingModel.GetTransformNodeID())
            boxToRas = vtk.vtkMatrix4x4()
            modelTransformNode.GetMatrixTransformToWorld(boxToRas)
            rasToModel.DeepCopy(boxToRas)
            rasToModel.Invert()

        ijkToRas = vtk.vtkMatrix4x4()
        inputVolume.GetIJKToRASMatrix(ijkToRas)

        ijkToModel = vtk.vtkMatrix4x4()
        vtk.vtkMatrix4x4.Multiply4x4(rasToModel, ijkToRas, ijkToModel)
        modelToIjkTransform = vtk.vtkTransform()
        modelToIjkTransform.SetMatrix(ijkToModel)
        modelToIjkTransform.Inverse()

        transformModelToIjk = vtk.vtkTransformPolyDataFilter()
        transformModelToIjk.SetTransform(modelToIjkTransform)
        transformModelToIjk.SetInputConnection(
            clippingModel.GetPolyDataConnection())

        # Use the stencil to fill the volume

        # Convert model to stencil
        polyToStencil = vtk.vtkPolyDataToImageStencil()
        polyToStencil.SetInputConnection(transformModelToIjk.GetOutputPort())
        polyToStencil.SetOutputSpacing(inputVolume.GetImageData().GetSpacing())
        polyToStencil.SetOutputOrigin(inputVolume.GetImageData().GetOrigin())
        polyToStencil.SetOutputWholeExtent(
            inputVolume.GetImageData().GetExtent())

        # Apply the stencil to the volume
        stencilToImage = vtk.vtkImageStencil()
        stencilToImage.SetInputConnection(inputVolume.GetImageDataConnection())
        stencilToImage.SetStencilConnection(polyToStencil.GetOutputPort())

        # Create a copy of the input volume to work on
        outputImageData = vtk.vtkImageData()
        outputImageData.DeepCopy(inputVolume.GetImageData())
        outputVolume.SetAndObserveImageData(outputImageData)
        outputVolume.SetIJKToRASMatrix(ijkToRas)

        # Update volume with the stencil operation result depending on user choices
        if clipOutsideSurface:
            stencilToImage.ReverseStencilOff()
            stencilToImage.SetBackgroundValue(fillOutsideValue)
            stencilToImage.Update()
            outputImageData.DeepCopy(stencilToImage.GetOutput())
            outputVolume.SetAndObserveImageData(outputImageData)
            outputVolume.SetIJKToRASMatrix(ijkToRas)

        if clipInsideSurface:
            stencilToImage.SetInputConnection(
                outputVolume.GetImageDataConnection())
            stencilToImage.ReverseStencilOn()
            stencilToImage.SetBackgroundValue(fillInsideValue)
            stencilToImage.Update()
            outputImageData.DeepCopy(stencilToImage.GetOutput())
            outputVolume.SetAndObserveImageData(outputImageData)
            outputVolume.SetIJKToRASMatrix(ijkToRas)

        # Add a default display node to output volume node if it does not exist yet
        if not outputVolume.GetDisplayNode:
            displayNode = slicer.vtkMRMLScalarVolumeDisplayNode()
            displayNode.SetAndObserveColorNodeID("vtkMRMLColorTableNodeGrey")
            slicer.mrmlScene.AddNode(displayNode)
            outputVolume.SetAndObserveDisplayNodeID(displayNode.GetID())

        return True
示例#4
0
  def makeMaskVolumeFromROI(self, refVolumeNode, maskVolumeNode, roiNode):
    # Create a box implicit function that will be used as a stencil to fill the volume

    roiBox = vtk.vtkBox()
    roiCenter = [0, 0, 0]
    roiNode.GetXYZ( roiCenter )
    roiRadius = [0, 0, 0]
    roiNode.GetRadiusXYZ( roiRadius )
    roiBox.SetBounds(roiCenter[0] - roiRadius[0], roiCenter[0] + roiRadius[0], roiCenter[1] - roiRadius[1], roiCenter[1] + roiRadius[1], roiCenter[2] - roiRadius[2], roiCenter[2] + roiRadius[2])

    # Determine the transform between the box and the image IJK coordinate systems

    rasToBox = vtk.vtkMatrix4x4()
    if roiNode.GetTransformNodeID() != None:
      roiBoxTransformNode = slicer.mrmlScene.GetNodeByID(roiNode.GetTransformNodeID())
      boxToRas = vtk.vtkMatrix4x4()
      roiBoxTransformNode.GetMatrixTransformToWorld(boxToRas)
      rasToBox.DeepCopy(boxToRas)
      rasToBox.Invert()

    ijkToRas = vtk.vtkMatrix4x4()
    refVolumeNode.GetIJKToRASMatrix( ijkToRas )

    ijkToBox = vtk.vtkMatrix4x4()
    vtk.vtkMatrix4x4.Multiply4x4(rasToBox,ijkToRas,ijkToBox)
    ijkToBoxTransform = vtk.vtkTransform()
    ijkToBoxTransform.SetMatrix(ijkToBox)
    roiBox.SetTransform(ijkToBoxTransform)

    # Use the stencil to fill the volume

    imageData = vtk.vtkImageData()
    refImageData = refVolumeNode.GetImageData()
    imageData.SetOrigin(refImageData.GetOrigin())
    imageData.SetSpacing(refImageData.GetSpacing())
    
    if vtk.VTK_MAJOR_VERSION <= 5:
      imageData.SetExtent(refImageData.GetWholeExtent())
      imageData.SetScalarTypeToUnsignedChar()
      imageData.AllocateScalars()
    else:
      imageData.SetExtent(refImageData.GetExtent())
      imageData.AllocateScalars(vtk.VTK_UNSIGNED_CHAR,1)

    # Convert the implicit function to a stencil
    functionToStencil = vtk.vtkImplicitFunctionToImageStencil()
    functionToStencil.SetInput(roiBox)
    functionToStencil.SetOutputOrigin(refImageData.GetOrigin())
    functionToStencil.SetOutputSpacing(refImageData.GetSpacing())    
    if vtk.VTK_MAJOR_VERSION <= 5:
      functionToStencil.SetOutputWholeExtent(refImageData.GetWholeExtent())
    else:
      functionToStencil.SetOutputWholeExtent(refImageData.GetExtent())
    functionToStencil.Update()

    # Apply the stencil to the volume
    stencilToImage=vtk.vtkImageStencil()
    if vtk.VTK_MAJOR_VERSION <= 5:
      stencilToImage.SetInput(imageData)
      stencilToImage.SetStencil(functionToStencil.GetOutput())
    else:
      stencilToImage.SetInputData(imageData)    
      stencilToImage.SetStencilData(functionToStencil.GetOutput())
    stencilToImage.ReverseStencilOn()
    stencilToImage.SetBackgroundValue(1)
    stencilToImage.Update()

    # Update the volume with the stencil operation result
    maskVolumeNode.SetAndObserveImageData(stencilToImage.GetOutput())
    maskVolumeNode.CopyOrientation(refVolumeNode)
示例#5
0
  def PolyDataToImageData(self, inputPolydata_Ras, referenceVolumeNode_Ras, inVal=100, outVal=0):
    """ We take in an polydata and convert it to an new image data , withing the Reference Voulume node
        the reference volume node is cleared with a threshold because originally the volume may contain
        alot of noisy pixels 
        PARAM: inputPolydata_Ras: Polydata we are looking to conver       vtkPolydata()
        PARAM: refernceVolumeNode_Ras                                     vtkMRMLScalarVolumeNode()
        RETURN : vtkImageData
        """
    
    """ Transform the polydata from ras to ijk using the referenceVolumeNode """
    #inputPolydataTriangulated_Ijk=polyToImage.GetOutput()
    transformPolydataFilter=vtk.vtkTransformPolyDataFilter()
    rasToIjkMatrix=vtk.vtkMatrix4x4()
    referenceVolumeNode_Ras.GetRASToIJKMatrix(rasToIjkMatrix)
    rasToIjkTransform = vtk.vtkTransform()
    rasToIjkTransform.SetMatrix(rasToIjkMatrix)
    transformPolydataFilter.SetTransform(rasToIjkTransform)
    transformPolydataFilter.SetInputData(inputPolydata_Ras)
    transformPolydataFilter.Update()
    inputPolydata_Ijk=transformPolydataFilter.GetOutput()
    normalsFunction=vtk.vtkPolyDataNormals()
    normalsFunction.SetInputData(inputPolydata_Ijk)
    normalsFunction.ConsistencyOn()
    trigFilter=vtk.vtkTriangleFilter()
    trigFilter.SetInputConnection(normalsFunction.GetOutputPort())
    stripper=vtk.vtkStripper()
    stripper.SetInputConnection(trigFilter.GetOutputPort())
    stripper.Update()
    inputPolydataTriangulated_Ijk=stripper.GetOutput()
    
    # Clone reference image and clear it
    referenceImage_Ijk = referenceVolumeNode_Ras.GetImageData()
    
    # Fill image with outVal (there is no volume Fill filter in VTK, therefore we need to use threshold filter)
    thresh = vtk.vtkImageThreshold()
    thresh.ReplaceInOn()
    thresh.ReplaceOutOn()
    thresh.SetInValue(outVal)
    thresh.SetOutValue(outVal)
    #thresh.SetOutputScalarType (vtk.VTK_UNSIGNED_CHAR)
    thresh.SetInputData(referenceImage_Ijk)
    thresh.Update()
    whiteImage_Ijk = thresh.GetOutput()

    # Convert polydata to stencil
    polyToImage = vtk.vtkPolyDataToImageStencil()
    polyToImage.SetInputData(inputPolydataTriangulated_Ijk)
    polyToImage.SetOutputSpacing(whiteImage_Ijk.GetSpacing())
    polyToImage.SetOutputOrigin(whiteImage_Ijk.GetOrigin())
    polyToImage.SetOutputWholeExtent(whiteImage_Ijk.GetExtent())
    polyToImage.Update()
    imageStencil_Ijk=polyToImage.GetOutput()
    
    # Convert stencil to image
    imgstenc = vtk.vtkImageStencil()
    imgstenc.SetInputData(whiteImage_Ijk)
    imgstenc.SetStencilData(imageStencil_Ijk)
    imgstenc.ReverseStencilOn()
    imgstenc.SetBackgroundValue(inVal)
    imgstenc.Update()
    return imgstenc.GetOutput()
示例#6
0
    def PolyDataToImageData(self,
                            inputPolydata_Ras,
                            referenceVolumeNode_Ras,
                            inVal=100,
                            outVal=0):
        """ We take in an polydata and convert it to an new image data , withing the Reference Voulume node
        the reference volume node is cleared with a threshold because originally the volume may contain
        alot of noisy pixels 
        PARAM: inputPolydata_Ras: Polydata we are looking to conver       vtkPolydata()
        PARAM: refernceVolumeNode_Ras                                     vtkMRMLScalarVolumeNode()
        RETURN : vtkImageData
        """
        """ Transform the polydata from ras to ijk using the referenceVolumeNode """
        #inputPolydataTriangulated_Ijk=polyToImage.GetOutput()
        transformPolydataFilter = vtk.vtkTransformPolyDataFilter()
        rasToIjkMatrix = vtk.vtkMatrix4x4()
        referenceVolumeNode_Ras.GetRASToIJKMatrix(rasToIjkMatrix)
        rasToIjkTransform = vtk.vtkTransform()
        rasToIjkTransform.SetMatrix(rasToIjkMatrix)
        transformPolydataFilter.SetTransform(rasToIjkTransform)
        transformPolydataFilter.SetInputData(inputPolydata_Ras)
        transformPolydataFilter.Update()
        inputPolydata_Ijk = transformPolydataFilter.GetOutput()
        normalsFunction = vtk.vtkPolyDataNormals()
        normalsFunction.SetInputData(inputPolydata_Ijk)
        normalsFunction.ConsistencyOn()
        trigFilter = vtk.vtkTriangleFilter()
        trigFilter.SetInputConnection(normalsFunction.GetOutputPort())
        stripper = vtk.vtkStripper()
        stripper.SetInputConnection(trigFilter.GetOutputPort())
        stripper.Update()
        inputPolydataTriangulated_Ijk = stripper.GetOutput()

        # Clone reference image and clear it
        referenceImage_Ijk = referenceVolumeNode_Ras.GetImageData()

        # Fill image with outVal (there is no volume Fill filter in VTK, therefore we need to use threshold filter)
        thresh = vtk.vtkImageThreshold()
        thresh.ReplaceInOn()
        thresh.ReplaceOutOn()
        thresh.SetInValue(outVal)
        thresh.SetOutValue(outVal)
        #thresh.SetOutputScalarType (vtk.VTK_UNSIGNED_CHAR)
        thresh.SetInputData(referenceImage_Ijk)
        thresh.Update()
        whiteImage_Ijk = thresh.GetOutput()

        # Convert polydata to stencil
        polyToImage = vtk.vtkPolyDataToImageStencil()
        polyToImage.SetInputData(inputPolydataTriangulated_Ijk)
        polyToImage.SetOutputSpacing(whiteImage_Ijk.GetSpacing())
        polyToImage.SetOutputOrigin(whiteImage_Ijk.GetOrigin())
        polyToImage.SetOutputWholeExtent(whiteImage_Ijk.GetExtent())
        polyToImage.Update()
        imageStencil_Ijk = polyToImage.GetOutput()

        # Convert stencil to image
        imgstenc = vtk.vtkImageStencil()
        imgstenc.SetInputData(whiteImage_Ijk)
        imgstenc.SetStencilData(imageStencil_Ijk)
        imgstenc.ReverseStencilOn()
        imgstenc.SetBackgroundValue(inVal)
        imgstenc.Update()
        return imgstenc.GetOutput()
示例#7
0
    def createSyntheticMask(self, maskVolumeNode, radius):
        """
    Run the actual algorithm
    """

        roiSphere = vtk.vtkSphere()
        roiCenter = [0, 0, 0]
        roiOrigin = [0, 0, 0]
        roiSpacing = [1, 1, 1]
        roiDimension = [100, 100, 100]
        # roiDimension = refVolumeNode.GetImageData().GetDimensions()
        roiCenter[0] = roiOrigin[0] + roiDimension[0] * roiSpacing[0] / 2
        roiCenter[1] = roiOrigin[1] + roiDimension[1] * roiSpacing[1] / 2
        roiCenter[2] = roiOrigin[2] + roiDimension[2] * roiSpacing[2] / 2
        print "roiCenter", roiCenter
        """
    ijkToRas = vtk.vtkMatrix4x4()
    refVolumeNode.GetIJKToRASMatrix( ijkToRas )
    roiPoint = [0,0,0,1];
    roiPoint[0] = roiCenter[0]
    roiPoint[1] = roiCenter[1]
    roiPoint[2] = roiCenter[2]
    roiPoint = ijkToRas.MultiplyPoint(roiPoint)
    roiCenter[0] = roiPoint[0]
    roiCenter[1] = roiPoint[1]
    roiCenter[2] = roiPoint[2]

    print "roiCenter", roiCenter
    """

        roiSphere.SetCenter(roiCenter)
        roiSphere.SetRadius(radius)

        # Determine the transform between the box and the image IJK coordinate systems

        rasToSphere = vtk.vtkMatrix4x4()
        # if roiNode.GetTransformNodeID() != None:
        # roiSphereTransformNode = slicer.mrmlScene.GetNodeByID(roiNode.GetTransformNodeID())
        # sphereToRas = vtk.vtkMatrix4x4()
        # roiSphereTransformNode.GetMatrixTransformToWorld(sphereToRas)
        # rasToSphere.DeepCopy(sphereToRas)
        # rasToSphere.Invert()
        """
    ijkToSphere = vtk.vtkMatrix4x4()
    vtk.vtkMatrix4x4.Multiply4x4(rasToSphere,ijkToRas,ijkToSphere)
    ijkToSphereTransform = vtk.vtkTransform()
    ijkToSphereTransform.SetMatrix(ijkToSphere)
    roiSphere.SetTransform(ijkToSphereTransform)

    # Use the stencil to fill the volume
    refImageData = refVolumeNode.GetImageData()
    """

        imageSource = vtk.vtkImageNoiseSource()
        imageSource.SetMinimum(0)
        imageSource.SetMaximum(0)
        imageSource.SetWholeExtent(0, roiDimension[0] - 1, 0,
                                   roiDimension[1] - 1, 0, roiDimension[2] - 1)
        imageSource.Update()

        imageCast = vtk.vtkImageCast()
        imageCast.SetInputData(imageSource.GetOutput())
        imageCast.SetOutputScalarTypeToUnsignedChar()
        imageCast.Update()
        """
    changeInfo = vtk.vtkImageChangeInformation()
    changeInfo.SetInputData(imageCast.GetOutput())
    changeInfo.SetOutputOrigin(refImageData.GetOrigin())
    changeInfo.SetOutputSpacing(refImageData.GetSpacing())
    changeInfo.Update()
    """

        # Convert the implicit function to a stencil
        functionToStencil = vtk.vtkImplicitFunctionToImageStencil()
        functionToStencil.SetInput(roiSphere)
        functionToStencil.SetOutputOrigin(0, 0, 0)
        functionToStencil.SetOutputSpacing(1, 1, 1)
        functionToStencil.SetOutputWholeExtent(0, roiDimension[0] - 1, 0,
                                               roiDimension[1] - 1, 0,
                                               roiDimension[2] - 1)
        functionToStencil.Update()

        # Apply the stencil to the volume
        stencilToImage = vtk.vtkImageStencil()
        stencilToImage.SetInputData(imageCast.GetOutput())
        stencilToImage.SetStencilData(functionToStencil.GetOutput())
        stencilToImage.ReverseStencilOn()
        stencilToImage.SetBackgroundValue(1)
        stencilToImage.Update()
        """
    extent = refImageData.GetWholeExtent()
    resample = vtk.vtkImageReslice()
    resample.SetInputData(stencilToImage.GetOutput())
    resample.SetOutputOrigin(refImageData.GetOrigin())
    resample.SetOutputSpacing(refImageData.GetSpacing()[0]/2, refImageData.GetSpacing()[1]/2, refImageData.GetSpacing()[2]/2 )
    resample.SetOutputExtent(extent[0], (extent[1]-extent[0])*2-1, 
                             extent[2], (extent[3]-extent[2])*2-1, 
                             extent[4], (extent[5]-extent[4])*2-1)
                             
    resample.Update()
    
    changeInfo2 = vtk.vtkImageChangeInformation()
    changeInfo2.SetInputData(resample.GetOutput())
    changeInfo2.SetOutputOrigin(refImageData.GetOrigin())
    changeInfo2.SetOutputSpacing(refImageData.GetSpacing())
    changeInfo2.Update()
    """

        # Update the volume with the stencil operation result
        maskVolumeNode.SetAndObserveImageData(stencilToImage.GetOutput())
        maskVolumeNode.SetOrigin(0, 0, 0)
        maskVolumeNode.SetSpacing(1, 1, 1)
        # maskVolumeNode.CopyOrientation(refVolumeNode)
        mgr = slicer.app.layoutManager()
        mgr.sliceWidget(
            'Red').sliceLogic().GetSliceCompositeNode().SetLabelVolumeID(
                maskVolumeNode.GetID())
        mgr.sliceWidget(
            'Yellow').sliceLogic().GetSliceCompositeNode().SetLabelVolumeID(
                maskVolumeNode.GetID())
        mgr.sliceWidget(
            'Green').sliceLogic().GetSliceCompositeNode().SetLabelVolumeID(
                maskVolumeNode.GetID())
示例#8
0
    def clipImageWithPolyData(self,
                              inputImageData,
                              outputImageData,
                              clippingPolyData,
                              rasToModel,
                              inputIjkToRas,
                              outputIjkToRas,
                              clipOutsideSurface=True,
                              fillValue=0,
                              reduceExtent=False):
        """
    Fill voxels of the input volume inside/outside the clipping model with the provided fill value
    If reduceExtent is True then the extent of the volume will be reduced to the smallest possible box that still contains all the non-zero voxels.
    """

        # Determine the transform between the box and the image IJK coordinate systems

        ijkToModel = vtk.vtkMatrix4x4()
        vtk.vtkMatrix4x4.Multiply4x4(rasToModel, inputIjkToRas, ijkToModel)
        modelToIjkTransform = vtk.vtkTransform()
        modelToIjkTransform.SetMatrix(ijkToModel)
        modelToIjkTransform.Inverse()

        transformModelToIjk = vtk.vtkTransformPolyDataFilter()
        transformModelToIjk.SetTransform(modelToIjkTransform)
        transformModelToIjk.SetInputData(clippingPolyData)

        # Use the stencil to fill the volume

        # Convert model to stencil
        polyToStencil = vtk.vtkPolyDataToImageStencil()
        polyToStencil.SetInputConnection(transformModelToIjk.GetOutputPort())
        polyToStencil.SetOutputSpacing(inputImageData.GetSpacing())
        polyToStencil.SetOutputOrigin(inputImageData.GetOrigin())
        polyToStencil.SetOutputWholeExtent(inputImageData.GetExtent())

        # Apply the stencil to the volume
        stencilToImage = vtk.vtkImageStencil()
        stencilToImage.SetInputData(inputImageData)
        stencilToImage.SetStencilConnection(polyToStencil.GetOutputPort())
        if clipOutsideSurface:
            stencilToImage.ReverseStencilOff()
        else:
            stencilToImage.ReverseStencilOn()
        stencilToImage.SetBackgroundValue(fillValue)
        stencilToImage.Update()

        # Update the volume with the stencil operation result
        if reduceExtent:

            clippingPolyDataBounds_Ijk = [0, 0, 0, 0, 0, 0]
            transformModelToIjk.GetOutput().GetBounds(
                clippingPolyDataBounds_Ijk)
            inputVolumeExtent_Ijk = inputImageData.GetExtent()
            outputVolumeExtent_Ijk = list(inputVolumeExtent_Ijk)  # make a copy
            for i in range(3):
                a = int(math.floor(clippingPolyDataBounds_Ijk[i * 2]))
                if a > outputVolumeExtent_Ijk[i * 2]:
                    outputVolumeExtent_Ijk[i * 2] = a
                b = int(math.ceil(clippingPolyDataBounds_Ijk[i * 2 + 1]))
                if b < outputVolumeExtent_Ijk[i * 2 + 1]:
                    outputVolumeExtent_Ijk[i * 2 + 1] = b

            clipper = vtk.vtkImageClip()
            clipper.SetOutputWholeExtent(outputVolumeExtent_Ijk)
            clipper.ClipDataOn()
            clipper.SetInputConnection(stencilToImage.GetOutputPort())
            clipper.Update()
            outputImageData.DeepCopy(clipper.GetOutput())

            # Offset the extent to start at [0,0,0]
            # (maybe this is not needed, but we do it because some code may assume the image extent starts from zero)
            outputVolumeExtent_Ijk = list(outputImageData.GetExtent())
            outputIjkToInputIjk = vtk.vtkMatrix4x4()
            for i in range(3):
                outputVolumeExtentOffset = outputVolumeExtent_Ijk[i * 2]
                outputVolumeExtent_Ijk[i * 2] = outputVolumeExtent_Ijk[
                    i * 2] - outputVolumeExtentOffset
                outputVolumeExtent_Ijk[i * 2 + 1] = outputVolumeExtent_Ijk[
                    i * 2 + 1] - outputVolumeExtentOffset
                outputIjkToInputIjk.SetElement(i, 3, outputVolumeExtentOffset)
            outputImageData.SetExtent(outputVolumeExtent_Ijk)
            vtk.vtkMatrix4x4.Multiply4x4(inputIjkToRas, outputIjkToInputIjk,
                                         outputIjkToRas)

        else:

            outputImageData.DeepCopy(stencilToImage.GetOutput())
            outputIjkToRas.DeepCopy(inputIjkToRas)
示例#9
0
    def roiSegment(self, inputSelector, seedingSelector, seedingBSelector,
                   labelmapSelector):
        ##########################
        ## read input volume node
        ####
        inputVolume = inputSelector.currentNode()
        # extract array
        inputVolumeData = slicer.util.array(inputVolume.GetID())
        # input label map
        labelMap = labelmapSelector.currentNode()

        ##########################
        ## read seeding ROI
        ####
        seedingROI = seedingSelector
        boundROI = seedingBSelector

        # center and radius of foreground seeding points
        seedingROIcenter = [0, 0, 0]
        seedingROIRadius = [0, 0, 0]
        seedingROI.GetXYZ(seedingROIcenter)
        seedingROI.GetRadiusXYZ(seedingROIRadius)
        roiSBox = vtk.vtkBox()
        roiSBox.SetBounds(seedingROIcenter[0] - seedingROIRadius[0],
                          seedingROIcenter[0] + seedingROIRadius[0],
                          seedingROIcenter[1] - seedingROIRadius[1],
                          seedingROIcenter[1] + seedingROIRadius[1],
                          seedingROIcenter[2] - seedingROIRadius[2],
                          seedingROIcenter[2] + seedingROIRadius[2])

        # center and radius of bounding box
        boundROIcenter = [0, 0, 0]
        boundROIRadius = [0, 0, 0]
        boundROI.GetXYZ(boundROIcenter)
        boundROI.GetRadiusXYZ(boundROIRadius)
        roiBBox = vtk.vtkBox()
        roiBBox.SetBounds(boundROIcenter[0] - boundROIRadius[0],
                          boundROIcenter[0] + boundROIRadius[0],
                          boundROIcenter[1] - boundROIRadius[1],
                          boundROIcenter[1] + boundROIRadius[1],
                          boundROIcenter[2] - boundROIRadius[2],
                          boundROIcenter[2] + boundROIRadius[2])

        # transform between ijk and ras
        rasToBox = vtk.vtkMatrix4x4()
        if boundROI.GetTransformNodeID() != None:
            roiBoxTransformNode = slicer.mrmlScene.GetNodeByID(
                boundROI.GetTransformNodeID())
            boxToRas = vtk.vtkMatrix4x4()
            roiBoxTransformNode.GetMatrixTransformToWorld(boxToRas)
            rasToBox.DeepCopy(boxToRas)
            rasToBox.Invert()

        rasToSBox = vtk.vtkMatrix4x4()
        if seedingROI.GetTransformNodeID() != None:
            seedingBoxTransformNode = slicer.mrmlScene.GetNodeByID(
                seedingROI.GetTransformNodeID())
            sboxToRas = vtk.vtkMatrix4x4()
            seedingBoxTransformNode.GetMatrixTransformToWorld(sboxToRas)
            rasToSBox.DeepCopy(sboxToRas)
            rasToSBox.Invert()

        ijkToRas = vtk.vtkMatrix4x4()
        labelMap.GetIJKToRASMatrix(ijkToRas)

        ijkToBox = vtk.vtkMatrix4x4()
        ijkToSBox = vtk.vtkMatrix4x4()
        vtk.vtkMatrix4x4.Multiply4x4(rasToBox, ijkToRas, ijkToBox)
        vtk.vtkMatrix4x4.Multiply4x4(rasToSBox, ijkToRas, ijkToSBox)
        ijkToBoxTransform = vtk.vtkTransform()
        ijkToBoxTransform.SetMatrix(ijkToBox)
        roiBBox.SetTransform(ijkToBoxTransform)
        ijkToBoxTransform.SetMatrix(ijkToSBox)
        roiSBox.SetTransform(ijkToBoxTransform)

        imageData = labelMap.GetImageData()

        # show boudning area and seeding area in label map
        # label the bounding region
        functionToStencil = vtk.vtkImplicitFunctionToImageStencil()
        functionToStencil.SetInput(roiBBox)
        functionToStencil.SetOutputOrigin(imageData.GetOrigin())
        functionToStencil.SetOutputSpacing(imageData.GetSpacing())
        functionToStencil.SetOutputWholeExtent(imageData.GetExtent())
        functionToStencil.Update()

        stencilToImage = vtk.vtkImageStencil()
        stencilToImage.SetInputData(imageData)
        stencilToImage.SetStencilData(functionToStencil.GetOutput())
        stencilToImage.ReverseStencilOn()
        stencilToImage.SetBackgroundValue(2.00)  # set background label to 2
        stencilToImage.Update()
        imageData.DeepCopy(stencilToImage.GetOutput())

        # label the seeding region
        functionToStencil = vtk.vtkImplicitFunctionToImageStencil()
        functionToStencil.SetInput(roiSBox)
        functionToStencil.SetOutputOrigin(imageData.GetOrigin())
        functionToStencil.SetOutputSpacing(imageData.GetSpacing())
        functionToStencil.SetOutputWholeExtent(imageData.GetExtent())
        functionToStencil.Update()

        stencilToImage = vtk.vtkImageStencil()
        stencilToImage.SetInputData(imageData)
        stencilToImage.SetStencilData(functionToStencil.GetOutput())
        stencilToImage.ReverseStencilOn()
        stencilToImage.SetBackgroundValue(3.00)
        stencilToImage.Update()
        imageData.DeepCopy(stencilToImage.GetOutput())

        # update label map
        labelMap.Modified()

        ##########################
        ## output label map
        ####
        labelMapData = slicer.util.array(labelMap.GetID())

        ##########################
        ## segmentation
        ####
        #determine threshold from seeding points
        s = np.where(labelMapData == 3)  # get seeding points location
        threshold = np.median(inputVolumeData[s[0], s[1], s[2]])

        # check voxels within the bounding region
        t = np.where(np.logical_or(labelMapData == 2, labelMapData == 3))
        for w in range(len(t[0])):
            i = t[0][w]
            j = t[1][w]
            k = t[2][w]
            if (inputVolumeData[i, j, k] < threshold + 50) and (
                    inputVolumeData[i, j, k] > threshold - 30):
                labelMapData[i, j, k] = 1

        #######################################################
        # set background to zero
        labelMapData[labelMapData != 1] = 0