def __init__(self, scriptedEffect):
    AbstractScriptedSegmentEditorEffect.__init__(self, scriptedEffect)
    scriptedEffect.name = 'Threshold'

    # Effect-specific members
    import vtkITK
    self.autoThresholdCalculator = vtkITK.vtkITKImageThresholdCalculator()

    self.timer = qt.QTimer()
    self.previewState = 0
    self.previewStep = 1
    self.previewSteps = 5
    self.timer.connect('timeout()', self.preview)

    self.previewPipelines = {}
    self.setupPreviewDisplay()
Пример #2
0
  def __init__(self, scriptedEffect):
    AbstractScriptedSegmentEditorEffect.__init__(self, scriptedEffect)
    scriptedEffect.name = 'Threshold'

    # Effect-specific members
    import vtkITK
    self.autoThresholdCalculator = vtkITK.vtkITKImageThresholdCalculator()

    self.timer = qt.QTimer()
    self.previewState = 0
    self.previewStep = 1
    self.previewSteps = 5
    self.timer.connect('timeout()', self.preview)

    self.previewPipelines = {}
    self.setupPreviewDisplay()
Пример #3
0
    def run(self, inputVolume, outputSegmentation, smoothingKernelSize=3.0):
        """
    Run the processing algorithm.
    Can be used without GUI widget.
    :param inputVolume: volume to be segmented
    :param outputSegmentation: segmentation to sore the result in
    :param smoothingKernelSize: this is used for closing small holes in the segmentation
    """

        if not inputVolume or not outputSegmentation:
            raise ValueError("Input volume or output segmentation is invalid")

        logging.info('Processing started')

        # Compute bone threshold value automatically
        import vtkITK
        thresholdCalculator = vtkITK.vtkITKImageThresholdCalculator()
        thresholdCalculator.SetInputData(inputVolume.GetImageData())
        thresholdCalculator.SetMethodToOtsu()
        thresholdCalculator.Update()
        boneThresholdValue = thresholdCalculator.GetThreshold()
        volumeScalarRange = inputVolume.GetImageData().GetScalarRange()
        logging.debug(
            "Volume minimum = {0}, maximum = {1}, bone threshold = {2}".format(
                volumeScalarRange[0], volumeScalarRange[1],
                boneThresholdValue))

        # Set up segmentation
        outputSegmentation.CreateDefaultDisplayNodes()
        outputSegmentation.SetReferenceImageGeometryParameterFromVolumeNode(
            inputVolume)

        # Create segment editor to get access to effects
        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        # To show segment editor widget (useful for debugging): segmentEditorWidget.show()
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        if not segmentEditorWidget.effectByName("Wrap Solidify"):
            raise NotImplementedError(
                "SurfaceWrapSolidify extension is required")

        segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
        slicer.mrmlScene.AddNode(segmentEditorNode)
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(outputSegmentation)
        segmentEditorWidget.setMasterVolumeNode(inputVolume)

        # Create bone segment by thresholding
        boneSegmentID = outputSegmentation.GetSegmentation().AddEmptySegment(
            "bone")
        segmentEditorNode.SetSelectedSegmentID(boneSegmentID)
        segmentEditorWidget.setActiveEffectByName("Threshold")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MinimumThreshold", str(boneThresholdValue))
        effect.setParameter("MaximumThreshold", str(volumeScalarRange[1]))
        effect.self().onApply()

        # Smooth bone segment (just to reduce solidification computation time)
        segmentEditorWidget.setActiveEffectByName("Smoothing")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("SmoothingMethod", "MORPHOLOGICAL_CLOSING")
        effect.setParameter("KernelSizeMm", str(smoothingKernelSize))
        effect.self().onApply()

        # Solidify bone
        segmentEditorWidget.setActiveEffectByName("Wrap Solidify")
        effect = segmentEditorWidget.activeEffect()
        effect.self().onApply()

        # Create segment for cavity within bone region using thresholding
        segmentEditorNode.SetOverwriteMode(
            slicer.vtkMRMLSegmentEditorNode.OverwriteNone)
        segmentEditorNode.SetMaskMode(
            slicer.vtkMRMLSegmentEditorNode.PaintAllowedInsideAllSegments)
        cavitySegmentID = outputSegmentation.GetSegmentation().AddEmptySegment(
            "cavity")
        segmentEditorNode.SetSelectedSegmentID(cavitySegmentID)
        segmentEditorWidget.setActiveEffectByName("Threshold")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MinimumThreshold", str(volumeScalarRange[0]))
        effect.setParameter("MaximumThreshold", str(boneThresholdValue))
        effect.self().onApply()

        # Cavity shrink
        segmentEditorWidget.setActiveEffectByName("Margin")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MarginSizeMm", str(-smoothingKernelSize))
        effect.self().onApply()

        # Find largest cavity
        segmentEditorWidget.setActiveEffectByName("Islands")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameterDefault("Operation", "KEEP_LARGEST_ISLAND")
        effect.self().onApply()

        # Cavity restore
        segmentEditorNode.SetMaskMode(
            slicer.vtkMRMLSegmentEditorNode.PaintAllowedInsideAllSegments
        )  # ensure we don't leak into bone
        segmentEditorWidget.setActiveEffectByName("Margin")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MarginSizeMm", str(smoothingKernelSize))
        effect.self().onApply()

        # Clean up
        slicer.mrmlScene.RemoveNode(segmentEditorNode)
        outputSegmentation.RemoveSegment(boneSegmentID)
        segmentEditorWidget = None

        logging.info('Processing completed')
