Esempio n. 1
0
    def runGrowCut(self, masterImageData, seedLabelmap, outputLabelmap):

        self.clippedMaskImageData = slicer.vtkOrientedImageData()
        intensityBasedMasking = self.scriptedEffect.parameterSetNode(
        ).GetMasterVolumeIntensityMask()
        segmentationNode = self.scriptedEffect.parameterSetNode(
        ).GetSegmentationNode()
        success = segmentationNode.GenerateEditMask(
            self.clippedMaskImageData,
            self.scriptedEffect.parameterSetNode().GetMaskMode(),
            masterImageData,  # reference geometry
            "",  # edited segment ID
            self.scriptedEffect.parameterSetNode().GetMaskSegmentID() if
            self.scriptedEffect.parameterSetNode().GetMaskSegmentID() else "",
            masterImageData if intensityBasedMasking else None,
            self.scriptedEffect.parameterSetNode(
            ).GetMasterVolumeIntensityMaskRange()
            if intensityBasedMasking else None)

        import vtkSlicerSegmentationsModuleLogicPython as vtkSlicerSegmentationsModuleLogic
        self.growCutFilter = vtkSlicerSegmentationsModuleLogic.vtkImageGrowCutSegment(
        )
        self.growCutFilter.SetIntensityVolume(masterImageData)
        self.growCutFilter.SetSeedLabelVolume(seedLabelmap)
        self.growCutFilter.SetMaskVolume(self.clippedMaskImageData)
        self.growCutFilter.Update()
        outputLabelmap.ShallowCopy(self.growCutFilter.GetOutput())
    def computePreviewLabelmap(self, mergedImage, outputLabelmap):
        import vtkSlicerSegmentationsModuleLogicPython as vtkSlicerSegmentationsModuleLogic

        if not self.growCutFilter:
            self.growCutFilter = vtkSlicerSegmentationsModuleLogic.vtkImageGrowCutSegment(
            )
            self.growCutFilter.SetIntensityVolume(self.clippedMasterImageData)
            self.growCutFilter.SetMaskVolume(self.clippedMaskImageData)
            maskExtent = self.clippedMaskImageData.GetExtent(
            ) if self.clippedMaskImageData else None
            if maskExtent is not None and maskExtent[0] <= maskExtent[
                    1] and maskExtent[2] <= maskExtent[3] and maskExtent[
                        4] <= maskExtent[5]:
                # Mask is used.
                # Grow the extent more, as background segment does not surround region of interest.
                self.extentGrowthRatio = 0.50
            else:
                # No masking is used.
                # Background segment is expected to surround region of interest, so narrower margin is enough.
                self.extentGrowthRatio = 0.20

            self.extentGrowthRatio

        if self.scriptedEffect.parameterDefined("SeedLocalityFactor"):
            seedLocalityFactor = self.scriptedEffect.doubleParameter(
                "SeedLocalityFactor")
        else:
            seedLocalityFactor = 0.0
        self.growCutFilter.SetDistancePenalty(seedLocalityFactor)
        self.growCutFilter.SetSeedLabelVolume(mergedImage)
        self.growCutFilter.Update()

        outputLabelmap.DeepCopy(self.growCutFilter.GetOutput())
  def computePreviewLabelmap(self, mergedImage, outputLabelmap):
    import vtkSlicerSegmentationsModuleLogicPython as vtkSlicerSegmentationsModuleLogic

    if not self.growCutFilter:
      self.growCutFilter = vtkSlicerSegmentationsModuleLogic.vtkImageGrowCutSegment()
      self.growCutFilter.SetIntensityVolume(self.clippedMasterImageData)

    self.growCutFilter.SetSeedLabelVolume(mergedImage)
    self.growCutFilter.Update()

    outputLabelmap.DeepCopy( self.growCutFilter.GetOutput() )
    def computePreviewLabelmap(self, mergedImage, outputLabelmap):
        import vtkSlicerSegmentationsModuleLogicPython as vtkSlicerSegmentationsModuleLogic

        if not self.growCutFilter:
            self.growCutFilter = vtkSlicerSegmentationsModuleLogic.vtkImageGrowCutSegment(
            )
            self.growCutFilter.SetIntensityVolume(self.clippedMasterImageData)
            self.growCutFilter.SetMaskVolume(self.clippedMaskImageData)
            maskExtent = self.clippedMaskImageData.GetExtent(
            ) if self.clippedMaskImageData else None
            if maskExtent is not None and maskExtent[0] <= maskExtent[
                    1] and maskExtent[2] <= maskExtent[3] and maskExtent[
                        4] <= maskExtent[5]:
                # Mask is used.
                # Grow the extent more, as background segment does not surround region of interest.
                self.extentGrowthRatio = 0.50
            else:
                # No masking is used.
                # Background segment is expected to surround region of interest, so narrower margin is enough.
                self.extentGrowthRatio = 0.20

        if self.scriptedEffect.parameterDefined("SeedLocalityFactor"):
            seedLocalityFactor = self.scriptedEffect.doubleParameter(
                "SeedLocalityFactor")
        else:
            seedLocalityFactor = 0.0
        self.growCutFilter.SetDistancePenalty(seedLocalityFactor)
        self.growCutFilter.SetSeedLabelVolume(mergedImage)
        startTime = time.time()
        self.growCutFilter.Update()
        logging.info(
            'Grow-cut operation on volume of {}x{}x{} voxels was completed in {:3.1f} seconds.'
            .format(self.clippedMasterImageData.GetDimensions()[0],
                    self.clippedMasterImageData.GetDimensions()[1],
                    self.clippedMasterImageData.GetDimensions()[2],
                    time.time() - startTime))

        outputLabelmap.DeepCopy(self.growCutFilter.GetOutput())
        imageToWorld = vtk.vtkMatrix4x4()
        mergedImage.GetImageToWorldMatrix(imageToWorld)
        outputLabelmap.SetImageToWorldMatrix(imageToWorld)
