コード例 #1
4
  def removeIslands(self):
    #
    # change the label values based on the parameter node
    #
    if not self.sliceLogic:
      self.sliceLogic = self.editUtil.getSliceLogic()
    parameterNode = self.editUtil.getParameterNode()
    minimumSize = int(parameterNode.GetParameter("IslandEffect,minimumSize"))
    fullyConnected = bool(parameterNode.GetParameter("IslandEffect,fullyConnected"))
    label = self.editUtil.getLabel()

    # first, create an inverse binary version of the image
    # so that islands inside segemented object will be detected, along
    # with a big island of the background
    preThresh = vtk.vtkImageThreshold()
    preThresh.SetInValue( 0 )
    preThresh.SetOutValue( 1 )
    preThresh.ReplaceInOn()
    preThresh.ReplaceOutOn()
    preThresh.ThresholdBetween( label,label )
    preThresh.SetInput( self.getScopedLabelInput() )
    preThresh.SetOutputScalarTypeToUnsignedLong()

    # now identify the islands in the inverted volume
    # and find the pixel that corresponds to the background
    islandMath = vtkITK.vtkITKIslandMath()
    islandMath.SetInput( preThresh.GetOutput() )
    islandMath.SetFullyConnected( fullyConnected )
    islandMath.SetMinimumSize( minimumSize )
    # TODO: $this setProgressFilter $islandMath "Calculating Islands..."
    islandMath.Update()
    islandCount = islandMath.GetNumberOfIslands()
    islandOrigCount = islandMath.GetOriginalNumberOfIslands()
    ignoredIslands = islandOrigCount - islandCount
    print( "%d islands created (%d ignored)" % (islandCount, ignoredIslands) )

    # now rethreshold so that everything which is not background becomes the label
    postThresh = vtk.vtkImageThreshold()
    postThresh.SetInValue( label )
    postThresh.SetOutValue( 0 )
    postThresh.ReplaceInOn()
    postThresh.ReplaceOutOn()
    postThresh.ThresholdBetween( 0, 0 )
    postThresh.SetOutputScalarTypeToShort()
    postThresh.SetInput( islandMath.GetOutput() )
    postThresh.SetOutput( self.getScopedLabelOutput() )
    # TODO $this setProgressFilter $postThresh "Applying to Label Map..."
    postThresh.Update()

    self.applyScopedLabel()
コード例 #2
0
    def onApply(self):
        # This can be a long operation - indicate it to the user
        qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)

        self.scriptedEffect.saveStateForUndo()

        # Get parameters
        fullyConnected = self.scriptedEffect.integerParameter("FullyConnected")
        minimumSize = self.scriptedEffect.integerParameter("MinimumSize")

        # Get modifier labelmap
        selectedSegmentLabelmap = self.scriptedEffect.selectedSegmentLabelmap()

        castIn = vtk.vtkImageCast()
        castIn.SetInputData(selectedSegmentLabelmap)
        castIn.SetOutputScalarTypeToUnsignedLong()

        # Identify the islands in the inverted volume and
        # find the pixel that corresponds to the background
        islandMath = vtkITK.vtkITKIslandMath()
        islandMath.SetInputConnection(castIn.GetOutputPort())
        islandMath.SetFullyConnected(fullyConnected)
        islandMath.SetMinimumSize(minimumSize)

        # Note that island operation happens in unsigned long space
        # but the segment editor works in unsigned char
        castOut = vtk.vtkImageCast()
        castOut.SetInputConnection(islandMath.GetOutputPort())
        castOut.SetOutputScalarTypeToUnsignedChar()
        castOut.Update()

        islandCount = islandMath.GetNumberOfIslands()
        islandOrigCount = islandMath.GetOriginalNumberOfIslands()
        ignoredIslands = islandOrigCount - islandCount
        logging.info("%d islands created (%d ignored)" %
                     (islandCount, ignoredIslands))

        # Create oriented image data from output
        import vtkSegmentationCorePython as vtkSegmentationCore
        multiLabelImage = vtkSegmentationCore.vtkOrientedImageData()
        multiLabelImage.DeepCopy(castOut.GetOutput())
        selectedSegmentLabelmapImageToWorldMatrix = vtk.vtkMatrix4x4()
        selectedSegmentLabelmap.GetImageToWorldMatrix(
            selectedSegmentLabelmapImageToWorldMatrix)
        multiLabelImage.SetGeometryFromImageToWorldMatrix(
            selectedSegmentLabelmapImageToWorldMatrix)

        # Import multi-label labelmap to segmentation
        segmentationNode = self.scriptedEffect.parameterSetNode(
        ).GetSegmentationNode()
        selectedSegmentID = self.scriptedEffect.parameterSetNode(
        ).GetSelectedSegmentID()
        selectedSegmentName = segmentationNode.GetSegmentation().GetSegment(
            selectedSegmentID).GetName()
        slicer.vtkSlicerSegmentationsModuleLogic.ImportLabelmapToSegmentationNode( \
          multiLabelImage, segmentationNode, selectedSegmentName )

        segmentationNode.GetSegmentation().RemoveSegment(selectedSegmentID)

        qt.QApplication.restoreOverrideCursor()
コード例 #3
0
    def onApply(self):
        # TODO:
        # self.logic.undoRedo = self.undoRedo

        # Get parameters
        fullyConnected = self.scriptedEffect.integerParameter("FullyConnected")
        minimumSize = self.scriptedEffect.integerParameter("MinimumSize")

        # Get modifier labelmap
        selectedSegmentLabelmap = self.scriptedEffect.selectedSegmentLabelmap()

        castIn = vtk.vtkImageCast()
        castIn.SetInputData(selectedSegmentLabelmap)
        castIn.SetOutputScalarTypeToUnsignedLong()

        # Identify the islands in the inverted volume and
        # find the pixel that corresponds to the background
        islandMath = vtkITK.vtkITKIslandMath()
        islandMath.SetInputConnection(castIn.GetOutputPort())
        islandMath.SetFullyConnected(fullyConnected)
        islandMath.SetMinimumSize(minimumSize)

        # Note that island operation happens in unsigned long space
        # but the segment editor works in unsigned char
        castOut = vtk.vtkImageCast()
        castOut.SetInputConnection(islandMath.GetOutputPort())
        castOut.SetOutputScalarTypeToUnsignedChar()
        castOut.Update()

        islandCount = islandMath.GetNumberOfIslands()
        islandOrigCount = islandMath.GetOriginalNumberOfIslands()
        ignoredIslands = islandOrigCount - islandCount
        logging.info("%d islands created (%d ignored)" % (islandCount, ignoredIslands))

        # Create oriented image data from output
        import vtkSegmentationCorePython as vtkSegmentationCore

        multiLabelImage = vtkSegmentationCore.vtkOrientedImageData()
        multiLabelImage.DeepCopy(castOut.GetOutput())
        selectedSegmentLabelmapImageToWorldMatrix = vtk.vtkMatrix4x4()
        selectedSegmentLabelmap.GetImageToWorldMatrix(selectedSegmentLabelmapImageToWorldMatrix)
        multiLabelImage.SetGeometryFromImageToWorldMatrix(selectedSegmentLabelmapImageToWorldMatrix)

        # Import multi-label labelmap to segmentation
        segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
        selectedSegmentID = self.scriptedEffect.parameterSetNode().GetSelectedSegmentID()
        selectedSegmentName = segmentationNode.GetSegmentation().GetSegment(selectedSegmentID).GetName()
        slicer.vtkSlicerSegmentationsModuleLogic.ImportLabelmapToSegmentationNode(
            multiLabelImage, segmentationNode, selectedSegmentName
        )

        # Set labelmap visibility to outline for the new segments
        displayNode = segmentationNode.GetDisplayNode()
        # for index in xrange(1,islandCount+1):
        #  segmentID = selectedSegmentName + "_" + str(index)
        #  displayNode.SetSegmentVisibility2DFill(segmentID, False)
        #  displayNode.SetSegmentVisibility2DOutline(segmentID, True)

        displayNode.SetSegmentVisibility(selectedSegmentID, False)
