def ClipData(self, ROI, noisySurfacePolyData):
        """ Returns the clipped polydata from the region defined by the ROI
    Turn on the Debug to make the clipped object appear, 
    For specific filter functionality see DataFlow doc: ClipData.pdf
    """
        connectivityFilter = vtk.vtkPolyDataConnectivityFilter()
        self.utility.PolyDataWriter(
            noisySurfacePolyData, "C:\\MakeHDRApplicatorMask\\doc\\" + "DebugPolyData\\PreClipped.vtk"
        )
        connectivityFilter.SetInputData(noisySurfacePolyData)
        connectivityFilter.SetExtractionModeToLargestRegion()
        connectivityFilter.Update()
        self.skinSurface = connectivityFilter.GetOutput()  # skinSurface Set
        if self.DEBUG_CONNECTIVITYFACE:
            self.utility.DisplayPolyData("ConnectedFace", self.skinSurface)
        # Expansion of ROI is explained in vtkImplicitModeller limitations
        ROIExtents = self.utility.GetROIExtents(ROI)
        BiggerROI = self.utility.ExpandExtents(ROIExtents, 0.5)
        # See vtkImplicitModdeler limitations.pdf for explanation
        implicitBoxRegion = vtk.vtkBox()
        implicitBoxRegion.SetBounds(BiggerROI)

        clipper = vtk.vtkClipPolyData()
        clipper.InsideOutOn()  # Clip the regions outside of implicit function
        clipper.SetInputConnection(connectivityFilter.GetOutputPort())
        clipper.SetClipFunction(implicitBoxRegion)
        clipper.Update()
        self.clippedSurface = clipper.GetOutput()
        return clipper
Example #2
0
    def cropScrew(self,input, area):
        #Get bounds of screw 
        bounds = input.GetPolyData().GetBounds()
        print bounds
        
        #Define bounds for cropping out the head or shaft of the screw respectively
        if area == 'head':
            i = bounds[2]
            j = bounds[3]-17
        elif area == 'shaft':
            i = bounds[3]-17
            j = bounds[3]

        #Create a box with bounds equal to that of the screw minus the head (-17)
        cropBox = vtk.vtkBox()
        cropBox.SetBounds(bounds[0],bounds[1],i,j,bounds[4],bounds[5])
        
        #Crop out head of screw
        extract = vtk.vtkExtractPolyDataGeometry()
        extract.SetImplicitFunction(cropBox)
        extract.SetInput(input.GetPolyData())
        extract.Update()
        
        #PolyData of cropped screw
        output = extract.GetOutput()
        return output
    def cropScrew(self, input, area):
        #Get bounds of screw
        bounds = input.GetPolyData().GetBounds()
        logging.debug(bounds)

        #Define bounds for cropping out the head or shaft of the screw respectively
        if area == 'head':
            i = bounds[2]
            j = bounds[3] - 17
        elif area == 'shaft':
            i = bounds[3] - 17
            j = bounds[3]

        #Create a box with bounds equal to that of the screw minus the head (-17)
        cropBox = vtk.vtkBox()
        cropBox.SetBounds(bounds[0], bounds[1], i, j, bounds[4], bounds[5])

        #Crop out head of screw
        extract = vtk.vtkExtractPolyDataGeometry()
        extract.SetImplicitFunction(cropBox)
        extract.SetInputData(input.GetPolyData())
        extract.Update()

        #PolyData of cropped screw
        output = extract.GetOutput()
        return output
Example #4
0
    def ClipData(self, ROI, noisySurfacePolyData):
        """ Returns the clipped polydata from the region defined by the ROI
    Turn on the Debug to make the clipped object appear, 
    For specific filter functionality see DataFlow doc: ClipData.pdf
    """
        connectivityFilter = vtk.vtkPolyDataConnectivityFilter()
        self.utility.PolyDataWriter(noisySurfacePolyData,
                                    "C:\\MakeHDRApplicatorMask\\doc\\"+\
                                    "DebugPolyData\\PreClipped.vtk")
        connectivityFilter.SetInputData(noisySurfacePolyData)
        connectivityFilter.SetExtractionModeToLargestRegion()
        connectivityFilter.Update()
        self.skinSurface = connectivityFilter.GetOutput()  #skinSurface Set
        if self.DEBUG_CONNECTIVITYFACE:
            self.utility.DisplayPolyData("ConnectedFace", self.skinSurface)
        # Expansion of ROI is explained in vtkImplicitModeller limitations
        ROIExtents = self.utility.GetROIExtents(ROI)
        BiggerROI = self.utility.ExpandExtents(ROIExtents, .5)
        #See vtkImplicitModdeler limitations.pdf for explanation
        implicitBoxRegion = vtk.vtkBox()
        implicitBoxRegion.SetBounds(BiggerROI)

        clipper = vtk.vtkClipPolyData()
        clipper.InsideOutOn()  # Clip the regions outside of implicit function
        clipper.SetInputConnection(connectivityFilter.GetOutputPort())
        clipper.SetClipFunction(implicitBoxRegion)
        clipper.Update()
        self.clippedSurface = clipper.GetOutput()
        return clipper