Пример #4
0
    def run(self,
            inputVolume,
            outputSegmentation,
            smoothingKernelSize=3.0,
            splitCavitiesDiameter=15.0):
        """
    Run the processing algorithm.
    Can be used without GUI widget.
    :param inputVolume: volume to be segmented
    :param outputSegmentation: segmentation to sore the result in
    :param smoothingKernelSize: this is used for closing small holes in the segmentation
    :param splitCavitiesDiameter: plugs in holes smaller than splitCavitiesDiamater.
    """

        if not inputVolume or not outputSegmentation:
            raise ValueError("Input volume or output segmentation is invalid")

        logging.info('Processing started')

        # Compute bone threshold value automatically
        import vtkITK
        thresholdCalculator = vtkITK.vtkITKImageThresholdCalculator()
        thresholdCalculator.SetInputData(inputVolume.GetImageData())
        # thresholdCalculator.SetMethodToOtsu()  - this does not always work (see for example CTHead example data set)
        thresholdCalculator.SetMethodToMaximumEntropy()
        thresholdCalculator.Update()
        boneThresholdValue = thresholdCalculator.GetThreshold()
        volumeScalarRange = inputVolume.GetImageData().GetScalarRange()
        logging.debug(
            f"Volume minimum = {volumeScalarRange[0]}, maximum = {volumeScalarRange[1]}, bone threshold = {boneThresholdValue}"
        )

        # Set up segmentation
        outputSegmentation.CreateDefaultDisplayNodes()
        outputSegmentation.SetReferenceImageGeometryParameterFromVolumeNode(
            inputVolume)

        # Create segment editor to get access to effects
        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        # To show segment editor widget (useful for debugging): segmentEditorWidget.show()
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        if not segmentEditorWidget.effectByName("Wrap Solidify"):
            raise NotImplementedError(
                "SurfaceWrapSolidify extension is required")

        segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
        slicer.mrmlScene.AddNode(segmentEditorNode)
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(outputSegmentation)
        segmentEditorWidget.setMasterVolumeNode(inputVolume)

        # Create bone segment by thresholding
        boneSegmentID = outputSegmentation.GetSegmentation().AddEmptySegment(
            "bone")
        segmentEditorNode.SetSelectedSegmentID(boneSegmentID)
        segmentEditorWidget.setActiveEffectByName("Threshold")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MinimumThreshold", str(boneThresholdValue))
        effect.setParameter("MaximumThreshold", str(volumeScalarRange[1]))
        effect.self().onApply()

        # Smooth bone segment (just to reduce solidification computation time)
        segmentEditorWidget.setActiveEffectByName("Smoothing")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("SmoothingMethod", "MORPHOLOGICAL_CLOSING")
        effect.setParameter("KernelSizeMm", str(smoothingKernelSize))
        effect.self().onApply()

        # Solidify bone
        segmentEditorWidget.setActiveEffectByName("Wrap Solidify")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("region", "largestCavity")
        effect.setParameter("splitCavities",
                            "True" if splitCavitiesDiameter > 0 else "False")
        effect.setParameter("splitCavitiesDiameter",
                            str(splitCavitiesDiameter))  # in mm
        effect.setParameter("outputType", "newSegment")  # in mm
        effect.self().onApply()

        # Clean up
        #slicer.mrmlScene.RemoveNode(segmentEditorNode)
        #outputSegmentation.RemoveSegment(boneSegmentID)
        #segmentEditorWidget = None

        logging.info('Processing completed')