コード例 #4
0
  def onApply(self):
    #TODO:
    #self.logic.undoRedo = self.undoRedo

    # Get parameters
    fullyConnected = self.scriptedEffect.integerParameter("FullyConnected")
    minimumSize = self.scriptedEffect.integerParameter("MinimumSize")

    # Get modifier labelmap
    selectedSegmentLabelmap = self.scriptedEffect.selectedSegmentLabelmap()

    castIn = vtk.vtkImageCast()
    castIn.SetInputData(selectedSegmentLabelmap)
    castIn.SetOutputScalarTypeToUnsignedLong()

    # Identify the islands in the inverted volume and
    # find the pixel that corresponds to the background
    islandMath = vtkITK.vtkITKIslandMath()
    islandMath.SetInputConnection(castIn.GetOutputPort())
    islandMath.SetFullyConnected(fullyConnected)
    islandMath.SetMinimumSize(minimumSize)

    # Note that island operation happens in unsigned long space
    # but the segment editor works in unsigned char
    castOut = vtk.vtkImageCast()
    castOut.SetInputConnection(islandMath.GetOutputPort())
    castOut.SetOutputScalarTypeToUnsignedChar()
    castOut.Update()

    islandCount = islandMath.GetNumberOfIslands()
    islandOrigCount = islandMath.GetOriginalNumberOfIslands()
    ignoredIslands = islandOrigCount - islandCount
    logging.info( "%d islands created (%d ignored)" % (islandCount, ignoredIslands) )

    # Create oriented image data from output
    import vtkSegmentationCorePython as vtkSegmentationCore
    multiLabelImage = vtkSegmentationCore.vtkOrientedImageData()
    multiLabelImage.DeepCopy(castOut.GetOutput())
    selectedSegmentLabelmapImageToWorldMatrix = vtk.vtkMatrix4x4()
    selectedSegmentLabelmap.GetImageToWorldMatrix(selectedSegmentLabelmapImageToWorldMatrix)
    multiLabelImage.SetGeometryFromImageToWorldMatrix(selectedSegmentLabelmapImageToWorldMatrix)

    # Import multi-label labelmap to segmentation
    segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
    selectedSegmentID = self.scriptedEffect.parameterSetNode().GetSelectedSegmentID()
    selectedSegmentName = segmentationNode.GetSegmentation().GetSegment(selectedSegmentID).GetName()
    slicer.vtkSlicerSegmentationsModuleLogic.ImportLabelmapToSegmentationNode( \
      multiLabelImage, segmentationNode, selectedSegmentName )

    # Set labelmap visibility to outline for the new segments
    displayNode = segmentationNode.GetDisplayNode()
    #for index in xrange(1,islandCount+1):
    #  segmentID = selectedSegmentName + "_" + str(index)
    #  displayNode.SetSegmentVisibility2DFill(segmentID, False)
    #  displayNode.SetSegmentVisibility2DOutline(segmentID, True)

    displayNode.SetSegmentVisibility(selectedSegmentID, False)
コード例 #5
0
  def onApply(self):
    # This can be a long operation - indicate it to the user
    qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)

    self.scriptedEffect.saveStateForUndo()

    # Get parameters
    fullyConnected = self.scriptedEffect.integerParameter("FullyConnected")
    minimumSize = self.scriptedEffect.integerParameter("MinimumSize")

    # Get modifier labelmap
    selectedSegmentLabelmap = self.scriptedEffect.selectedSegmentLabelmap()

    castIn = vtk.vtkImageCast()
    castIn.SetInputData(selectedSegmentLabelmap)
    castIn.SetOutputScalarTypeToUnsignedLong()

    # Identify the islands in the inverted volume and
    # find the pixel that corresponds to the background
    islandMath = vtkITK.vtkITKIslandMath()
    islandMath.SetInputConnection(castIn.GetOutputPort())
    islandMath.SetFullyConnected(fullyConnected)
    islandMath.SetMinimumSize(minimumSize)

    # Note that island operation happens in unsigned long space
    # but the segment editor works in unsigned char
    castOut = vtk.vtkImageCast()
    castOut.SetInputConnection(islandMath.GetOutputPort())
    castOut.SetOutputScalarTypeToUnsignedChar()
    castOut.Update()

    islandCount = islandMath.GetNumberOfIslands()
    islandOrigCount = islandMath.GetOriginalNumberOfIslands()
    ignoredIslands = islandOrigCount - islandCount
    logging.info( "%d islands created (%d ignored)" % (islandCount, ignoredIslands) )

    # Create oriented image data from output
    import vtkSegmentationCorePython as vtkSegmentationCore
    multiLabelImage = vtkSegmentationCore.vtkOrientedImageData()
    multiLabelImage.DeepCopy(castOut.GetOutput())
    selectedSegmentLabelmapImageToWorldMatrix = vtk.vtkMatrix4x4()
    selectedSegmentLabelmap.GetImageToWorldMatrix(selectedSegmentLabelmapImageToWorldMatrix)
    multiLabelImage.SetGeometryFromImageToWorldMatrix(selectedSegmentLabelmapImageToWorldMatrix)

    # Import multi-label labelmap to segmentation
    segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
    selectedSegmentID = self.scriptedEffect.parameterSetNode().GetSelectedSegmentID()
    selectedSegmentName = segmentationNode.GetSegmentation().GetSegment(selectedSegmentID).GetName()
    slicer.vtkSlicerSegmentationsModuleLogic.ImportLabelmapToSegmentationNode( \
      multiLabelImage, segmentationNode, selectedSegmentName )

    segmentationNode.GetSegmentation().RemoveSegment(selectedSegmentID)

    qt.QApplication.restoreOverrideCursor()
コード例 #6
0
    def removeIslands(self):
        #
        # change the label values based on the parameter node
        #
        if not self.sliceLogic:
            self.sliceLogic = self.editUtil.getSliceLogic()
        parameterNode = self.editUtil.getParameterNode()
        minimumSize = int(
            parameterNode.GetParameter("IslandEffect,minimumSize"))
        fullyConnected = bool(
            parameterNode.GetParameter("IslandEffect,fullyConnected"))
        label = self.editUtil.getLabel()

        # note that island operation happens in unsigned long space
        # but the slicer editor works in Short
        castIn = vtk.vtkImageCast()
        if vtk.VTK_MAJOR_VERSION <= 5:
            castIn.SetInput(self.getScopedLabelInput())
        else:
            castIn.SetInputData(self.getScopedLabelInput())
        castIn.SetOutputScalarTypeToUnsignedLong()

        # now identify the islands in the inverted volume
        # and find the pixel that corresponds to the background
        islandMath = vtkITK.vtkITKIslandMath()
        if vtk.VTK_MAJOR_VERSION <= 5:
            islandMath.SetInput(castIn.GetOutput())
        else:
            islandMath.SetInputConnection(castIn.GetOutputPort())
        islandMath.SetFullyConnected(fullyConnected)
        islandMath.SetMinimumSize(minimumSize)
        # TODO: $this setProgressFilter $islandMath "Calculating Islands..."

        # note that island operation happens in unsigned long space
        # but the slicer editor works in Short
        castOut = vtk.vtkImageCast()
        if vtk.VTK_MAJOR_VERSION <= 5:
            castOut.SetInput(islandMath.GetOutput())
        else:
            castOut.SetInputConnection(islandMath.GetOutputPort())
        castOut.SetOutputScalarTypeToShort()
        castOut.SetOutput(self.getScopedLabelOutput())

        # TODO $this setProgressFilter $postThresh "Applying to Label Map..."
        castOut.Update()
        islandCount = islandMath.GetNumberOfIslands()
        islandOrigCount = islandMath.GetOriginalNumberOfIslands()
        ignoredIslands = islandOrigCount - islandCount
        print("%d islands created (%d ignored)" %
              (islandCount, ignoredIslands))

        self.applyScopedLabel()
        castOut.SetOutput(None)