Example #5
0
    def MinimumDistanceMask(self,
                            vtkAlgorythmObject,
                            distanceFromMask,
                            ROI,
                            ruler,
                            isBubble=False):
        """ Takes an algorythm object which is will send through a pipeline to 
    create a mask defining the minimum distance value from the skin surface
    returns an algorythm object as well to preform GetOutput() -> polydata
    or GetOutputPort() -> algorythm
    see MinimumDistanceMask.pdf 
    """
        if distanceFromMask < 2:
            print "WARNING: MouldLogic: MinimumDistanceMask implicit",
            "modeling is very unstable below 1.5 , mask may degrade",
            "and lines will become discontinuous."
        Extents = self.utility.GetROIExtents(ROI)
        if (isBubble):
            Extents = self.utility.ExpandExtents(Extents, 100)
        implicitModeller = vtk.vtkImplicitModeller()
        implicitModeller.SetInputConnection(vtkAlgorythmObject.GetOutputPort())
        implicitModeller.SetMaximumDistance(distanceFromMask)
        implicitModeller.SetModelBounds(Extents)
        implicitModeller.AdjustBoundsOn()
        implicitModeller.SetAdjustBounds(10)  # Removes the boundary effects
        implicitModeller.CappingOff(
        )  # Important to create disjoint inner and outer masks
        implicitModeller.SetProcessModeToPerVoxel()
        implicitModeller.Update()

        contourFilter = vtk.vtkContourFilter()
        contourFilter.SetValue(0, distanceFromMask)
        contourFilter.SetInputConnection(implicitModeller.GetOutputPort())
        contourFilter.Update()

        normalsFunction = vtk.vtkPolyDataNormals()
        normalsFunction.FlipNormalsOn()
        normalsFunction.AddInputConnection(contourFilter.GetOutputPort())
        normalsFunction.Update()

        implicitBoxRegion = vtk.vtkBox()
        implicitBoxRegion.SetBounds(Extents)
        clipper2 = vtk.vtkClipPolyData()
        clipper2.InsideOutOn()  # Clip the regions outside of implicit function
        clipper2.SetInputConnection(normalsFunction.GetOutputPort())
        clipper2.SetClipFunction(implicitBoxRegion)
        clipper2.Update()

        closestPoint = [0, 0, 0]
        ruler.GetPosition1(closestPoint)
        connectivityFilter = vtk.vtkPolyDataConnectivityFilter()
        connectivityFilter.SetInputConnection(clipper2.GetOutputPort())
        connectivityFilter.SetExtractionModeToClosestPointRegion()
        connectivityFilter.SetClosestPoint(closestPoint)
        connectivityFilter.Update()

        return connectivityFilter.GetOutput()
    def MinimumDistanceMask(self, vtkAlgorythmObject, distanceFromMask, ROI, ruler, isBubble=False):
        """ Takes an algorythm object which is will send through a pipeline to 
    create a mask defining the minimum distance value from the skin surface
    returns an algorythm object as well to preform GetOutput() -> polydata
    or GetOutputPort() -> algorythm
    see MinimumDistanceMask.pdf 
    """
        if distanceFromMask < 2:
            print "WARNING: MouldLogic: MinimumDistanceMask implicit",
            "modeling is very unstable below 1.5 , mask may degrade",
            "and lines will become discontinuous."
        Extents = self.utility.GetROIExtents(ROI)
        if isBubble:
            Extents = self.utility.ExpandExtents(Extents, 100)
        implicitModeller = vtk.vtkImplicitModeller()
        implicitModeller.SetInputConnection(vtkAlgorythmObject.GetOutputPort())
        implicitModeller.SetMaximumDistance(distanceFromMask)
        implicitModeller.SetModelBounds(Extents)
        implicitModeller.AdjustBoundsOn()
        implicitModeller.SetAdjustBounds(10)  # Removes the boundary effects
        implicitModeller.CappingOff()  # Important to create disjoint inner and outer masks
        implicitModeller.SetProcessModeToPerVoxel()
        implicitModeller.Update()

        contourFilter = vtk.vtkContourFilter()
        contourFilter.SetValue(0, distanceFromMask)
        contourFilter.SetInputConnection(implicitModeller.GetOutputPort())
        contourFilter.Update()

        normalsFunction = vtk.vtkPolyDataNormals()
        normalsFunction.FlipNormalsOn()
        normalsFunction.AddInputConnection(contourFilter.GetOutputPort())
        normalsFunction.Update()

        implicitBoxRegion = vtk.vtkBox()
        implicitBoxRegion.SetBounds(Extents)
        clipper2 = vtk.vtkClipPolyData()
        clipper2.InsideOutOn()  # Clip the regions outside of implicit function
        clipper2.SetInputConnection(normalsFunction.GetOutputPort())
        clipper2.SetClipFunction(implicitBoxRegion)
        clipper2.Update()

        closestPoint = [0, 0, 0]
        ruler.GetPosition1(closestPoint)
        connectivityFilter = vtk.vtkPolyDataConnectivityFilter()
        connectivityFilter.SetInputConnection(clipper2.GetOutputPort())
        connectivityFilter.SetExtractionModeToClosestPointRegion()
        connectivityFilter.SetClosestPoint(closestPoint)
        connectivityFilter.Update()

        return connectivityFilter.GetOutput()
    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())
Example #8
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)
Example #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