Esempio n. 5
0
  def preview(self):
    # Get master volume image data
    import vtkSegmentationCorePython as vtkSegmentationCore
    masterImageData = self.scriptedEffect.masterVolumeImageData()

    # Get segmentation
    segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()

    method = self.scriptedEffect.parameter("AutoCompleteMethod")

    previewNode = self.scriptedEffect.parameterSetNode().GetNodeReference(ResultPreviewNodeReferenceRole)
    if not previewNode or not self.mergedLabelmapGeometryImage \
      or (method == GROWCUT and not self.clippedMasterImageData):
      self.reset()
      # Compute merged labelmap extent (effective extent slightly expanded)
      self.selectedSegmentIds = vtk.vtkStringArray()
      segmentationNode.GetDisplayNode().GetVisibleSegmentIDs(self.selectedSegmentIds)
      minimumNumberOfSegments = 2 if method == GROWCUT else 1
      if self.selectedSegmentIds.GetNumberOfValues() < minimumNumberOfSegments:
        logging.info("Auto-complete operation skipped: at least {0} visible segments are required".format(minimumNumberOfSegments))
        return
      if not self.mergedLabelmapGeometryImage:
        self.mergedLabelmapGeometryImage = vtkSegmentationCore.vtkOrientedImageData()
      commonGeometryString = segmentationNode.GetSegmentation().DetermineCommonLabelmapGeometry(
        vtkSegmentationCore.vtkSegmentation.EXTENT_UNION_OF_EFFECTIVE_SEGMENTS, self.selectedSegmentIds)
      if not commonGeometryString:
        logging.info("Auto-complete operation skipped: all visible segments are empty")
        return
      vtkSegmentationCore.vtkSegmentationConverter.DeserializeImageGeometry(commonGeometryString, self.mergedLabelmapGeometryImage)

      masterImageExtent = masterImageData.GetExtent()
      labelsEffectiveExtent = self.mergedLabelmapGeometryImage.GetExtent()
      margin = [17, 17, 17]
      labelsExpandedExtent = [
        max(masterImageExtent[0], labelsEffectiveExtent[0]-margin[0]),
        min(masterImageExtent[1], labelsEffectiveExtent[1]+margin[0]),
        max(masterImageExtent[2], labelsEffectiveExtent[2]-margin[1]),
        min(masterImageExtent[3], labelsEffectiveExtent[3]+margin[1]),
        max(masterImageExtent[4], labelsEffectiveExtent[4]-margin[2]),
        min(masterImageExtent[5], labelsEffectiveExtent[5]+margin[2]) ]
      self.mergedLabelmapGeometryImage.SetExtent(labelsExpandedExtent)

      previewNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLSegmentationNode')
      previewNode.UnRegister(None)
      previewNode = slicer.mrmlScene.AddNode(previewNode)
      previewNode.CreateDefaultDisplayNodes()
      previewNode.GetDisplayNode().SetVisibility2DOutline(False)
      if segmentationNode.GetParentTransformNode():
        previewNode.SetAndObserveTransformNodeID(segmentationNode.GetParentTransformNode().GetID())
      self.scriptedEffect.parameterSetNode().SetNodeReferenceID(ResultPreviewNodeReferenceRole, previewNode.GetID())
      self.setPreviewOpacity(0.6)

      if method == GROWCUT:
        self.clippedMasterImageData = vtkSegmentationCore.vtkOrientedImageData()
        masterImageClipper = vtk.vtkImageConstantPad()
        masterImageClipper.SetInputData(masterImageData)
        masterImageClipper.SetOutputWholeExtent(self.mergedLabelmapGeometryImage.GetExtent())
        masterImageClipper.Update()
        self.clippedMasterImageData.ShallowCopy(masterImageClipper.GetOutput())
        self.clippedMasterImageData.CopyDirections(self.mergedLabelmapGeometryImage)

    previewNode.SetName(segmentationNode.GetName()+" preview")

    mergedImage = vtkSegmentationCore.vtkOrientedImageData()
    segmentationNode.GenerateMergedLabelmapForAllSegments(mergedImage,
      vtkSegmentationCore.vtkSegmentation.EXTENT_UNION_OF_EFFECTIVE_SEGMENTS, self.mergedLabelmapGeometryImage, self.selectedSegmentIds)

    # Make a zero-valued volume for the output
    outputLabelmap = vtkSegmentationCore.vtkOrientedImageData()

    if method == MORPHOLOGICAL_SLICE_INTERPOLATION:
        import vtkITK
        interpolator = vtkITK.vtkITKMorphologicalContourInterpolator()
        interpolator.SetInputData(mergedImage)
        interpolator.Update()
        outputLabelmap.DeepCopy(interpolator.GetOutput())

    elif method == GROWCUT:

      import vtkSlicerSegmentationsModuleLogicPython as vtkSlicerSegmentationsModuleLogic
      # if self.growCutFilter exists but previewNode is empty then probably the scene was closed
      # while in preview mode
      if self.growCutFilter:
        self.growCutFilter.SetSeedLabelVolume(mergedImage)
        self.growCutFilter.Update()
      else:
        self.growCutFilter = vtkSlicerSegmentationsModuleLogic.vtkImageGrowCutSegment()
        self.growCutFilter.SetIntensityVolume(self.clippedMasterImageData)
        self.growCutFilter.SetSeedLabelVolume(mergedImage)
        self.growCutFilter.Update()

      outputLabelmap.DeepCopy( self.growCutFilter.GetOutput() )
    else:
      logging.error("Invalid auto-complete method {0}".format(smoothingMethod))
      return

    # Write output segmentation results in segments
    for index in xrange(self.selectedSegmentIds.GetNumberOfValues()):
      segmentID = self.selectedSegmentIds.GetValue(index)
      segment = segmentationNode.GetSegmentation().GetSegment(segmentID)
      # Disable save with scene?

      # Get only the label of the current segment from the output image
      thresh = vtk.vtkImageThreshold()
      thresh.ReplaceInOn()
      thresh.ReplaceOutOn()
      thresh.SetInValue(1)
      thresh.SetOutValue(0)
      labelValue = index + 1 # n-th segment label value = n + 1 (background label value is 0)
      thresh.ThresholdBetween(labelValue, labelValue);
      thresh.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR)
      thresh.SetInputData(outputLabelmap)
      thresh.Update()

      # Write label to segment
      newSegmentLabelmap = vtkSegmentationCore.vtkOrientedImageData()
      newSegmentLabelmap.ShallowCopy(thresh.GetOutput())
      newSegmentLabelmap.CopyDirections(mergedImage)
      newSegment = previewNode.GetSegmentation().GetSegment(segmentID)
      if not newSegment:
        newSegment = vtkSegmentationCore.vtkSegment()
        newSegment.SetName(segment.GetName())
        previewNode.GetSegmentation().AddSegment(newSegment, segmentID)
        previewNode.GetDisplayNode().SetSegmentColor(segmentID, segmentationNode.GetDisplayNode().GetSegmentColor(segmentID))
      slicer.vtkSlicerSegmentationsModuleLogic.SetBinaryLabelmapToSegment(newSegmentLabelmap, previewNode, segmentID)

    self.updateGUIFromMRML()
  def preview(self):
    # Get master volume image data
    import vtkSegmentationCorePython as vtkSegmentationCore
    masterImageData = self.scriptedEffect.masterVolumeImageData()

    # Get segmentation
    segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()

    method = self.scriptedEffect.parameter("AutoCompleteMethod")

    previewNode = self.scriptedEffect.parameterSetNode().GetNodeReference(ResultPreviewNodeReferenceRole)
    if not previewNode or not self.mergedLabelmapGeometryImage \
      or (method == GROWCUT and not self.clippedMasterImageData):
      self.reset()
      # Compute merged labelmap extent (effective extent slightly expanded)
      self.selectedSegmentIds = vtk.vtkStringArray()
      segmentationNode.GetDisplayNode().GetVisibleSegmentIDs(self.selectedSegmentIds)
      minimumNumberOfSegments = 2 if method == GROWCUT else 1
      if self.selectedSegmentIds.GetNumberOfValues() < minimumNumberOfSegments:
        logging.info("Auto-complete operation skipped: at least {0} visible segments are required".format(minimumNumberOfSegments))
        return
      if not self.mergedLabelmapGeometryImage:
        self.mergedLabelmapGeometryImage = vtkSegmentationCore.vtkOrientedImageData()
      commonGeometryString = segmentationNode.GetSegmentation().DetermineCommonLabelmapGeometry(
        vtkSegmentationCore.vtkSegmentation.EXTENT_UNION_OF_EFFECTIVE_SEGMENTS, self.selectedSegmentIds)
      if not commonGeometryString:
        logging.info("Auto-complete operation skipped: all visible segments are empty")
        return
      vtkSegmentationCore.vtkSegmentationConverter.DeserializeImageGeometry(commonGeometryString, self.mergedLabelmapGeometryImage)

      masterImageExtent = masterImageData.GetExtent()
      labelsEffectiveExtent = self.mergedLabelmapGeometryImage.GetExtent()
      margin = [17, 17, 17]
      labelsExpandedExtent = [
        max(masterImageExtent[0], labelsEffectiveExtent[0]-margin[0]),
        min(masterImageExtent[1], labelsEffectiveExtent[1]+margin[0]),
        max(masterImageExtent[2], labelsEffectiveExtent[2]-margin[1]),
        min(masterImageExtent[3], labelsEffectiveExtent[3]+margin[1]),
        max(masterImageExtent[4], labelsEffectiveExtent[4]-margin[2]),
        min(masterImageExtent[5], labelsEffectiveExtent[5]+margin[2]) ]
      self.mergedLabelmapGeometryImage.SetExtent(labelsExpandedExtent)

      previewNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLSegmentationNode')
      previewNode.UnRegister(None)
      previewNode = slicer.mrmlScene.AddNode(previewNode)
      previewNode.CreateDefaultDisplayNodes()
      previewNode.GetDisplayNode().SetVisibility2DOutline(False)
      if segmentationNode.GetParentTransformNode():
        previewNode.SetAndObserveTransformNodeID(segmentationNode.GetParentTransformNode().GetID())
      self.scriptedEffect.parameterSetNode().SetNodeReferenceID(ResultPreviewNodeReferenceRole, previewNode.GetID())
      self.setPreviewOpacity(0.6)

      if method == GROWCUT:
        self.clippedMasterImageData = vtkSegmentationCore.vtkOrientedImageData()
        masterImageClipper = vtk.vtkImageConstantPad()
        masterImageClipper.SetInputData(masterImageData)
        masterImageClipper.SetOutputWholeExtent(self.mergedLabelmapGeometryImage.GetExtent())
        masterImageClipper.Update()
        self.clippedMasterImageData.ShallowCopy(masterImageClipper.GetOutput())
        self.clippedMasterImageData.CopyDirections(self.mergedLabelmapGeometryImage)

    previewNode.SetName(segmentationNode.GetName()+" preview")

    mergedImage = vtkSegmentationCore.vtkOrientedImageData()
    segmentationNode.GenerateMergedLabelmapForAllSegments(mergedImage,
      vtkSegmentationCore.vtkSegmentation.EXTENT_UNION_OF_EFFECTIVE_SEGMENTS, self.mergedLabelmapGeometryImage, self.selectedSegmentIds)

    # Make a zero-valued volume for the output
    outputLabelmap = vtkSegmentationCore.vtkOrientedImageData()

    if method == MORPHOLOGICAL_SLICE_INTERPOLATION:
        import vtkITK
        interpolator = vtkITK.vtkITKMorphologicalContourInterpolator()
        interpolator.SetInputData(mergedImage)
        interpolator.Update()
        outputLabelmap.DeepCopy(interpolator.GetOutput())

    elif method == GROWCUT:

      import vtkSlicerSegmentationsModuleLogicPython as vtkSlicerSegmentationsModuleLogic
      # if self.growCutFilter exists but previewNode is empty then probably the scene was closed
      # while in preview mode
      if self.growCutFilter:
        self.growCutFilter.SetSeedLabelVolume(mergedImage)
        self.growCutFilter.Update()
      else:
        self.growCutFilter = vtkSlicerSegmentationsModuleLogic.vtkImageGrowCutSegment()
        self.growCutFilter.SetIntensityVolume(self.clippedMasterImageData)
        self.growCutFilter.SetSeedLabelVolume(mergedImage)
        self.growCutFilter.Update()

      outputLabelmap.DeepCopy( self.growCutFilter.GetOutput() )
    else:
      logging.error("Invalid auto-complete method {0}".format(smoothingMethod))
      return

    # Write output segmentation results in segments
    for index in xrange(self.selectedSegmentIds.GetNumberOfValues()):
      segmentID = self.selectedSegmentIds.GetValue(index)
      segment = segmentationNode.GetSegmentation().GetSegment(segmentID)
      # Disable save with scene?

      # Get only the label of the current segment from the output image
      thresh = vtk.vtkImageThreshold()
      thresh.ReplaceInOn()
      thresh.ReplaceOutOn()
      thresh.SetInValue(1)
      thresh.SetOutValue(0)
      labelValue = index + 1 # n-th segment label value = n + 1 (background label value is 0)
      thresh.ThresholdBetween(labelValue, labelValue);
      thresh.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR)
      thresh.SetInputData(outputLabelmap)
      thresh.Update()

      # Write label to segment
      newSegmentLabelmap = vtkSegmentationCore.vtkOrientedImageData()
      newSegmentLabelmap.ShallowCopy(thresh.GetOutput())
      newSegmentLabelmap.CopyDirections(mergedImage)
      newSegment = previewNode.GetSegmentation().GetSegment(segmentID)
      if not newSegment:
        newSegment = vtkSegmentationCore.vtkSegment()
        newSegment.SetName(segment.GetName())
        color = segmentationNode.GetSegmentation().GetSegment(segmentID).GetColor()
        newSegment.SetColor(color)
        previewNode.GetSegmentation().AddSegment(newSegment, segmentID)
      slicer.vtkSlicerSegmentationsModuleLogic.SetBinaryLabelmapToSegment(newSegmentLabelmap, previewNode, segmentID)

    self.updateGUIFromMRML()