コード例 #7
0
  def removeIslands(self):
    #
    # change the label values based on the parameter node
    #
    if not self.sliceLogic:
      self.sliceLogic = self.editUtil.getSliceLogic()
    parameterNode = self.editUtil.getParameterNode()
    minimumSize = int(parameterNode.GetParameter("IslandEffect,minimumSize"))
    fullyConnected = bool(parameterNode.GetParameter("IslandEffect,fullyConnected"))
    label = self.editUtil.getLabel()

    # note that island operation happens in unsigned long space
    # but the slicer editor works in Short
    castIn = vtk.vtkImageCast()
    if vtk.VTK_MAJOR_VERSION <= 5:
      castIn.SetInput( self.getScopedLabelInput() )
    else:
      castIn.SetInputData( self.getScopedLabelInput() )
    castIn.SetOutputScalarTypeToUnsignedLong()

    # now identify the islands in the inverted volume
    # and find the pixel that corresponds to the background
    islandMath = vtkITK.vtkITKIslandMath()
    if vtk.VTK_MAJOR_VERSION <= 5:
      islandMath.SetInput( castIn.GetOutput() )
    else:
      islandMath.SetInputConnection( castIn.GetOutputPort() )
    islandMath.SetFullyConnected( fullyConnected )
    islandMath.SetMinimumSize( minimumSize )
    # TODO: $this setProgressFilter $islandMath "Calculating Islands..."

    # note that island operation happens in unsigned long space
    # but the slicer editor works in Short
    castOut = vtk.vtkImageCast()
    if vtk.VTK_MAJOR_VERSION <= 5:
      castOut.SetInput( islandMath.GetOutput() )
    else:
      castOut.SetInputConnection( islandMath.GetOutputPort() )
    castOut.SetOutputScalarTypeToShort()
    castOut.SetOutput( self.getScopedLabelOutput() )

    # TODO $this setProgressFilter $postThresh "Applying to Label Map..."
    castOut.Update()
    islandCount = islandMath.GetNumberOfIslands()
    islandOrigCount = islandMath.GetOriginalNumberOfIslands()
    ignoredIslands = islandOrigCount - islandCount
    print( "%d islands created (%d ignored)" % (islandCount, ignoredIslands) )

    self.applyScopedLabel()
    castOut.SetOutput( None )
コード例 #8
0
  def identIslands(self):
    inputImage=self.volume.GetImageData()
    labelImage=self.label.GetImageData()
    #labelImage.SetSpacing(self.label.GetSpacing())

    IJKToRAS = vtk.vtkMatrix4x4()
    self.volume.GetIJKToRASMatrix(IJKToRAS)
    self.label.SetIJKToRASMatrix(IJKToRAS)

    eV=slicer.vtkFillVOIImageFilter()
    eV.SetfillValue(0)
    eV.SetInputData(inputImage)

    if self.sliceidx>0:
      VOIpre=[0,inputImage.GetDimensions()[0],0,inputImage.GetDimensions()[1],0,self.sliceidx-1]
      eV.AddVOI(VOIpre)
    if self.sliceidx<inputImage.GetDimensions()[2]:
      VOIpost=[0,inputImage.GetDimensions()[0],0,inputImage.GetDimensions()[1],self.sliceidx+1,inputImage.GetDimensions()[2]]
      eV.AddVOI(VOIpost)

    eV.Update()
                    
    slice=eV.GetOutput()

    thresh = vtk.vtkImageThreshold()
    thresh.SetInputData(slice)

    thresh.ThresholdBetween(self.thrRange[0],self.thrRange[1])
    thresh.SetInValue(1)
    thresh.SetOutValue(0)
    thresh.SetOutputScalarType(vtk.VTK_SHORT)
    thresh.Modified()
    thresh.Update()

    islandM=vtkITK.vtkITKIslandMath()
    islandM.SetInputData(thresh.GetOutput())
    islandM.Update()

    labelImage.DeepCopy(islandM.GetOutput())
コード例 #9
0
    def splitSegments(self, minimumSize=0, maxNumberOfSegments=0, split=True):
        """
    minimumSize: if 0 then it means that all islands are kept, regardless of size
    maxNumberOfSegments: if 0 then it means that all islands are kept, regardless of how many
    """
        # This can be a long operation - indicate it to the user
        qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)

        self.scriptedEffect.saveStateForUndo()

        # Get modifier labelmap
        selectedSegmentLabelmap = self.scriptedEffect.selectedSegmentLabelmap()

        castIn = vtk.vtkImageCast()
        castIn.SetInputData(selectedSegmentLabelmap)
        castIn.SetOutputScalarTypeToUnsignedInt()

        # Identify the islands in the inverted volume and
        # find the pixel that corresponds to the background
        islandMath = vtkITK.vtkITKIslandMath()
        islandMath.SetInputConnection(castIn.GetOutputPort())
        islandMath.SetFullyConnected(False)
        islandMath.SetMinimumSize(minimumSize)
        islandMath.Update()

        # Create a separate image for the first (largest) island
        labelValue = 1
        backgroundValue = 0
        thresh = vtk.vtkImageThreshold()
        if split:
            thresh.ThresholdBetween(1, 1)
        else:
            if maxNumberOfSegments != 0:
                thresh.ThresholdBetween(1, maxNumberOfSegments)
            else:
                thresh.ThresholdByUpper(1)

        thresh.SetInputData(islandMath.GetOutput())
        thresh.SetOutValue(backgroundValue)
        thresh.SetInValue(labelValue)
        thresh.SetOutputScalarType(selectedSegmentLabelmap.GetScalarType())
        thresh.Update()
        # Create oriented image data from output
        import vtkSegmentationCorePython as vtkSegmentationCore
        largestIslandImage = vtkSegmentationCore.vtkOrientedImageData()
        largestIslandImage.ShallowCopy(thresh.GetOutput())
        selectedSegmentLabelmapImageToWorldMatrix = vtk.vtkMatrix4x4()
        selectedSegmentLabelmap.GetImageToWorldMatrix(
            selectedSegmentLabelmapImageToWorldMatrix)
        largestIslandImage.SetImageToWorldMatrix(
            selectedSegmentLabelmapImageToWorldMatrix)

        if split and (maxNumberOfSegments != 1):

            thresh2 = vtk.vtkImageThreshold()
            # 0 is background, 1 is largest island; we need label 2 and higher
            if maxNumberOfSegments != 0:
                thresh2.ThresholdBetween(2, maxNumberOfSegments)
            else:
                thresh2.ThresholdByUpper(2)
            thresh2.SetInputData(islandMath.GetOutput())
            thresh2.SetOutValue(backgroundValue)
            thresh2.ReplaceInOff()
            thresh2.Update()

            islandCount = islandMath.GetNumberOfIslands()
            islandOrigCount = islandMath.GetOriginalNumberOfIslands()
            ignoredIslands = islandOrigCount - islandCount
            logging.info("%d islands created (%d ignored)" %
                         (islandCount, ignoredIslands))

            # Create oriented image data from output
            import vtkSegmentationCorePython as vtkSegmentationCore
            multiLabelImage = vtkSegmentationCore.vtkOrientedImageData()
            multiLabelImage.DeepCopy(thresh2.GetOutput())
            selectedSegmentLabelmapImageToWorldMatrix = vtk.vtkMatrix4x4()
            selectedSegmentLabelmap.GetImageToWorldMatrix(
                selectedSegmentLabelmapImageToWorldMatrix)
            multiLabelImage.SetGeometryFromImageToWorldMatrix(
                selectedSegmentLabelmapImageToWorldMatrix)

            # Import multi-label labelmap to segmentation
            segmentationNode = self.scriptedEffect.parameterSetNode(
            ).GetSegmentationNode()
            selectedSegmentID = self.scriptedEffect.parameterSetNode(
            ).GetSelectedSegmentID()
            selectedSegmentIndex = segmentationNode.GetSegmentation(
            ).GetSegmentIndex(selectedSegmentID)
            insertBeforeSegmentID = segmentationNode.GetSegmentation(
            ).GetNthSegmentID(selectedSegmentIndex + 1)
            selectedSegmentName = segmentationNode.GetSegmentation(
            ).GetSegment(selectedSegmentID).GetName()
            slicer.vtkSlicerSegmentationsModuleLogic.ImportLabelmapToSegmentationNode( \
              multiLabelImage, segmentationNode, selectedSegmentName+" -", insertBeforeSegmentID )

        self.scriptedEffect.modifySelectedSegmentByLabelmap(
            largestIslandImage,
            slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet)

        qt.QApplication.restoreOverrideCursor()
コード例 #10
0
ファイル: RemoveIslandsEffect.py プロジェクト: Outs/Slicer
  def removeIslands(self):
    #
    # change the label values based on the parameter node
    #
    if not self.sliceLogic:
      self.sliceLogic = self.editUtil.getSliceLogic()
    parameterNode = self.editUtil.getParameterNode()
    minimumSize = int(parameterNode.GetParameter("IslandEffect,minimumSize"))
    fullyConnected = bool(parameterNode.GetParameter("IslandEffect,fullyConnected"))
    label = self.editUtil.getLabel()

    # first, create an inverse binary version of the image
    # so that islands inside segemented object will be detected, along
    # with a big island of the background
    preThresh = vtk.vtkImageThreshold()
    preThresh.SetInValue( 0 )
    preThresh.SetOutValue( 1 )
    preThresh.ReplaceInOn()
    preThresh.ReplaceOutOn()
    preThresh.ThresholdBetween( label,label )
    preThresh.SetInput( self.getScopedLabelInput() )
    preThresh.SetOutputScalarTypeToUnsignedLong()

    # now identify the islands in the inverted volume
    # and find the pixel that corresponds to the background
    islandMath = vtkITK.vtkITKIslandMath()
    islandMath.SetInput( preThresh.GetOutput() )
    islandMath.SetFullyConnected( fullyConnected )
    islandMath.SetMinimumSize( minimumSize )
    # TODO: $this setProgressFilter $islandMath "Calculating Islands..."
    islandMath.Update()
    islandCount = islandMath.GetNumberOfIslands()
    islandOrigCount = islandMath.GetOriginalNumberOfIslands()
    ignoredIslands = islandOrigCount - islandCount
    print( "%d islands created (%d ignored)" % (islandCount, ignoredIslands) )
    if islandCount == 0:
      return

    bgPixel = self.findNonZeroBorderPixel(islandMath.GetOutput())

    # now rethreshold so that everything which is not background becomes the label
    postThresh = vtk.vtkImageThreshold()
    postThresh.SetInValue( 0 )
    postThresh.SetOutValue( label )
    postThresh.ReplaceInOn()
    postThresh.ReplaceOutOn()
    postThresh.ThresholdBetween( bgPixel, bgPixel )
    postThresh.SetOutputScalarTypeToShort()
    postThresh.SetInput( islandMath.GetOutput() )
    postThresh.SetOutput( self.getScopedLabelOutput() )
    # TODO $this setProgressFilter $postThresh "Applying to Label Map..."
    postThresh.Update()

    self.applyScopedLabel()


    if False:
      # some code for debugging - leave it in 
      layerLogic = self.sliceLogic.GetLabelLayer()
      labelNode = layerLogic.GetVolumeNode()
      volumesLogic = slicer.modules.volumes.logic()
      thresh1 = volumesLogic.CloneVolume(slicer.mrmlScene, labelNode, 'thres1')
      islands = volumesLogic.CloneVolume(slicer.mrmlScene, labelNode, 'islands')
      thresh2 = volumesLogic.CloneVolume(slicer.mrmlScene, labelNode, 'thres2')
      cast = vtk.vtkImageCast()
      cast.SetOutputScalarTypeToShort()
      cast.SetInput(preThresh.GetOutput())
      cast.Update()
      thresh1.SetAndObserveImageData(cast.GetOutput())
      cast2 = vtk.vtkImageCast()
      cast2.SetOutputScalarTypeToShort()
      cast2.SetInput(islandMath.GetOutput())
      cast2.Update()
      islands.SetAndObserveImageData(cast2.GetOutput())
      thresh2.SetAndObserveImageData(postThresh.GetOutput())
コード例 #11
0
    def splitSegments(self, minimumSize=0, maxNumberOfSegments=0, split=True):
        """
    minimumSize: if 0 then it means that all islands are kept, regardless of size
    maxNumberOfSegments: if 0 then it means that all islands are kept, regardless of how many
    """
        # This can be a long operation - indicate it to the user
        qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)

        self.scriptedEffect.saveStateForUndo()

        # Get modifier labelmap
        selectedSegmentLabelmap = self.scriptedEffect.selectedSegmentLabelmap()

        castIn = vtk.vtkImageCast()
        castIn.SetInputData(selectedSegmentLabelmap)
        castIn.SetOutputScalarTypeToUnsignedInt()

        # Identify the islands in the inverted volume and
        # find the pixel that corresponds to the background
        islandMath = vtkITK.vtkITKIslandMath()
        islandMath.SetInputConnection(castIn.GetOutputPort())
        islandMath.SetFullyConnected(False)
        islandMath.SetMinimumSize(minimumSize)
        islandMath.Update()

        islandImage = slicer.vtkOrientedImageData()
        islandImage.ShallowCopy(islandMath.GetOutput())
        selectedSegmentLabelmapImageToWorldMatrix = vtk.vtkMatrix4x4()
        selectedSegmentLabelmap.GetImageToWorldMatrix(
            selectedSegmentLabelmapImageToWorldMatrix)
        islandImage.SetImageToWorldMatrix(
            selectedSegmentLabelmapImageToWorldMatrix)

        islandCount = islandMath.GetNumberOfIslands()
        islandOrigCount = islandMath.GetOriginalNumberOfIslands()
        ignoredIslands = islandOrigCount - islandCount
        logging.info("%d islands created (%d ignored)" %
                     (islandCount, ignoredIslands))

        baseSegmentName = "Label"
        selectedSegmentID = self.scriptedEffect.parameterSetNode(
        ).GetSelectedSegmentID()
        segmentationNode = self.scriptedEffect.parameterSetNode(
        ).GetSegmentationNode()
        with slicer.util.NodeModify(segmentationNode):
            segmentation = segmentationNode.GetSegmentation()
            selectedSegment = segmentation.GetSegment(selectedSegmentID)
            selectedSegmentName = selectedSegment.GetName()
            if selectedSegmentName is not None and selectedSegmentName != "":
                baseSegmentName = selectedSegmentName

            labelValues = vtk.vtkIntArray()
            slicer.vtkSlicerSegmentationsModuleLogic.GetAllLabelValues(
                labelValues, islandImage)

            # Erase segment from in original labelmap.
            # Individuall islands will be added back later.
            threshold = vtk.vtkImageThreshold()
            threshold.SetInputData(selectedSegmentLabelmap)
            threshold.ThresholdBetween(0, 0)
            threshold.SetInValue(0)
            threshold.SetOutValue(0)
            threshold.Update()
            emptyLabelmap = slicer.vtkOrientedImageData()
            emptyLabelmap.ShallowCopy(threshold.GetOutput())
            emptyLabelmap.CopyDirections(selectedSegmentLabelmap)
            self.scriptedEffect.modifySegmentByLabelmap(
                segmentationNode, selectedSegmentID, emptyLabelmap,
                slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet)

            for i in range(labelValues.GetNumberOfTuples()):
                if (maxNumberOfSegments > 0 and i >= maxNumberOfSegments):
                    # We only care about the segments up to maxNumberOfSegments.
                    # If we do not want to split segments, we only care about the first.
                    break

                labelValue = int(labelValues.GetTuple1(i))
                segment = selectedSegment
                segmentID = selectedSegmentID
                if i != 0 and split:
                    segment = slicer.vtkSegment()
                    name = baseSegmentName + "_" + str(i + 1)
                    segment.SetName(name)
                    segment.AddRepresentation(
                        slicer.vtkSegmentationConverter.
                        GetSegmentationBinaryLabelmapRepresentationName(),
                        selectedSegment.GetRepresentation(
                            slicer.vtkSegmentationConverter.
                            GetSegmentationBinaryLabelmapRepresentationName()))
                    segmentation.AddSegment(segment)
                    segmentID = segmentation.GetSegmentIdBySegment(segment)
                    segment.SetLabelValue(
                        segmentation.GetUniqueLabelValueForSharedLabelmap(
                            selectedSegmentID))

                threshold = vtk.vtkImageThreshold()
                threshold.SetInputData(islandMath.GetOutput())
                threshold.ThresholdBetween(labelValue, labelValue)
                threshold.SetInValue(1)
                threshold.SetOutValue(0)
                threshold.Update()

                modificationMode = slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeAdd
                if i == 0:
                    modificationMode = slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet

                # Create oriented image data from output
                modifierImage = slicer.vtkOrientedImageData()
                modifierImage.DeepCopy(threshold.GetOutput())
                selectedSegmentLabelmapImageToWorldMatrix = vtk.vtkMatrix4x4()
                selectedSegmentLabelmap.GetImageToWorldMatrix(
                    selectedSegmentLabelmapImageToWorldMatrix)
                modifierImage.SetGeometryFromImageToWorldMatrix(
                    selectedSegmentLabelmapImageToWorldMatrix)
                # We could use a single slicer.vtkSlicerSegmentationsModuleLogic.ImportLabelmapToSegmentationNode
                # method call to import all the resulting segments at once but that would put all the imported segments
                # in a new layer. By using modifySegmentByLabelmap, the number of layers will not increase.
                self.scriptedEffect.modifySegmentByLabelmap(
                    segmentationNode, segmentID, modifierImage,
                    modificationMode)

        qt.QApplication.restoreOverrideCursor()
コード例 #12
0
  def splitSegments(self, minimumSize = 0, maxNumberOfSegments = 0, split = True):
    """
    minimumSize: if 0 then it means that all islands are kept, regardless of size
    maxNumberOfSegments: if 0 then it means that all islands are kept, regardless of how many
    """
    # This can be a long operation - indicate it to the user
    qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)

    self.scriptedEffect.saveStateForUndo()

    # Get modifier labelmap
    selectedSegmentLabelmap = self.scriptedEffect.selectedSegmentLabelmap()

    castIn = vtk.vtkImageCast()
    castIn.SetInputData(selectedSegmentLabelmap)
    castIn.SetOutputScalarTypeToUnsignedInt()

    # Identify the islands in the inverted volume and
    # find the pixel that corresponds to the background
    islandMath = vtkITK.vtkITKIslandMath()
    islandMath.SetInputConnection(castIn.GetOutputPort())
    islandMath.SetFullyConnected(False)
    islandMath.SetMinimumSize(minimumSize)
    islandMath.Update()

    # Create a separate image for the first (largest) island
    labelValue = 1
    backgroundValue = 0
    thresh = vtk.vtkImageThreshold()
    if split:
      thresh.ThresholdBetween(1, 1)
    else:
      if maxNumberOfSegments != 0:
        thresh.ThresholdBetween(1, maxNumberOfSegments)
      else:
        thresh.ThresholdByUpper(1)

    thresh.SetInputData(islandMath.GetOutput())
    thresh.SetOutValue(backgroundValue)
    thresh.SetInValue(labelValue)
    thresh.SetOutputScalarType(selectedSegmentLabelmap.GetScalarType())
    thresh.Update()
    # Create oriented image data from output
    import vtkSegmentationCorePython as vtkSegmentationCore
    largestIslandImage = vtkSegmentationCore.vtkOrientedImageData()
    largestIslandImage.ShallowCopy(thresh.GetOutput())
    selectedSegmentLabelmapImageToWorldMatrix = vtk.vtkMatrix4x4()
    selectedSegmentLabelmap.GetImageToWorldMatrix(selectedSegmentLabelmapImageToWorldMatrix)
    largestIslandImage.SetImageToWorldMatrix(selectedSegmentLabelmapImageToWorldMatrix)

    if split and (maxNumberOfSegments != 1):

      thresh2 = vtk.vtkImageThreshold()
      # 0 is background, 1 is largest island; we need label 2 and higher
      if maxNumberOfSegments != 0:
        thresh2.ThresholdBetween(2, maxNumberOfSegments)
      else:
        thresh2.ThresholdByUpper(2)
      thresh2.SetInputData(islandMath.GetOutput())
      thresh2.SetOutValue(backgroundValue)
      thresh2.ReplaceInOff()
      thresh2.Update()

      islandCount = islandMath.GetNumberOfIslands()
      islandOrigCount = islandMath.GetOriginalNumberOfIslands()
      ignoredIslands = islandOrigCount - islandCount
      logging.info( "%d islands created (%d ignored)" % (islandCount, ignoredIslands) )

      # Create oriented image data from output
      import vtkSegmentationCorePython as vtkSegmentationCore
      multiLabelImage = vtkSegmentationCore.vtkOrientedImageData()
      multiLabelImage.DeepCopy(thresh2.GetOutput())
      selectedSegmentLabelmapImageToWorldMatrix = vtk.vtkMatrix4x4()
      selectedSegmentLabelmap.GetImageToWorldMatrix(selectedSegmentLabelmapImageToWorldMatrix)
      multiLabelImage.SetGeometryFromImageToWorldMatrix(selectedSegmentLabelmapImageToWorldMatrix)

      # Import multi-label labelmap to segmentation
      segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
      selectedSegmentID = self.scriptedEffect.parameterSetNode().GetSelectedSegmentID()
      selectedSegmentIndex = segmentationNode.GetSegmentation().GetSegmentIndex(selectedSegmentID)
      insertBeforeSegmentID = segmentationNode.GetSegmentation().GetNthSegmentID(selectedSegmentIndex + 1)
      selectedSegmentName = segmentationNode.GetSegmentation().GetSegment(selectedSegmentID).GetName()
      slicer.vtkSlicerSegmentationsModuleLogic.ImportLabelmapToSegmentationNode( \
        multiLabelImage, segmentationNode, selectedSegmentName+" -", insertBeforeSegmentID )

    self.scriptedEffect.modifySelectedSegmentByLabelmap(largestIslandImage, slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet)

    qt.QApplication.restoreOverrideCursor()
コード例 #13
0
    def removeIslandsMorphologyDecruft(self,
                                       image,
                                       foregroundLabel,
                                       backgroundLabel,
                                       iterations=1):
        #
        # make binary mask foregroundLabel->1, backgroundLabel->0
        #
        binThresh = vtk.vtkImageThreshold()
        binThresh.SetInputData(image)
        binThresh.ThresholdBetween(foregroundLabel, foregroundLabel)
        binThresh.SetInValue(1)
        binThresh.SetOutValue(0)
        binThresh.Update()

        #
        # first, erode iterations number of times
        #
        eroder = slicer.vtkImageErode()
        eroderImage = vtk.vtkImageData()
        eroderImage.DeepCopy(binThresh.GetOutput())
        eroder.SetInputData(eroderImage)
        for iteration in range(iterations):
            eroder.SetForeground(1)
            eroder.SetBackground(0)
            eroder.SetNeighborTo8()
            eroder.Update()
            eroderImage.DeepCopy(eroder.GetOutput())

        #
        # now save only islands bigger than a specified size
        #

        # note that island operation happens in unsigned long space
        # but the slicer editor works in Short
        castIn = vtk.vtkImageCast()
        castIn.SetInputConnection(eroder.GetInputConnection(0, 0))
        castIn.SetOutputScalarTypeToUnsignedLong()

        # now identify the islands in the inverted volume
        # and find the pixel that corresponds to the background
        islandMath = vtkITK.vtkITKIslandMath()
        islandMath.SetInputConnection(castIn.GetOutputPort())
        islandMath.SetFullyConnected(self.fullyConnected)
        islandMath.SetMinimumSize(self.minimumSize)

        # note that island operation happens in unsigned long space
        # but the slicer editor works in Short
        castOut = vtk.vtkImageCast()
        castOut.SetInputConnection(islandMath.GetOutputPort())
        castOut.SetOutputScalarTypeToShort()

        castOut.Update()
        islandCount = islandMath.GetNumberOfIslands()
        islandOrigCount = islandMath.GetOriginalNumberOfIslands()
        ignoredIslands = islandOrigCount - islandCount
        print("%d islands created (%d ignored)" %
              (islandCount, ignoredIslands))

        #
        # now map everything back to 0 and 1
        #

        thresh = vtk.vtkImageThreshold()
        thresh.SetInputConnection(castOut.GetOutputPort())
        thresh.ThresholdByUpper(1)
        thresh.SetInValue(1)
        thresh.SetOutValue(0)
        thresh.Update()

        #
        # now, dilate back (erode background) iterations_plus_one number of times
        #
        dilater = slicer.vtkImageErode()
        dilaterImage = vtk.vtkImageData()
        dilaterImage.DeepCopy(thresh.GetOutput())
        dilater.SetInputData(dilaterImage)
        for iteration in range(1 + iterations):
            dilater.SetForeground(0)
            dilater.SetBackground(1)
            dilater.SetNeighborTo8()
            dilater.Update()
            dilaterImage.DeepCopy(dilater.GetOutput())

        #
        # only keep pixels in both original and dilated result
        #

        logic = vtk.vtkImageLogic()
        logic.SetInputConnection(0, dilater.GetInputConnection(0, 0))
        logic.SetInputConnection(1, binThresh.GetOutputPort())
        #if foregroundLabel == 0:
        #  logic.SetOperationToNand()
        #else:
        logic.SetOperationToAnd()
        logic.SetOutputTrueValue(1)
        logic.Update()

        #
        # convert from binary mask to 1->foregroundLabel, 0->backgroundLabel
        #
        unbinThresh = vtk.vtkImageThreshold()
        unbinThresh.SetInputConnection(logic.GetOutputPort())
        unbinThresh.ThresholdBetween(1, 1)
        unbinThresh.SetInValue(foregroundLabel)
        unbinThresh.SetOutValue(backgroundLabel)
        unbinThresh.Update()

        image.DeepCopy(unbinThresh.GetOutput())
コード例 #14
0
    def removeIslandsConnectivity(self):
        #
        # change the label values based on the parameter node
        #
        if not self.sliceLogic:
            self.sliceLogic = self.editUtil.getSliceLogic()
        parameterNode = self.editUtil.getParameterNode()
        minimumSize = int(
            parameterNode.GetParameter("IslandEffect,minimumSize"))
        fullyConnected = bool(
            parameterNode.GetParameter("IslandEffect,fullyConnected"))
        label = self.editUtil.getLabel()

        # first, create an inverse binary version of the image
        # so that islands inside segemented object will be detected, along
        # with a big island of the background
        preThresh = vtk.vtkImageThreshold()
        preThresh.SetInValue(0)
        preThresh.SetOutValue(1)
        preThresh.ReplaceInOn()
        preThresh.ReplaceOutOn()
        preThresh.ThresholdBetween(label, label)
        preThresh.SetInputData(self.getScopedLabelInput())
        preThresh.SetOutputScalarTypeToUnsignedLong()

        # now identify the islands in the inverted volume
        # and find the pixel that corresponds to the background
        islandMath = vtkITK.vtkITKIslandMath()
        islandMath.SetInputConnection(preThresh.GetOutputPort())
        islandMath.SetFullyConnected(fullyConnected)
        islandMath.SetMinimumSize(minimumSize)
        # TODO: $this setProgressFilter $islandMath "Calculating Islands..."
        islandMath.Update()
        islandCount = islandMath.GetNumberOfIslands()
        islandOrigCount = islandMath.GetOriginalNumberOfIslands()
        ignoredIslands = islandOrigCount - islandCount
        print("%d islands created (%d ignored)" %
              (islandCount, ignoredIslands))
        if islandCount == 0:
            return

        bgPixel = self.findNonZeroBorderPixel(islandMath.GetOutput())

        # now rethreshold so that everything which is not background becomes the label
        postThresh = vtk.vtkImageThreshold()
        postThresh.SetInValue(0)
        postThresh.SetOutValue(label)
        postThresh.ReplaceInOn()
        postThresh.ReplaceOutOn()
        postThresh.ThresholdBetween(bgPixel, bgPixel)
        postThresh.SetOutputScalarTypeToShort()
        postThresh.SetInputConnection(islandMath.GetOutputPort())
        postThresh.SetOutput(self.getScopedLabelOutput())
        # TODO $this setProgressFilter $postThresh "Applying to Label Map..."
        postThresh.Update()

        self.applyScopedLabel()
        postThresh.SetOutput(None)

        if False:
            # some code for debugging - leave it in
            layerLogic = self.sliceLogic.GetLabelLayer()
            labelNode = layerLogic.GetVolumeNode()
            volumesLogic = slicer.modules.volumes.logic()
            thresh1 = volumesLogic.CloneVolume(slicer.mrmlScene, labelNode,
                                               'thres1')
            islands = volumesLogic.CloneVolume(slicer.mrmlScene, labelNode,
                                               'islands')
            thresh2 = volumesLogic.CloneVolume(slicer.mrmlScene, labelNode,
                                               'thres2')
            cast = vtk.vtkImageCast()
            cast.SetOutputScalarTypeToShort()
            cast.SetInputConnection(preThresh.GetOutputPort())
            thresh1.SetImageDataConnection(cast.GetOutputPort())
            cast2 = vtk.vtkImageCast()
            cast2.SetOutputScalarTypeToShort()
            cast2.SetInputConnection(islandMath.GetOutputPort())
            islands.SetImageDataConnection(cast2.GetOutputPort())
            thresh2.SetImageDataConnection(postThresh.GetOutputPort())
コード例 #15
0
    def removeIslandsMorphologyDecruft(self, image, foregroundLabel, backgroundLabel, iterations=1):
        #
        # make binary mask foregroundLabel->1, backgroundLabel->0
        #
        binThresh = vtk.vtkImageThreshold()
        if vtk.VTK_MAJOR_VERSION <= 5:
            binThresh.SetInput(image)
        else:
            binThresh.SetInputData(image)
        binThresh.ThresholdBetween(foregroundLabel, foregroundLabel)
        binThresh.SetInValue(1)
        binThresh.SetOutValue(0)
        binThresh.Update()

        #
        # first, erode iterations number of times
        #
        eroder = slicer.vtkImageErode()
        eroderImage = vtk.vtkImageData()
        eroderImage.DeepCopy(binThresh.GetOutput())
        if vtk.VTK_MAJOR_VERSION <= 5:
            eroder.SetInput(eroderImage)
        else:
            eroder.SetInputData(eroderImage)
        for iteration in range(iterations):
            eroder.SetForeground(1)
            eroder.SetBackground(0)
            eroder.SetNeighborTo8()
            eroder.Update()
            eroderImage.DeepCopy(eroder.GetOutput())

        #
        # now save only islands bigger than a specified size
        #

        # note that island operation happens in unsigned long space
        # but the slicer editor works in Short
        castIn = vtk.vtkImageCast()
        if vtk.VTK_MAJOR_VERSION <= 5:
            castIn.SetInput(eroderImage)
        else:
            castIn.SetInputConnection(eroder.GetInputConnection(0, 0))
        castIn.SetOutputScalarTypeToUnsignedLong()

        # now identify the islands in the inverted volume
        # and find the pixel that corresponds to the background
        islandMath = vtkITK.vtkITKIslandMath()
        if vtk.VTK_MAJOR_VERSION <= 5:
            islandMath.SetInput(castIn.GetOutput())
        else:
            islandMath.SetInputConnection(castIn.GetOutputPort())
        islandMath.SetFullyConnected(self.fullyConnected)
        islandMath.SetMinimumSize(self.minimumSize)

        # note that island operation happens in unsigned long space
        # but the slicer editor works in Short
        castOut = vtk.vtkImageCast()
        if vtk.VTK_MAJOR_VERSION <= 5:
            castOut.SetInput(islandMath.GetOutput())
        else:
            castOut.SetInputConnection(islandMath.GetOutputPort())
        castOut.SetOutputScalarTypeToShort()

        castOut.Update()
        islandCount = islandMath.GetNumberOfIslands()
        islandOrigCount = islandMath.GetOriginalNumberOfIslands()
        ignoredIslands = islandOrigCount - islandCount
        print("%d islands created (%d ignored)" % (islandCount, ignoredIslands))

        #
        # now map everything back to 0 and 1
        #

        thresh = vtk.vtkImageThreshold()
        if vtk.VTK_MAJOR_VERSION <= 5:
            thresh.SetInput(castOut.GetOutput())
        else:
            thresh.SetInputConnection(castOut.GetOutputPort())
        thresh.ThresholdByUpper(1)
        thresh.SetInValue(1)
        thresh.SetOutValue(0)
        thresh.Update()

        #
        # now, dilate back (erode background) iterations_plus_one number of times
        #
        dilater = slicer.vtkImageErode()
        dilaterImage = vtk.vtkImageData()
        dilaterImage.DeepCopy(thresh.GetOutput())
        if vtk.VTK_MAJOR_VERSION <= 5:
            dilater.SetInput(dilaterImage)
        else:
            dilater.SetInputData(dilaterImage)
        for iteration in range(1 + iterations):
            dilater.SetForeground(0)
            dilater.SetBackground(1)
            dilater.SetNeighborTo8()
            dilater.Update()
            dilaterImage.DeepCopy(dilater.GetOutput())

        #
        # only keep pixels in both original and dilated result
        #

        logic = vtk.vtkImageLogic()
        if vtk.VTK_MAJOR_VERSION <= 5:
            logic.SetInput1(dilaterImage)
            logic.SetInput2(binThresh.GetOutput())
        else:
            logic.SetInputConnection(0, dilater.GetInputConnection(0, 0))
            logic.SetInputConnection(1, binThresh.GetOutputPort())
        # if foregroundLabel == 0:
        #  logic.SetOperationToNand()
        # else:
        logic.SetOperationToAnd()
        logic.SetOutputTrueValue(1)
        logic.Update()

        #
        # convert from binary mask to 1->foregroundLabel, 0->backgroundLabel
        #
        unbinThresh = vtk.vtkImageThreshold()
        if vtk.VTK_MAJOR_VERSION <= 5:
            unbinThresh.SetInput(logic.GetOutput())
        else:
            unbinThresh.SetInputConnection(logic.GetOutputPort())
        unbinThresh.ThresholdBetween(1, 1)
        unbinThresh.SetInValue(foregroundLabel)
        unbinThresh.SetOutValue(backgroundLabel)
        unbinThresh.Update()

        image.DeepCopy(unbinThresh.GetOutput())
コード例 #16
0
  def apply(self, ijkPoints):
    kernelSizePixel = self.getKernelSizePixel()
    if kernelSizePixel[0]<=0 and kernelSizePixel[1]<=0 and kernelSizePixel[2]<=0:
      return

    qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)

    # Get parameter set node
    parameterSetNode = self.scriptedEffect.parameterSetNode()

    # Get parameters
    minimumThreshold = self.scriptedEffect.doubleParameter("MinimumThreshold")
    maximumThreshold = self.scriptedEffect.doubleParameter("MaximumThreshold")

    # Get modifier labelmap
    modifierLabelmap = self.scriptedEffect.defaultModifierLabelmap()

    # Get master volume image data
    masterImageData = self.scriptedEffect.masterVolumeImageData()

    # Set intensity range
    oldMasterVolumeIntensityMask = parameterSetNode.GetMasterVolumeIntensityMask()
    parameterSetNode.MasterVolumeIntensityMaskOn()
    oldIntensityMaskRange = parameterSetNode.GetMasterVolumeIntensityMaskRange()
    intensityRange = [265.00, 1009.00]
    if oldMasterVolumeIntensityMask:
      intensityRange = [max(oldIntensityMaskRange[0], minimumThreshold), min(oldIntensityMaskRange[1], maximumThreshold)]
    parameterSetNode.SetMasterVolumeIntensityMaskRange(intensityRange)

    roiNode = lumbarSeed ##self.roiSelector.currentNode()
    clippedMasterImageData = masterImageData
    if roiNode is not None:
      worldToImageMatrix = vtk.vtkMatrix4x4()
      masterImageData.GetWorldToImageMatrix(worldToImageMatrix)

      bounds = [0,0,0,0,0,0]
      roiNode.GetRASBounds(bounds)
      corner1RAS = [bounds[0], bounds[2], bounds[4], 1]
      corner1IJK = [0, 0, 0, 0]
      worldToImageMatrix.MultiplyPoint(corner1RAS, corner1IJK)

      corner2RAS = [bounds[1], bounds[3], bounds[5], 1]
      corner2IJK = [0, 0, 0, 0]
      worldToImageMatrix.MultiplyPoint(corner2RAS, corner2IJK)

      extent = [0, -1, 0, -1, 0, -1]
      for i in range(3):
          lowerPoint = min(corner1IJK[i], corner2IJK[i])
          upperPoint = max(corner1IJK[i], corner2IJK[i])
          extent[2*i] = int(math.floor(lowerPoint))
          extent[2*i+1] = int(math.ceil(upperPoint))

      imageToWorldMatrix = vtk.vtkMatrix4x4()
      masterImageData.GetImageToWorldMatrix(imageToWorldMatrix)
      clippedMasterImageData = slicer.vtkOrientedImageData()
      self.padder = vtk.vtkImageConstantPad()
      self.padder.SetInputData(masterImageData)
      self.padder.SetOutputWholeExtent(extent)
      self.padder.Update()
      clippedMasterImageData.ShallowCopy(self.padder.GetOutput())
      clippedMasterImageData.SetImageToWorldMatrix(imageToWorldMatrix)

    # Pipeline
    self.thresh = vtk.vtkImageThreshold()
    self.thresh.SetInValue(LABEL_VALUE)
    self.thresh.SetOutValue(BACKGROUND_VALUE)
    self.thresh.SetInputData(clippedMasterImageData)
    self.thresh.ThresholdBetween(minimumThreshold, maximumThreshold)
    self.thresh.SetOutputScalarTypeToUnsignedChar()
    self.thresh.Update()

    self.erode = vtk.vtkImageDilateErode3D()
    self.erode.SetInputConnection(self.thresh.GetOutputPort())
    self.erode.SetDilateValue(BACKGROUND_VALUE)
    self.erode.SetErodeValue(LABEL_VALUE)
    self.erode.SetKernelSize(
      kernelSizePixel[0],
      kernelSizePixel[1],
      kernelSizePixel[2])

    self.erodeCast = vtk.vtkImageCast()
    self.erodeCast.SetInputConnection(self.erode.GetOutputPort())
    self.erodeCast.SetOutputScalarTypeToUnsignedInt()
    self.erodeCast.Update()

    # Remove small islands
    self.islandMath = vtkITK.vtkITKIslandMath()
    self.islandMath.SetInputConnection(self.erodeCast.GetOutputPort())
    self.islandMath.SetFullyConnected(False)
    self.islandMath.SetMinimumSize(125)  # remove regions smaller than 5x5x5 voxels

    self.islandThreshold = vtk.vtkImageThreshold()
    self.islandThreshold.SetInputConnection(self.islandMath.GetOutputPort())
    self.islandThreshold.ThresholdByLower(BACKGROUND_VALUE)
    self.islandThreshold.SetInValue(BACKGROUND_VALUE)
    self.islandThreshold.SetOutValue(LABEL_VALUE)
    self.islandThreshold.SetOutputScalarTypeToUnsignedChar()
    self.islandThreshold.Update()

    # Points may be outside the region after it is eroded.
    # Snap the points to LABEL_VALUE voxels,
    snappedIJKPoints = self.snapIJKPointsToLabel(ijkPoints, self.islandThreshold.GetOutput())
    if snappedIJKPoints.GetNumberOfPoints() == 0:
      qt.QApplication.restoreOverrideCursor()
      return

    # Convert points to real data coordinates. Required for vtkImageThresholdConnectivity.
    seedPoints = vtk.vtkPoints()
    origin = masterImageData.GetOrigin()
    spacing = masterImageData.GetSpacing()
    for i in range(snappedIJKPoints.GetNumberOfPoints()):
      ijkPoint = snappedIJKPoints.GetPoint(i)
      seedPoints.InsertNextPoint(
        origin[0]+ijkPoint[0]*spacing[0],
        origin[1]+ijkPoint[1]*spacing[1],
        origin[2]+ijkPoint[2]*spacing[2])

    segmentationAlgorithm = self.scriptedEffect.parameter(SEGMENTATION_ALGORITHM_PARAMETER_NAME)
    if segmentationAlgorithm == SEGMENTATION_ALGORITHM_MASKING:
      self.runMasking(seedPoints, self.islandThreshold.GetOutput(), modifierLabelmap)

    else:
      self.floodFillingFilterIsland = vtk.vtkImageThresholdConnectivity()
      self.floodFillingFilterIsland.SetInputConnection(self.islandThreshold.GetOutputPort())
      self.floodFillingFilterIsland.SetInValue(SELECTED_ISLAND_VALUE)
      self.floodFillingFilterIsland.ReplaceInOn()
      self.floodFillingFilterIsland.ReplaceOutOff()
      self.floodFillingFilterIsland.ThresholdBetween(265.00, 1009.00)
      self.floodFillingFilterIsland.SetSeedPoints(seedPoints)
      self.floodFillingFilterIsland.Update()

      self.maskCast = vtk.vtkImageCast()
      self.maskCast.SetInputData(self.thresh.GetOutput())
      self.maskCast.SetOutputScalarTypeToUnsignedChar()
      self.maskCast.Update()

      self.imageMask = vtk.vtkImageMask()
      self.imageMask.SetInputConnection(self.floodFillingFilterIsland.GetOutputPort())
      self.imageMask.SetMaskedOutputValue(OUTSIDE_THRESHOLD_VALUE)
      self.imageMask.SetMaskInputData(self.maskCast.GetOutput())
      self.imageMask.Update()

      imageMaskOutput = slicer.vtkOrientedImageData()
      imageMaskOutput.ShallowCopy(self.imageMask.GetOutput())
      imageMaskOutput.CopyDirections(clippedMasterImageData)

      imageToWorldMatrix = vtk.vtkMatrix4x4()
      imageMaskOutput.GetImageToWorldMatrix(imageToWorldMatrix)

      segmentOutputLabelmap = slicer.vtkOrientedImageData()
      if segmentationAlgorithm == SEGMENTATION_ALGORITHM_GROWCUT:
        self.runGrowCut(clippedMasterImageData, imageMaskOutput, segmentOutputLabelmap)
      elif segmentationAlgorithm == SEGMENTATION_ALGORITHM_WATERSHED:
        self.runWatershed(clippedMasterImageData, imageMaskOutput, segmentOutputLabelmap)
      else:
        logging.error("Unknown segmentation algorithm: \"" + segmentationAlgorithm + "\"")

      segmentOutputLabelmap.SetImageToWorldMatrix(imageToWorldMatrix)

      self.selectedSegmentThreshold = vtk.vtkImageThreshold()
      self.selectedSegmentThreshold.SetInputData(segmentOutputLabelmap)
      self.selectedSegmentThreshold.ThresholdBetween(SELECTED_ISLAND_VALUE, SELECTED_ISLAND_VALUE)
      self.selectedSegmentThreshold.SetInValue(LABEL_VALUE)
      self.selectedSegmentThreshold.SetOutValue(BACKGROUND_VALUE)
      self.selectedSegmentThreshold.SetOutputScalarType(modifierLabelmap.GetScalarType())
      self.selectedSegmentThreshold.Update()
      modifierLabelmap.ShallowCopy(self.selectedSegmentThreshold.GetOutput())

    self.scriptedEffect.saveStateForUndo()
    self.scriptedEffect.modifySelectedSegmentByLabelmap(modifierLabelmap, slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeAdd)

    parameterSetNode.SetMasterVolumeIntensityMask(oldMasterVolumeIntensityMask)
    parameterSetNode.SetMasterVolumeIntensityMaskRange(oldIntensityMaskRange)

    qt.QApplication.restoreOverrideCursor()