Пример #1
0
    def onApplyButton(self):
        red_logic = slicer.app.layoutManager().sliceWidget("Red").sliceLogic()
        red_cn = red_logic.GetSliceCompositeNode()
        volumeID = red_cn.GetBackgroundVolumeID()
        CTNode = SlicerUtil.getNode(volumeID)
        if self.labelSelector.currentNode() == None:
            warning = self.preProcessingWidget.warningMessageForLM()
            if warning == 16384:
                labelNode = slicer.mrmlScene.AddNode(
                    slicer.vtkMRMLLabelMapVolumeNode())
                labelNode.SetName(CTNode.GetName() + '_partialLungLabelMap')

                if not CTNode:
                    self.applyButton.enabled = True
                    return False
                if self.preProcessingWidget.filterOnRadioButton.checked:
                    volumesLogic = slicer.modules.volumes.logic()
                    clonedCTNode = volumesLogic.CloneVolume(
                        slicer.mrmlScene, CTNode, 'Cloned Volume')
                    self.filterInputCT(clonedCTNode)
                    self.createLungLabelMap(clonedCTNode, labelNode)
                    slicer.mrmlScene.RemoveNode(clonedCTNode)
                    for color in ['Red', 'Yellow', 'Green']:
                        slicer.app.layoutManager().sliceWidget(
                            color).sliceLogic().GetSliceCompositeNode(
                            ).SetBackgroundVolumeID(CTNode.GetID())
                else:
                    self.createLungLabelMap(CTNode, labelNode)

            else:
                qt.QMessageBox.warning(slicer.util.mainWindow(),
                                       "Parenchyma Analysis",
                                       "Please select a Lung Label Map.")
                self.applyButton.enabled = True
                return False

        self.visualizationWidget.updateScene()

        self.applyButton.text = "Segmenting Lobes..."
        self.applyButton.repaint()
        slicer.app.processEvents()

        logic = CIP_InteractiveLobeSegmentationLogic()

        self.visualizationWidget.pendingUpdate = True
        outputNode = self.outputSelector.currentNode()
        if not outputNode:
            outputNode = slicer.vtkMRMLLabelMapVolumeNode()
            slicer.mrmlScene.AddNode(outputNode)

        fissureVolume = None
        try:
            fissureVolume = logic.run(self.labelSelector.currentNode(),
                                      outputNode)
        except Exception, e:
            import traceback
            traceback.print_exc()
            qt.QMessageBox.warning(
                slicer.util.mainWindow(), "Running", 'Exception!\n\n' +
                str(e) + "\n\nSee Python Console for Stack Trace")
  def runWatershed(self, masterImageData, seedLabelmap, outputLabelmap):

    masterVolumeNode = slicer.vtkMRMLScalarVolumeNode()
    slicer.mrmlScene.AddNode(masterVolumeNode)
    slicer.vtkSlicerSegmentationsModuleLogic.CopyOrientedImageDataToVolumeNode(masterImageData, masterVolumeNode)

    seedLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
    slicer.mrmlScene.AddNode(seedLabelmapNode)
    slicer.vtkSlicerSegmentationsModuleLogic.CopyOrientedImageDataToVolumeNode(seedLabelmap, seedLabelmapNode)

    # Read input data from Slicer into SimpleITK
    labelImage = sitk.ReadImage(sitkUtils.GetSlicerITKReadWriteAddress(seedLabelmapNode.GetName()))
    backgroundImage = sitk.ReadImage(sitkUtils.GetSlicerITKReadWriteAddress(masterVolumeNode.GetName()))
    # Run watershed filter
    featureImage = sitk.GradientMagnitudeRecursiveGaussian(backgroundImage, float(self.scriptedEffect.doubleParameter(FEATURE_SIZE_MM_PARAMETER_NAME)))
    del backgroundImage
    f = sitk.MorphologicalWatershedFromMarkersImageFilter()
    f.SetMarkWatershedLine(False)
    f.SetFullyConnected(False)
    labelImage = f.Execute(featureImage, labelImage)
    del featureImage
    # Pixel type of watershed output is the same as the input. Convert it to int16 now.
    if labelImage.GetPixelID() != sitk.sitkInt16:
      labelImage = sitk.Cast(labelImage, sitk.sitkInt16)
    # Write result from SimpleITK to Slicer. This currently performs a deep copy of the bulk data.
    sitk.WriteImage(labelImage, sitkUtils.GetSlicerITKReadWriteAddress(seedLabelmapNode.GetName()))

    # Update segmentation from labelmap node and remove temporary nodes
    outputLabelmap.ShallowCopy(seedLabelmapNode.GetImageData())
    outputLabelmap.SetExtent(masterImageData.GetExtent())

    slicer.mrmlScene.RemoveNode(masterVolumeNode)
    slicer.mrmlScene.RemoveNode(seedLabelmapNode)
Пример #3
0
  def prepareLabelsFromSegmentation(self, segmentationNode, grayscaleImage, labelsDict):
    import vtkSegmentationCorePython as vtkSegmentationCore
    segLogic = slicer.modules.segmentations.logic()

    segmentation = segmentationNode.GetSegmentation()
    binaryRepresentationDef = vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName()
    if not segmentation.ContainsRepresentation(binaryRepresentationDef):
      segmentation.CreateRepresentation(binaryRepresentationDef)

    segmentLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
    slicer.mrmlScene.AddNode(segmentLabelmapNode)

    for segmentID in range(segmentation.GetNumberOfSegments()):
      segment = segmentation.GetNthSegment(segmentID)
      segmentLabelmap = segment.GetRepresentation(
        vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName())
      if not segLogic.CreateLabelmapVolumeFromOrientedImageData(segmentLabelmap, segmentLabelmapNode):
        self.logger.error("Failed to convert label map")
        return labelsDict
      labelmapImage = sitk.ReadImage(sitkUtils.GetSlicerITKReadWriteAddress(segmentLabelmapNode.GetName()))
      labelmapImage = self.resampleITKLabel(labelmapImage, grayscaleImage)
      labelsDict[segmentationNode.GetName()+"_segment_"+segment.GetName()] = labelmapImage

    displayNode = segmentLabelmapNode.GetDisplayNode()
    if displayNode:
      slicer.mrmlScene.RemoveNode(displayNode)
    slicer.mrmlScene.RemoveNode(segmentLabelmapNode)

    return labelsDict
Пример #4
0
def warpImg(inImg, refImg, outImg, pixelT, tfmFile, intplMode, labelMap=False):
    '''Resample an image using an exisiting transform.
    inImg: full path to the input image (to be resampled);
    refImg: full path to the reference image;
    outImg: full path to the output image (resampled image);
    pixelT: pixel type, options include
            float, short, ushort, int, uint, uchar, binary
    tfmFile: full path to the transform image;
    intplMode: interpolation mode, options include
            Linear, NearestNeighbor, BSpline, WindowedSinc.
    labelMap: whether the output is a label map (Boolean).
    '''
    slicer.mrmlScene.Clear(0)
    if labelMap:
        inimg = slicer.util.loadLabelVolume(inImg)
        outVolume = slicer.vtkMRMLLabelMapVolumeNode()
    else:
        inimg = slicer.util.loadVolume(inImg)
        outVolume = slicer.vtkMRMLScalarVolumeNode()
    refimg = slicer.util.loadVolume(refImg)
    tfm = slicer.util.loadTransform(tfmFile)
    slicer.mrmlScene.AddNode(outVolume)
    cliModule = slicer.modules.brainsresample
    p = {}
    p['inputVolume'] = inimg.GetID()
    p['referenceVolume'] = refimg.GetID()
    p['outputVolume'] = outVolume.GetID()
    p['pixelType'] = pixelT
    p['warpTransform'] = tfm.GetID()
    p['interpolationMode'] = intplMode
    slicer.cli.run(cliModule, None, p, wait_for_completion=True)
    state = slicer.util.saveNode(outVolume, outImg)
    slicer.mrmlScene.Clear(0)
    return {outImg: state}
Пример #5
0
  def createSampleLabelmapVolumeNode(self, volumeNode, name, label, colorNode=None):
    self.assertIsNotNone( volumeNode )
    self.assertTrue( volumeNode.IsA('vtkMRMLScalarVolumeNode') )
    self.assertTrue( label > 0 )

    sampleLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
    sampleLabelmapNode.SetName(name)
    sampleLabelmapNode = slicer.mrmlScene.AddNode(sampleLabelmapNode)
    sampleLabelmapNode.Copy(volumeNode)
    imageData = sampleLabelmapNode.GetImageData()
    extent = imageData.GetExtent()
    for x in range(extent[0], extent[1]+1):
      for y in range(extent[2], extent[3]+1):
        for z in range(extent[4], extent[5]+1):
          if ( (x >= (extent[1]/4) and x <= (extent[1]/4) * 3) and
               (y >= (extent[3]/4) and y <= (extent[3]/4) * 3) and
               (z >= (extent[5]/4) and z <= (extent[5]/4) * 3) ):
            imageData.SetScalarComponentFromDouble(x,y,z,0,label)
          else:
            imageData.SetScalarComponentFromDouble(x,y,z,0,0)

    # Display labelmap
    labelmapVolumeDisplayNode = slicer.vtkMRMLLabelMapVolumeDisplayNode()
    slicer.mrmlScene.AddNode(labelmapVolumeDisplayNode)
    if colorNode is None:
      colorNode = slicer.util.getNode('GenericAnatomyColors')
      self.assertIsNotNone( colorNode )
    labelmapVolumeDisplayNode.SetAndObserveColorNodeID(colorNode.GetID())
    labelmapVolumeDisplayNode.VisibilityOn()
    sampleLabelmapName = slicer.mrmlScene.GenerateUniqueName(name)
    sampleLabelmapNode.SetName(sampleLabelmapName)
    sampleLabelmapNode.SetAndObserveDisplayNodeID(labelmapVolumeDisplayNode.GetID())

    return sampleLabelmapNode
Пример #6
0
    def findLargest2DRegion(segmentationNode):
        qrLogic = CustomSegmentEditorLogic
        segmentationsLogic = slicer.modules.segmentations.logic()

        largestLM = None
        largestSize = 0
        for segment in qrLogic.getAllSegments(segmentationNode):
            imageData = vtkSegmentationCore.vtkOrientedImageData()
            segmentID = segmentationNode.GetSegmentation(
            ).GetSegmentIdBySegment(segment)
            segmentationsLogic.GetSegmentBinaryLabelmapRepresentation(
                segmentationNode, segmentID, imageData)
            extent = imageData.GetExtent()

            if extent[1] != -1 and extent[3] != -1 and extent[5] != -1:
                tempLabel = slicer.vtkMRMLLabelMapVolumeNode()
                tempLabel.SetName(segment.GetName() + "CentroidHelper")
                segmentationsLogic.CreateLabelmapVolumeFromOrientedImageData(
                    imageData, tempLabel)

                dims = tempLabel.GetImageData().GetDimensions()
                size = dims[0] * dims[1]
                if size > largestSize:
                    largestSize = size
                    largestLM = tempLabel

        return largestLM
Пример #7
0
    def _getLabelGeneratorFromSegmentationNode(self, segmentationNode,
                                               imageNode):
        import vtkSegmentationCorePython as vtkSegmentationCore
        segLogic = slicer.modules.segmentations.logic()

        segmentation = segmentationNode.GetSegmentation()
        binaryRepresentationDef = \
            vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName()
        if not segmentation.ContainsRepresentation(binaryRepresentationDef):
            segmentation.CreateRepresentation(binaryRepresentationDef)

        segmentLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
        slicer.mrmlScene.AddNode(segmentLabelmapNode)

        for segmentIndex in range(segmentation.GetNumberOfSegments()):
            segmentID = segmentation.GetNthSegmentID(segmentIndex)
            segmentIDs = vtk.vtkStringArray()
            segmentIDs.InsertNextValue(segmentID)

            if not slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentsToLabelmapNode(
                    segmentationNode, segmentIDs, segmentLabelmapNode,
                    imageNode):
                self.logger.error("Failed to convert label map")
                continue
            if not segmentLabelmapNode:
                self.logger.warning('no node')
                continue
            segmentName = segmentation.GetNthSegment(segmentIndex).GetName()
            yield '%s_segment_%s' % (segmentationNode.GetName(), segmentName
                                     ), segmentLabelmapNode, 1, imageNode

        displayNode = segmentLabelmapNode.GetDisplayNode()
        if displayNode:
            slicer.mrmlScene.RemoveNode(displayNode)
        slicer.mrmlScene.RemoveNode(segmentLabelmapNode)
  def _getLabelGeneratorFromSegmentationNode(self, segmentationNode, imageNode):
    import vtkSegmentationCorePython as vtkSegmentationCore
    segLogic = slicer.modules.segmentations.logic()

    segmentation = segmentationNode.GetSegmentation()
    binaryRepresentationDef = vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName()
    if not segmentation.ContainsRepresentation(binaryRepresentationDef):
      segmentation.CreateRepresentation(binaryRepresentationDef)

    segmentLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
    slicer.mrmlScene.AddNode(segmentLabelmapNode)

    for segmentID in range(segmentation.GetNumberOfSegments()):
      segment = segmentation.GetNthSegment(segmentID)
      segmentLabelmap = segment.GetRepresentation(
        vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName())
      if not segLogic.CreateLabelmapVolumeFromOrientedImageData(segmentLabelmap, segmentLabelmapNode):
        self.logger.error("Failed to convert label map")
        continue
      if not segmentLabelmapNode:
        self.logger.warning('no node')
        continue
      yield '%s_segment_%s' % (segmentationNode.GetName(), segment.GetName()), segmentLabelmapNode, 1, imageNode

    displayNode = segmentLabelmapNode.GetDisplayNode()
    if displayNode:
      slicer.mrmlScene.RemoveNode(displayNode)
    slicer.mrmlScene.RemoveNode(segmentLabelmapNode)
  def createSampleLabelmapVolumeNode(self, volumeNode, name, label, colorNode=None):
    self.assertTrue( volumeNode != None )
    self.assertTrue( volumeNode.IsA('vtkMRMLScalarVolumeNode') )
    self.assertTrue( label > 0 )

    sampleLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
    sampleLabelmapNode.SetName(name)
    sampleLabelmapNode = slicer.mrmlScene.AddNode(sampleLabelmapNode)
    sampleLabelmapNode.Copy(volumeNode)
    imageData = vtk.vtkImageData()
    imageData.DeepCopy(volumeNode.GetImageData())
    sampleLabelmapNode.SetAndObserveImageData(imageData)

    extent = imageData.GetExtent()
    for x in xrange(extent[0], extent[1]+1):
      for y in xrange(extent[2], extent[3]+1):
        for z in xrange(extent[4], extent[5]+1):
          if (x >= (extent[1]/4) and x <= (extent[1]/4) * 3) and (y >= (extent[3]/4) and y <= (extent[3]/4) * 3) and (z >= (extent[5]/4) and z <= (extent[5]/4) * 3):
            imageData.SetScalarComponentFromDouble(x,y,z,0,label)
          else:
            imageData.SetScalarComponentFromDouble(x,y,z,0,0)

    # Display labelmap
    labelmapVolumeDisplayNode = slicer.vtkMRMLLabelMapVolumeDisplayNode()
    slicer.mrmlScene.AddNode(labelmapVolumeDisplayNode)
    if colorNode == None:
      colorNode = slicer.util.getNode('GenericAnatomyColors')
      self.assertTrue( colorNode != None )
    labelmapVolumeDisplayNode.SetAndObserveColorNodeID(colorNode.GetID())
    labelmapVolumeDisplayNode.VisibilityOn()
    sampleLabelmapNodeName = slicer.mrmlScene.GenerateUniqueName(name)
    sampleLabelmapNode.SetName(sampleLabelmapNodeName)
    sampleLabelmapNode.SetAndObserveDisplayNodeID(labelmapVolumeDisplayNode.GetID())

    return sampleLabelmapNode
Пример #10
0
    def computePreviewLabelmap(self, mergedImage, outputLabelmap):

        import vtkSegmentationCorePython as vtkSegmentationCore
        import vtkSlicerSegmentationsModuleLogicPython as vtkSlicerSegmentationsModuleLogic

        # This can be a long operation - indicate it to the user
        qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)

        masterVolumeNode = slicer.vtkMRMLScalarVolumeNode()
        slicer.mrmlScene.AddNode(masterVolumeNode)
        slicer.vtkSlicerSegmentationsModuleLogic.CopyOrientedImageDataToVolumeNode(
            self.clippedMasterImageData, masterVolumeNode)

        mergedLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
        slicer.mrmlScene.AddNode(mergedLabelmapNode)
        slicer.vtkSlicerSegmentationsModuleLogic.CopyOrientedImageDataToVolumeNode(
            mergedImage, mergedLabelmapNode)

        outputRasToIjk = vtk.vtkMatrix4x4()
        mergedImage.GetImageToWorldMatrix(outputRasToIjk)
        outputExtent = mergedImage.GetExtent()

        # Run segmentation algorithm
        import SimpleITK as sitk
        import sitkUtils
        # Read input data from Slicer into SimpleITK
        labelImage = sitk.ReadImage(
            sitkUtils.GetSlicerITKReadWriteAddress(
                mergedLabelmapNode.GetName()))
        backgroundImage = sitk.ReadImage(
            sitkUtils.GetSlicerITKReadWriteAddress(masterVolumeNode.GetName()))
        # Run watershed filter
        featureImage = sitk.GradientMagnitudeRecursiveGaussian(
            backgroundImage,
            float(self.scriptedEffect.doubleParameter("ObjectScaleMm")))
        del backgroundImage
        f = sitk.MorphologicalWatershedFromMarkersImageFilter()
        f.SetMarkWatershedLine(False)
        f.SetFullyConnected(False)
        labelImage = f.Execute(featureImage, labelImage)
        del featureImage
        # Pixel type of watershed output is the same as the input. Convert it to int16 now.
        if labelImage.GetPixelID() != sitk.sitkInt16:
            labelImage = sitk.Cast(labelImage, sitk.sitkInt16)
        # Write result from SimpleITK to Slicer. This currently performs a deep copy of the bulk data.
        sitk.WriteImage(
            labelImage,
            sitkUtils.GetSlicerITKReadWriteAddress(
                mergedLabelmapNode.GetName()))

        # Update segmentation from labelmap node and remove temporary nodes
        outputLabelmap.ShallowCopy(mergedLabelmapNode.GetImageData())
        outputLabelmap.SetImageToWorldMatrix(outputRasToIjk)
        outputLabelmap.SetExtent(outputExtent)

        slicer.mrmlScene.RemoveNode(masterVolumeNode)
        slicer.mrmlScene.RemoveNode(mergedLabelmapNode)

        qt.QApplication.restoreOverrideCursor()
Пример #11
0
  def onApply(self):

    # Get list of visible segment IDs, as the effect ignores hidden segments.
    segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
    visibleSegmentIds = vtk.vtkStringArray()
    segmentationNode.GetDisplayNode().GetVisibleSegmentIDs(visibleSegmentIds)
    if visibleSegmentIds.GetNumberOfValues() == 0:
      logging.info("Smoothing operation skipped: there are no visible segments")
      return

    # This can be a long operation - indicate it to the user
    qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)

    # Allow users revert to this state by clicking Undo
    self.scriptedEffect.saveStateForUndo()

    # Export master image data to temporary new volume node.
    # Note: Although the original master volume node is already in the scene, we do not use it here,
    # because the master volume may have been resampled to match segmentation geometry.
    import vtkSegmentationCorePython as vtkSegmentationCore
    masterVolumeNode = slicer.vtkMRMLScalarVolumeNode()
    slicer.mrmlScene.AddNode(masterVolumeNode)
    masterVolumeNode.SetAndObserveTransformNodeID(segmentationNode.GetTransformNodeID())
    slicer.vtkSlicerSegmentationsModuleLogic.CopyOrientedImageDataToVolumeNode(self.scriptedEffect.masterVolumeImageData(), masterVolumeNode)
    # Generate merged labelmap of all visible segments, as the filter expects a single labelmap with all the labels.
    mergedLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
    slicer.mrmlScene.AddNode(mergedLabelmapNode)
    slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentsToLabelmapNode(segmentationNode, visibleSegmentIds, mergedLabelmapNode, masterVolumeNode)

    # Run segmentation algorithm
    import SimpleITK as sitk
    import sitkUtils
    # Read input data from Slicer into SimpleITK
    labelImage = sitk.ReadImage(sitkUtils.GetSlicerITKReadWriteAddress(mergedLabelmapNode.GetName()))
    backgroundImage = sitk.ReadImage(sitkUtils.GetSlicerITKReadWriteAddress(masterVolumeNode.GetName()))
    # Run watershed filter
    featureImage = sitk.GradientMagnitudeRecursiveGaussian(backgroundImage, float(self.scriptedEffect.doubleParameter("ObjectScaleMm")))
    del backgroundImage
    f = sitk.MorphologicalWatershedFromMarkersImageFilter()
    f.SetMarkWatershedLine(False)
    f.SetFullyConnected(False)
    labelImage = f.Execute(featureImage, labelImage)
    del featureImage
    # Pixel type of watershed output is the same as the input. Convert it to int16 now.
    if labelImage.GetPixelID() != sitk.sitkInt16:
      labelImage = sitk.Cast(labelImage, sitk.sitkInt16)
    # Write result from SimpleITK to Slicer. This currently performs a deep copy of the bulk data.
    sitk.WriteImage(labelImage, sitkUtils.GetSlicerITKReadWriteAddress(mergedLabelmapNode.GetName()))
    mergedLabelmapNode.GetImageData().Modified()
    mergedLabelmapNode.Modified()

    # Update segmentation from labelmap node and remove temporary nodes
    slicer.vtkSlicerSegmentationsModuleLogic.ImportLabelmapToSegmentationNode(mergedLabelmapNode, segmentationNode, visibleSegmentIds)
    slicer.mrmlScene.RemoveNode(masterVolumeNode)
    slicer.mrmlScene.RemoveNode(mergedLabelmapNode)

    qt.QApplication.restoreOverrideCursor()
Пример #12
0
  def onApply(self):

    # Get list of visible segment IDs, as the effect ignores hidden segments.
    segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
    visibleSegmentIds = vtk.vtkStringArray()
    segmentationNode.GetDisplayNode().GetVisibleSegmentIDs(visibleSegmentIds)
    if visibleSegmentIds.GetNumberOfValues() == 0:
      logging.info("Smoothing operation skipped: there are no visible segments")
      return

    # This can be a long operation - indicate it to the user
    qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)

    # Allow users revert to this state by clicking Undo
    self.scriptedEffect.saveStateForUndo()

    # Export master image data to temporary new volume node.
    # Note: Although the original master volume node is already in the scene, we do not use it here,
    # because the master volume may have been resampled to match segmentation geometry.
    import vtkSegmentationCorePython as vtkSegmentationCore
    masterVolumeNode = slicer.vtkMRMLScalarVolumeNode()
    slicer.mrmlScene.AddNode(masterVolumeNode)
    masterVolumeNode.SetAndObserveTransformNodeID(segmentationNode.GetTransformNodeID())
    slicer.vtkSlicerSegmentationsModuleLogic.CopyOrientedImageDataToVolumeNode(self.scriptedEffect.masterVolumeImageData(), masterVolumeNode)
    # Generate merged labelmap of all visible segments, as the filter expects a single labelmap with all the labels.
    mergedLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
    slicer.mrmlScene.AddNode(mergedLabelmapNode)
    slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentsToLabelmapNode(segmentationNode, visibleSegmentIds, mergedLabelmapNode, masterVolumeNode)

    # Run segmentation algorithm
    import SimpleITK as sitk
    import sitkUtils
    # Read input data from Slicer into SimpleITK
    labelImage = sitk.ReadImage(sitkUtils.GetSlicerITKReadWriteAddress(mergedLabelmapNode.GetName()))
    backgroundImage = sitk.ReadImage(sitkUtils.GetSlicerITKReadWriteAddress(masterVolumeNode.GetName()))
    # Run watershed filter
    featureImage = sitk.GradientMagnitudeRecursiveGaussian(backgroundImage, float(self.scriptedEffect.doubleParameter("ObjectScaleMm")))
    del backgroundImage
    f = sitk.MorphologicalWatershedFromMarkersImageFilter()
    f.SetMarkWatershedLine(False)
    f.SetFullyConnected(False)
    labelImage = f.Execute(featureImage, labelImage)
    del featureImage
    # Pixel type of watershed output is the same as the input. Convert it to int16 now.
    if labelImage.GetPixelID() != sitk.sitkInt16:
      labelImage = sitk.Cast(labelImage, sitk.sitkInt16)
    # Write result from SimpleITK to Slicer. This currently performs a deep copy of the bulk data.
    sitk.WriteImage(labelImage, sitkUtils.GetSlicerITKReadWriteAddress(mergedLabelmapNode.GetName()))
    mergedLabelmapNode.GetImageData().Modified()
    mergedLabelmapNode.Modified()

    # Update segmentation from labelmap node and remove temporary nodes
    slicer.vtkSlicerSegmentationsModuleLogic.ImportLabelmapToSegmentationNode(mergedLabelmapNode, segmentationNode, visibleSegmentIds)
    slicer.mrmlScene.RemoveNode(masterVolumeNode)
    slicer.mrmlScene.RemoveNode(mergedLabelmapNode)

    qt.QApplication.restoreOverrideCursor()
Пример #13
0
 def getSignature(self, seg):
     if not 'labelmap' in self.__dict__ or not self.labelmap:
         self.labelmap = slicer.vtkMRMLLabelMapVolumeNode()
         slicer.mrmlScene.AddNode(self.labelmap)
     slicer.modules.segmentations.logic().ExportAllSegmentsToLabelmapNode(
         seg, self.labelmap)
     stat = vtk.vtkImageAccumulate()
     stat.SetInputData(self.labelmap.GetImageData())
     stat.Update()
     return int(round(stat.GetMean()[0] * 1e10))
    def ConvertStructureSetToLabelmap(self, use_ref_image, ref_image_node_id=None):
      import vtkSegmentationCorePython as vtkSegmentationCore

      labelmapsToSave = []

      # Get reference image volume node
      referenceVolume = None
      if ref_image_node_id is not None:
        try:
          referenceVolume = slicer.util.getNode(ref_image_node_id)
        except slicer.util.MRMLNodeNotFoundException:
          logging.error('Failed to get reference image with ID ' + str(ref_image_node_id) + '. Using image referenced by DICOM')

      # Get all segmentation nodes from the scene
      segmentationNodes = slicer.util.getNodes('vtkMRMLSegmentationNode*')

      for segmentationNode in segmentationNodes.values():
        logging.info('  Converting structure set ' + segmentationNode.GetName())
        # Set referenced volume as rasterization reference from DICOM if not explicitly specified
        if referenceVolume is None and use_ref_image == True:
          referenceVolume = slicer.vtkSlicerDicomRtImportExportModuleLogic.GetReferencedVolumeByDicomForSegmentation(
            segmentationNode)
        if referenceVolume is None and use_ref_image == True:
          logging.error('No reference volume found for segmentation ' + segmentationNode.GetName())
          continue

        # Perform conversion
        if not segmentationNode.CreateBinaryLabelmapRepresentation():
          logging.error('Failed to create binary labelmap representation for segmentation ' + segmentationNode.GetName())
          continue

        # Create labelmap volume nodes from binary labelmaps
        allSegmentIDs = vtk.vtkStringArray()
        segmentationNode.GetSegmentation().GetSegmentIDs(allSegmentIDs)
        for segmentIndex in range(allSegmentIDs.GetNumberOfValues()):
          segmentID = allSegmentIDs.GetValue(segmentIndex)

          # Create output labelmap volume
          labelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
          slicer.mrmlScene.AddNode(labelmapNode)
          labelmapName = segmentationNode.GetName() + "_" + segmentID
          labelmapNode.SetName(labelmapName)

          # Export single segment to labelmap
          singleSegmentIDArray = vtk.vtkStringArray()
          singleSegmentIDArray.InsertNextValue(segmentID)
          if not slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentsToLabelmapNode(
              segmentationNode, singleSegmentIDArray, labelmapNode, referenceVolume):
            logging.error('Failed to create labelmap from segment ' + segmentID + ' in segmentation ' + segmentationNode.GetName())
            continue

          # Append volume to list
          labelmapsToSave.append(labelmapNode)

      return labelmapsToSave
Пример #15
0
    def ConvertStructureSetToLabelmap(self):
        import vtkSegmentationCorePython as vtkSegmentationCore

        labelmapsToSave = []

        # Get all segmentation nodes from the scene
        segmentationNodes = slicer.util.getNodes('vtkMRMLSegmentationNode*')

        for segmentationNode in segmentationNodes.values():
            logging.info("  Converting structure set " +
                         segmentationNode.GetName())
            # Set referenced volume as rasterization reference
            referenceVolume = slicer.vtkSlicerDicomRtImportExportModuleLogic.GetReferencedVolumeByDicomForSegmentation(
                segmentationNode)
            if referenceVolume == None:
                logging.error("No reference volume found for segmentation " +
                              segmentationNode.GetName())
                continue

            # Perform conversion
            binaryLabelmapRepresentationName = vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName(
            )
            segmentation = segmentationNode.GetSegmentation()
            segmentation.CreateRepresentation(binaryLabelmapRepresentationName)

            # Create labelmap volume nodes from binary labelmaps
            segmentIDs = vtk.vtkStringArray()
            segmentation.GetSegmentIDs(segmentIDs)
            for segmentIndex in xrange(0, segmentIDs.GetNumberOfValues()):
                segmentID = segmentIDs.GetValue(segmentIndex)
                segment = segmentation.GetSegment(segmentID)
                binaryLabelmap = segment.GetRepresentation(
                    vtkSegmentationCore.vtkSegmentationConverter.
                    GetSegmentationBinaryLabelmapRepresentationName())
                if not binaryLabelmap:
                    logging.error(
                        "Failed to retrieve binary labelmap from segment " +
                        segmentID + " in segmentation " +
                        segmentationNode.GetName())
                    continue
                labelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
                slicer.mrmlScene.AddNode(labelmapNode)
                labelmapName = segmentationNode.GetName() + "_" + segmentID
                labelmapNode.SetName(labelmapName)
                if not slicer.vtkSlicerSegmentationsModuleLogic.CreateLabelmapVolumeFromOrientedImageData(
                        binaryLabelmap, labelmapNode):
                    logging.error("Failed to create labelmap from segment " +
                                  segmentID + " in segmentation " +
                                  segmentationNode.GetName())
                    continue

                # Append volume to list
                labelmapsToSave.append(labelmapNode)

        return labelmapsToSave
Пример #16
0
  def test_USGeometry_CreateScanlines(self):
    """ Ideally you should have several levels of tests.  At the lowest level
    tests should exercise the functionality of the logic with different inputs
    (both valid and invalid).  At higher levels your tests should emulate the
    way the user would interact with your code and confirm that it still works
    the way you intended.
    One of the most important features of the tests is that it should alert other
    developers when their changes will have an impact on the behavior of your
    module.  For example, if a developer removes a feature that you depend on,
    your test should break so they know that the feature is needed.
    """

    self.delayDisplay("Starting CreateScanlines test")

    # Setup testing data
    import urllib
    xmlFileName = 'SpineUltrasound-Lumbar-C5_config.xml'
    testDataPath = 'https://raw.githubusercontent.com/Mattel/USBoneSegmentation/master/USGeometry/Testing/Data/Curvilinear/'
    downloads = (
        (testDataPath+'SpineUltrasound-Lumbar-C5-Trimmed.mha', 'SpineUltrasound-Lumbar-C5-Trimmed.mha', slicer.util.loadLabelVolume),
        (testDataPath+'SpineUltrasound-Lumbar-C5_config.xml', xmlFileName, None),
        (testDataPath+'GroundTruth/SpineUltrasound-Lumbar-C5_Scanline_GroundTruth.mha', 'Curvilinear_Scanline_GroundTruth.mha', slicer.util.loadLabelVolume)
        )

    # Load testing data
    for url,name,loader in downloads:
      filePath = slicer.app.temporaryPath + '/' + name
      if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
        logging.info('Requesting download %s from %s...\n' % (name, url))
        urllib.urlretrieve(url, filePath)
      if loader:
        logging.info('Loading %s...' % (name,))
        loader(filePath)
    self.delayDisplay('Finished with download and loading')

    volumeNode = slicer.util.getNode(pattern="SpineUltrasound-Lumbar-C5-Trimmed")
    groundTruthNode = slicer.util.getNode(pattern="Curvilinear_Scanline_GroundTruth")
    logic = USGeometryLogic(slicer.app.temporaryPath+'/'+xmlFileName, volumeNode)
    scanlineNode = slicer.vtkMRMLLabelMapVolumeNode()
    scanlineNode.SetName("Scanline_Test")
    slicer.mrmlScene.AddNode(scanlineNode)
    scanlineDisplayNode = slicer.vtkMRMLLabelMapVolumeDisplayNode()
    colorNode = slicer.util.getNode('GenericAnatomyColors')
    scanlineDisplayNode.SetAndObserveColorNodeID(colorNode.GetID())
    slicer.mrmlScene.AddNode(scanlineDisplayNode)
    scanlineNode.AddAndObserveDisplayNodeID(scanlineDisplayNode.GetID())
    self.delayDisplay("Running createScanlines...")
    logic.createScanlines(scanlineNode)

    volumeEqualityCheck = self.compareVolumes(groundTruthNode, scanlineNode)
    if volumeEqualityCheck == True:
      self.delayDisplay('Scanline test passed!')
    else:
      self.delayDisplay('Scanline test failed!')
Пример #17
0
  def test_PathPlanning_TestEmptyMask(self):
    """Test the case for the empty mask where there is no target mask"""
    self.delayDisplay('Starting test points for empty mask')
    emptymask = slicer.vtkMRMLLabelMapVolumeNode()
    emptymask.SetAndObserveImageData(vtk.vtkImageData())

    targets = slicer.util.getNode('targets')

    #run the class PickPathsmat()
    Output = slicer.vtkMRMLMarkupsFiducialNode()
    PickPathsmat().run(emptymask, targets, Output)
    self.delayDisplay("Test passed! Empty mask doesn't break the class PickPathsmat()")
Пример #18
0
  def jumpToSegmentAndCreateScreenShot(segmentationNode, segment, widgets, center=False, crosshair=False):
    imageData = vtkSegmentationCore.vtkOrientedImageData()
    segmentID = segmentationNode.GetSegmentation().GetSegmentIdBySegment(segment)
    segmentationsLogic = slicer.modules.segmentations.logic()
    segmentationsLogic.GetSegmentBinaryLabelmapRepresentation(segmentationNode, segmentID, imageData)
    extent = imageData.GetExtent()
    if extent[1] != -1 and extent[3] != -1 and extent[5] != -1:
      tempLabel = slicer.vtkMRMLLabelMapVolumeNode()
      slicer.mrmlScene.AddNode(tempLabel)
      tempLabel.SetName(segment.GetName() + "CentroidHelper")
      segmentationsLogic.CreateLabelmapVolumeFromOrientedImageData(imageData, tempLabel)
      CustomSegmentEditorLogic.applyThreshold(tempLabel, 1)
      centroid = ModuleLogicMixin.getCentroidForLabel(tempLabel, 1)
      slicer.mrmlScene.RemoveNode(tempLabel)

      annotationNodes = []

      crosshairButton = None
      if crosshair:
        crosshairButton = CrosshairButton()
        crosshairButton.setSliceIntersectionEnabled(True)
        crosshairButton.checked = True

      for widget in widgets:
        sliceLogic = widget.sliceLogic()
        sliceNode = sliceLogic.GetSliceNode()

        if not center:
          sliceNode.JumpSliceByOffsetting(centroid[0], centroid[1], centroid[2])
        else:
          markupsLogic = slicer.modules.markups.logic()
          markupsLogic.JumpSlicesToLocation(centroid[0], centroid[1], centroid[2], True)

        dNodeProperties = ScreenShotHelper.saveSegmentDisplayProperties(segmentationNode, segment)
        segmentationNode.GetDisplayNode().SetAllSegmentsVisibility(False)
        ScreenShotHelper.setDisplayNodeProperties(segmentationNode, segment,
                                                  properties={'fill': True, 'outline': True, 'visible': True})

        if crosshairButton:
          crosshairButton.crosshairNode.SetCrosshairRAS(centroid)

        annotationNode = ScreenShotHelper.takeScreenShot("{}_Screenshot_{}_{}".format(segment.GetName(),
                                                                                      sliceNode.GetName(),
                                                                                      sliceNode.GetOrientation()),
                                                         "", widget)
        segmentationNode.GetDisplayNode().SetAllSegmentsVisibility(True)
        ScreenShotHelper.setDisplayNodeProperties(segmentationNode, segment, dNodeProperties)
        annotationNodes.append(annotationNode)
        if crosshairButton:
          crosshairButton.checked = False

      return annotationNodes[0] if len(annotationNodes) == 1 else annotationNodes
Пример #19
0
  def createLabelNodeFromSegment(segmentationNode, segmentID):
    labelNode = slicer.vtkMRMLLabelMapVolumeNode()
    slicer.mrmlScene.AddNode(labelNode)
    segmentationsLogic = slicer.modules.segmentations.logic()

    mergedImageData = vtkSegmentationCore.vtkOrientedImageData()
    segmentationNode.GenerateMergedLabelmapForAllSegments(mergedImageData, 0, None,
                                                          DICOMSegmentationExporter.vtkStringArrayFromList([segmentID]))
    if not segmentationsLogic.CreateLabelmapVolumeFromOrientedImageData(mergedImageData, labelNode):
      slicer.mrmlScene.RemoveNode(labelNode)
      return None
    labelNode.SetName("{}_label".format(segmentID))
    return labelNode
    def OnSmoothLabelMapButtonClicked(self):
        # Get working polydata
        WorkingNodeName = self.WorkingLabelMapStorage.currentNode().GetName()
        if self.SegmentationNode.GetClosedSurfaceRepresentation(
                WorkingNodeName) == None:
            self.SegmentationNode.CreateClosedSurfaceRepresentation()

        WorkingPolyData = self.SegmentationNode.GetClosedSurfaceRepresentation(
            WorkingNodeName)

        # Smooth working polydata
        logic = UsSurfaceToLandmarksLogic()
        SmoothedPolyData = logic.SmoothPolyData(
            WorkingPolyData, self.SmoothingConvergenceSlider.value,
            self.SmoothingIterationsSlider.value)

        # Convert polydata to labelmap via segmentation and vtkmodel
        SmoothedModelNode = slicer.vtkMRMLModelNode()
        SmoothedModelNode.SetName(WorkingNodeName)
        SmoothedModelNode.SetAndObservePolyData(SmoothedPolyData)
        #SmoothedModelNode

        ConvSeg = slicer.vtkMRMLSegmentationNode()
        ConvSeg.SetScene(slicer.mrmlScene)
        SegLogic = slicer.modules.segmentations.logic()
        SegLogic.ImportModelToSegmentationNode(SmoothedModelNode, ConvSeg)
        ConvSeg.CreateBinaryLabelmapRepresentation()
        ConvSeg.SetMasterRepresentationToBinaryLabelmap()

        # Clear mrmlScene of old labelmap node before exporting the new one
        #OldLabelMapNode = self.WorkingLabelMapStorage.currentNode()
        #OldLabelMapNode = slicer.util.getNode(WorkingNodeName)
        #if OldLabelMapNode != None:
        #  slicer.mrmlScene.RemoveNode(OldLabelMapNode)

        # Export segmentation label map representation to mrml node for storage in interface
        SmoothedLabelMapNode = slicer.vtkMRMLLabelMapVolumeNode()
        SmoothedLabelMapNode.SetName(WorkingNodeName + self.SmoothTag)

        LabelMapName = vtk.vtkStringArray()
        LabelMapName.InsertNextValue(WorkingNodeName)
        slicer.mrmlScene.AddNode(SmoothedLabelMapNode)
        SegLogic.ExportSegmentsToLabelmapNode(ConvSeg, LabelMapName,
                                              SmoothedLabelMapNode)
        #SmoothedLabelMapNode.SetOrigin(self.InputVolumeSelector.currentNode().GetOrigin())
        # Update working polydata in UI
        # Add new smoothed label map node to mrmlScene
        self.WorkingLabelMapStorage.setCurrentNode(SmoothedLabelMapNode)
        self.UpdateSegmentationNode()

        return True
Пример #21
0
    def createLungLabelMap(self):
        """Create the lung label map
        """
        self.applyButton.enabled = False
        if self.preProcessingWidget.filterOnRadioButton.checked:  # and not self.preProcessingWidget.filterApplication.checked:
            self.filterInputCT()

        inputNode = self.CTNode

        self.applyButton.text = "Creating Label Map..."
        # TODO: why doesn't processEvents alone make the label text change?
        self.applyButton.repaint()
        slicer.app.processEvents()

        self.labelNode = slicer.mrmlScene.AddNode(
            slicer.vtkMRMLLabelMapVolumeNode())
        name = inputNode.GetName() + '_partialLungLabelMap'
        self.labelNode.SetName(slicer.mrmlScene.GenerateUniqueName(name))

        self.preProcessingWidget.createPartialLM(inputNode, self.labelNode)

        label_image = self.labelNode.GetImageData()
        shape = list(label_image.GetDimensions())
        input_array = vtk.util.numpy_support.vtk_to_numpy(
            label_image.GetPointData().GetScalars())
        original_shape = input_array.shape
        input_array = input_array.reshape(
            shape[2], shape[1],
            shape[0])  # input_array.transpose([2, 1, 0]) would not work!

        input_image = sitk.GetImageFromArray(input_array)
        input_image.SetSpacing(self.labelNode.GetSpacing())
        input_image.SetOrigin(self.labelNode.GetOrigin())

        my_lung_splitter = lung_splitter(split_thirds=True)
        split_lm = my_lung_splitter.execute(input_image)

        split = sitk.GetArrayFromImage(split_lm)

        input_aa = vtk.util.numpy_support.vtk_to_numpy(
            label_image.GetPointData().GetScalars())

        input_aa[:] = split.reshape(original_shape)

        self.labelNode.StorableModified()
        self.labelNode.Modified()
        self.labelNode.InvokeEvent(
            slicer.vtkMRMLVolumeNode.ImageDataModifiedEvent, self.labelNode)

        SlicerUtil.changeLabelmapOpacity(0.5)
Пример #22
0
    def createLabelNodeFromSegment(segmentationNode, segmentID):
        labelNode = slicer.vtkMRMLLabelMapVolumeNode()
        slicer.mrmlScene.AddNode(labelNode)
        segmentationsLogic = slicer.modules.segmentations.logic()

        mergedImageData = vtkSegmentationCore.vtkOrientedImageData()
        segmentationNode.GenerateMergedLabelmapForAllSegments(
            mergedImageData, 0, None,
            DICOMSegmentationExporter.vtkStringArrayFromList([segmentID]))
        if not segmentationsLogic.CreateLabelmapVolumeFromOrientedImageData(
                mergedImageData, labelNode):
            slicer.mrmlScene.RemoveNode(labelNode)
            return None
        labelNode.SetName("{}_label".format(segmentID))
        return labelNode
Пример #23
0
  def test_USGeometry_SumManualSegmentations(self):
    self.delayDisplay("Starting SumManualSegmentations test")

    import urllib
    xmlFileName = 'SpineUltrasound-Lumbar-C5_config.xml'
    testDataPath = 'https://raw.githubusercontent.com/Mattel/USBoneSegmentation/master/USGeometry/Testing/Data/Curvilinear/'
    downloads = (
      (testDataPath+'SpineUltrasound-Lumbar-C5-Trimmed.mha', 'SpineUltrasound-Lumbar-C5-Trimmed.mha', slicer.util.loadLabelVolume),
      (testDataPath+'SpineUltrasound-Lumbar-C5_config.xml', xmlFileName, None),
      (testDataPath+'TestManualSegmentations/SpineUltrasound-Lumbar-C5-TestSeg1.mha', 'TestManualSegmentations/SpineUltrasound-Lumbar-C5-TestSeg1.mha', slicer.util.loadLabelVolume),
      (testDataPath+'TestManualSegmentations/SpineUltrasound-Lumbar-C5-TestSeg2.mha', 'TestManualSegmentations/SpineUltrasound-Lumbar-C5-TestSeg2.mha', slicer.util.loadLabelVolume),
      (testDataPath+'TestManualSegmentations/SpineUltrasound-Lumbar-C5-TestSeg3.mha', 'TestManualSegmentations/SpineUltrasound-Lumbar-C5-TestSeg3.mha', slicer.util.loadLabelVolume),
      (testDataPath+'GroundTruth/SummedManualSegmentations_GroundTruth.mha','SummedManualSegmentations_GroundTruth.mha', slicer.util.loadLabelVolume)
      )

    for url,name,loader in downloads:
      filePath = slicer.app.temporaryPath + '/' + name
      if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
        directoryName = os.path.dirname(filePath)
        if not os.path.exists(directoryName):
          os.makedirs(directoryName)
        logging.info('Requesting download %s from %s...\n' % (name,url))
        urllib.urlretrieve(url, filePath)
      if loader:
        logging.info('Loading %s...' % (name,))
        loader(filePath)
    self.delayDisplay('Finished with downloading and loading')

    volumeNode = slicer.util.getNode(pattern="SpineUltrasound-Lumbar-C5-Trimmed")
    groundTruthNode = slicer.util.getNode(pattern="SummedManualSegmentations_GroundTruth")
    logic = USGeometryLogic(slicer.app.temporaryPath+'/'+xmlFileName, volumeNode)
    summedManualSegNode = slicer.vtkMRMLLabelMapVolumeNode()
    summedManualSegNode.SetName("SummedManualSegmentations_Test")
    slicer.mrmlScene.AddNode(summedManualSegNode)
    summedManualSegDisplayNode = slicer.vtkMRMLLabelMapVolumeDisplayNode()
    colorNode = slicer.util.getNode('GenericAnatomyColors')
    summedManualSegDisplayNode.SetAndObserveColorNodeID(colorNode.GetID())
    slicer.mrmlScene.AddNode(summedManualSegDisplayNode)
    summedManualSegNode.AddAndObserveDisplayNodeID(summedManualSegDisplayNode.GetID())

    self.delayDisplay("Running sumManualSegmentations...")
    logic.sumManualSegmentations(slicer.app.temporaryPath+'/TestManualSegmentations', summedManualSegNode)

    volumeEqualityCheck = self.compareVolumes(groundTruthNode, summedManualSegNode)
    if volumeEqualityCheck == True:
      self.delayDisplay("Summed manual segmentations test passed!")
    else:
      self.delayDisplay("Summed manual segmentations test failed!")
Пример #24
0
 def getSegmentCentroid(segmentationNode, segment):
   imageData = vtkSegmentationCore.vtkOrientedImageData()
   segmentID = segmentationNode.GetSegmentation().GetSegmentIdBySegment(segment)
   segmentationsLogic = slicer.modules.segmentations.logic()
   segmentationsLogic.GetSegmentBinaryLabelmapRepresentation(segmentationNode, segmentID, imageData)
   extent = imageData.GetExtent()
   if extent[1] != -1 and extent[3] != -1 and extent[5] != -1:
     tempLabel = slicer.vtkMRMLLabelMapVolumeNode()
     slicer.mrmlScene.AddNode(tempLabel)
     tempLabel.SetName(segment.GetName() + "CentroidHelper")
     segmentationsLogic.CreateLabelmapVolumeFromOrientedImageData(imageData, tempLabel)
     CustomSegmentEditorLogic.applyThreshold(tempLabel, 1)
     centroid = ModuleLogicMixin.getCentroidForLabel(tempLabel, 1)
     slicer.mrmlScene.RemoveNode(tempLabel)
     return centroid
   return None
Пример #25
0
 def getSegmentCentroid(segmentationNode, segment):
   imageData = vtkSegmentationCore.vtkOrientedImageData()
   segmentID = segmentationNode.GetSegmentation().GetSegmentIdBySegment(segment)
   segmentationsLogic = slicer.modules.segmentations.logic()
   segmentationsLogic.GetSegmentBinaryLabelmapRepresentation(segmentationNode, segmentID, imageData)
   extent = imageData.GetExtent()
   if extent[1] != -1 and extent[3] != -1 and extent[5] != -1:
     tempLabel = slicer.vtkMRMLLabelMapVolumeNode()
     slicer.mrmlScene.AddNode(tempLabel)
     tempLabel.SetName(segment.GetName() + "CentroidHelper")
     segmentationsLogic.CreateLabelmapVolumeFromOrientedImageData(imageData, tempLabel)
     CustomSegmentEditorLogic.applyThreshold(tempLabel, 1)
     centroid = ModuleLogicMixin.getCentroidForLabel(tempLabel, 1)
     slicer.mrmlScene.RemoveNode(tempLabel)
     return centroid
   return None
    def ConvertStructureSetToLabelmap(self):
      import vtkSegmentationCorePython as vtkSegmentationCore

      labelmapsToSave = []

      # Get all segmentation nodes from the scene
      segmentationNodes = slicer.util.getNodes('vtkMRMLSegmentationNode*')

      for segmentationNode in segmentationNodes.values():
        logging.info('  Converting structure set ' + segmentationNode.GetName())
        # Set referenced volume as rasterization reference
        referenceVolume = slicer.vtkSlicerDicomRtImportExportModuleLogic.GetReferencedVolumeByDicomForSegmentation(
          segmentationNode)
        if referenceVolume == None:
          logging.error('No reference volume found for segmentation ' + segmentationNode.GetName())
          continue

        # Perform conversion
        binaryLabelmapRepresentationName = vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName()
        segmentation = segmentationNode.GetSegmentation()
        segmentation.CreateRepresentation(binaryLabelmapRepresentationName)

        # Create labelmap volume nodes from binary labelmaps
        segmentIDs = vtk.vtkStringArray()
        segmentation.GetSegmentIDs(segmentIDs)
        for segmentIndex in xrange(0, segmentIDs.GetNumberOfValues()):
          segmentID = segmentIDs.GetValue(segmentIndex)
          segment = segmentation.GetSegment(segmentID)
          binaryLabelmap = segment.GetRepresentation(
            vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName())
          if not binaryLabelmap:
            logging.error(
              'Failed to retrieve binary labelmap from segment ' + segmentID + ' in segmentation ' + segmentationNode.GetName())
            continue
          labelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
          slicer.mrmlScene.AddNode(labelmapNode)
          labelmapName = segmentationNode.GetName() + "_" + segmentID
          labelmapNode.SetName(labelmapName)
          if not slicer.vtkSlicerSegmentationsModuleLogic.CreateLabelmapVolumeFromOrientedImageData(
              binaryLabelmap, labelmapNode):
            logging.error('Failed to create labelmap from segment ' + segmentID + ' in segmentation ' + segmentationNode.GetName())
            continue

          # Append volume to list
          labelmapsToSave.append(labelmapNode)

      return labelmapsToSave
def swissSkullStripper(volumeNode):
    atlasImageNode = dataReader(ATLAS_FOLDER_PATH + DIR_DIVIDER +
                                'atlasImage.mha')
    atlasMaskNode = dataReader(ATLAS_FOLDER_PATH + DIR_DIVIDER +
                               'atlasMask.mha')
    parameters = {}
    parameters["patientVolume"] = volumeNode.GetID()
    outVolume = slicer.vtkMRMLScalarVolumeNode()
    slicer.mrmlScene.AddNode(outVolume)
    parameters["patientOutputVolume"] = outVolume.GetID()
    labelVolume = slicer.vtkMRMLLabelMapVolumeNode()
    slicer.mrmlScene.AddNode(labelVolume)
    parameters["patientMaskLabel"] = labelVolume.GetID()
    parameters["atlasMRIVolume"] = atlasImageNode.GetID()
    parameters["atlasMaskVolume"] = atlasMaskNode.GetID()
    return (slicer.cli.runSync(slicer.modules.swissskullstripper, None,
                               parameters))
Пример #28
0
def labelMapSmoothing(inImg, outImg, sigma=0.2):
    '''Label map smoothing using slicer.cli.run()
    inImg: the input image path. Expects a label map;
    outImg: the output image (to be saved) path;
    sigma: the Gaussian sigma for smoothing.'''
    node = slicer.util.loadLabelVolume(inImg)
    cliModule = slicer.modules.labelmapsmoothing
    outVolume = slicer.vtkMRMLLabelMapVolumeNode()
    slicer.mrmlScene.AddNode(outVolume)
    p = {}
    p['inputVolume'] = node.GetID()
    p['outputVolume'] = outVolume.GetID()
    p['gaussianSigma'] = sigma
    slicer.cli.run(cliModule, None, p, wait_for_completion=True)
    slicer.util.saveNode(outVolume, outImg)
    dilateLabelMap(outImg, outImg)
    slicer.mrmlScene.Clear(0)
    return {outImg: True}
Пример #29
0
  def labelMapFromClippingModel(self, inputVolume, outputLabelValue=1, outputLabelMap=None):
    if not outputLabelMap:
      outputLabelMap = slicer.vtkMRMLLabelMapVolumeNode()
      slicer.mrmlScene.AddNode(outputLabelMap)

    if self.outputLabelValue:
      outputLabelValue = self.outputLabelValue

    params = {'sampleDistance': 0.1, 'labelValue': outputLabelValue, 'InputVolume': inputVolume.GetID(),
              'surface': self.clippingModelNode.GetID(), 'OutputVolume': outputLabelMap.GetID()}

    logging.debug(params)
    slicer.cli.run(slicer.modules.modeltolabelmap, None, params, wait_for_completion=True)

    if self.colorNode:
      displayNode = outputLabelMap.GetDisplayNode()
      displayNode.SetAndObserveColorNodeID(self.colorNode.GetID())
    return outputLabelMap
    def VolumeThresholdToLabelMap(self, VolumeNode, Threshold):

        LabelMapNode = slicer.vtkMRMLLabelMapVolumeNode()
        LabelMapNode.SetSpacing(VolumeNode.GetSpacing())

        # Apply threshold
        Thresholder = vtk.vtkImageThreshold()
        Thresholder.SetInputData(VolumeNode.GetImageData())
        Thresholder.SetInValue(1)
        Thresholder.SetOutValue(0)
        Thresholder.ThresholdBetween(Threshold, 255)
        Thresholder.Update()

        LabelMapNode.SetAndObserveImageData(Thresholder.GetOutput())
        LabelMapNode.SetOrigin(VolumeNode.GetOrigin())
        mat = vtk.vtkMatrix4x4()
        VolumeNode.GetIJKToRASDirectionMatrix(mat)
        LabelMapNode.SetIJKToRASDirectionMatrix(mat)
        return LabelMapNode
    def ErodeLabelMap(self, LabelMapNode, ErosionKernelSize):

        # Initialize new label map node
        ErodedLabelMapNode = slicer.vtkMRMLLabelMapVolumeNode()
        ErodedLabelMapNode.SetSpacing(LabelMapNode.GetSpacing())
        ErodedLabelMapNode.SetOrigin(LabelMapNode.GetOrigin())

        # Intialize vtkImageDilateErode3D
        Eroder = vtk.vtkImageDilateErode3D()
        Eroder.SetErodeValue(1)
        Eroder.SetDilateValue(0)
        Eroder.SetKernelSize(ErosionKernelSize[0], ErosionKernelSize[1],
                             ErosionKernelSize[2])

        # Erode label map
        Eroder.SetInputData(LabelMapNode.GetImageData())
        Eroder.Update()
        ErodedLabelMapNode.SetAndObserveImageData(Eroder.GetOutput())

        return ErodedLabelMapNode
Пример #32
0
    def __init__(self):
        # Segmentation module (Loadable) to export segmentation to label map
        self.segmentationModuleLogic = slicer.modules.segmentations.logic()
        self.segmentationNode = None
        self.labelMapNode = slicer.vtkMRMLLabelMapVolumeNode()
        self.labelMapNode.SetHideFromEditors(1)
        slicer.mrmlScene.AddNode(self.labelMapNode)

        # Matlab module (CLI) to create a mesh from the label map
        self.image2MeshModule = slicer.modules.image2mesh
        self.image2MeshCLINode = slicer.cli.createNode(self.image2MeshModule)
        self.image2MeshCLINode.AddObserver(
            self.image2MeshCLINode.StatusModifiedEvent,
            self.onImage2MeshModified)
        self.image2MeshParameters = {}

        self.meshTypes = [
            'Standard', 'Fluorescence', 'Spectral', 'BEM', 'BEM Fluorescence',
            'BEM Spectral', 'SPN'
        ]
    def OnDecimateLabelMapButtonClicked(self):
        # Get working polydata
        WorkingNodeName = self.WorkingLabelMapStorage.currentNode().GetName()
        if self.SegmentationNode.GetClosedSurfaceRepresentation(
                WorkingNodeName) == None:
            self.SegmentationNode.CreateClosedSurfaceRepresentation()
        WorkingPolyData = self.SegmentationNode.GetClosedSurfaceRepresentation(
            WorkingNodeName)

        # Decimate working polydata
        logic = UsSurfaceToLandmarksLogic()
        DecimatedPolyData = logic.DecimatePolyData(WorkingPolyData)

        # Convert polydata to labelmap via segmentation and vtkmodel
        DecimatedModelNode = slicer.vtkMRMLModelNode()
        DecimatedModelNode.SetName(WorkingNodeName)
        DecimatedModelNode.SetAndObservePolyData(DecimatedPolyData)

        ConvSeg = slicer.vtkMRMLSegmentationNode()
        ConvSeg.SetScene(slicer.mrmlScene)
        SegLogic = slicer.modules.segmentations.logic()
        SegLogic.ImportModelToSegmentationNode(DecimatedModelNode, ConvSeg)
        ConvSeg.CreateBinaryLabelmapRepresentation()
        ConvSeg.SetMasterRepresentationToBinaryLabelmap()

        LabelMapName = vtk.vtkStringArray()
        LabelMapName.InsertNextValue(WorkingNodeName)

        DecimatedLabelMapNode = slicer.vtkMRMLLabelMapVolumeNode()
        DecimatedLabelMapNode.SetName(WorkingNodeName)
        slicer.mrmlScene.AddNode(DecimatedLabelMapNode)

        SegLogic.ExportSegmentsToLabelmapNode(ConvSeg, LabelMapName,
                                              DecimatedLabelMapNode)
        #SmoothedOrientedImageData = ConvSeg.GetBinaryLabelmapRepresentation(WorkingNodeName)
        #DecimatedLabelMapNode.SetAndObserveImageData(SmoothedOrientedImageData)
        # Update working polydata in UI
        self.WorkingLabelMapStorage.setCurrentNode(DecimatedLabelMapNode)
        self.UpdateSegmentationNode()

        return True
Пример #34
0
def test():
    import vtk, qt, ctk, slicer
    import os

    slicer.modules.DeerSegmentorWidget.onBtnInitializeStudy()
    for sid, deer in slicer.modules.DeerSegmentorWidget.logic.deers.items():
        if not deer.db_info["done"] == '1':
            continue
        #open deer
        slicer.modules.DeerSegmentorWidget.logic.load_deer(sid)

        segmentation_node = slicer.mrmlScene.GetNodesByClass(
            "vtkMRMLSegmentationNode").GetItemAsObject(0)
        accepted = ["mask", "non-liver", "worm"]

        volume = deer.node_dict[deer.t1_path]
        labelmap_node = slicer.vtkMRMLLabelMapVolumeNode()

        for seg_name in accepted:
            print(f"exporting segement {seg_name}...")
            segment = segmentation_node.GetSegmentation().GetSegment(seg_name)
            segments = vtk.vtkStringArray()
            segments.SetNumberOfValues(1)
            segments.SetValue(0, segment.GetName())

            slicer.mrmlScene.AddNode(labelmap_node)
            slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentsToLabelmapNode(
                segmentation_node, segments, labelmap_node, volume)

            myStorageNode = labelmap_node.CreateDefaultStorageNode()
            myStorageNode.SetFileName(
                os.path.join(deer.slicer_out_dir, f"{seg_name}.nii.gz"))
            myStorageNode.WriteData(labelmap_node)
            slicer.mrmlScene.RemoveNode(myStorageNode)

        slicer.mrmlScene.RemoveNode(labelmap_node)

        #close deer
        slicer.modules.DeerSegmentorWidget.logic.close_active_deer(True)
    def OnRemoveIslandsButtonClicked(self):
        logic = UsSurfaceToLandmarksLogic()
        WorkingLabelMap = self.WorkingLabelMapStorage.currentNode()
        WorkingImageData = WorkingLabelMap.GetImageData()

        # Clear mrmlScene of old labelmap node before exporting the new one
        OldLabelMapNode = self.WorkingLabelMapStorage.currentNode()
        if OldLabelMapNode != None:
            slicer.mrmlScene.RemoveNode(OldLabelMapNode)

        print "DEBUG - About to remove islands"

        LabelMapIslandsRemoved = logic.RemoveCoronalIslands(
            WorkingImageData, self.IslandSizeThresholdSlider.value)
        LabelMapIslandsRemoved.SetName(WorkingLabelMap.GetName())
        print "DEBUG - Islands removed"

        ConvSeg = slicer.vtkMRMLSegmentationNode()
        ConvSeg.SetScene(slicer.mrmlScene)
        SegLogic = slicer.modules.segmentations.logic()
        SegLogic.ImportLabelmapToSegmentationNode(LabelMapIslandsRemoved,
                                                  ConvSeg)
        ConvSeg.CreateBinaryLabelmapRepresentation()
        ConvSeg.SetMasterRepresentationToBinaryLabelmap()

        LabelMapName = vtk.vtkStringArray()
        LabelMapName.InsertNextValue(WorkingLabelMap.GetName())
        DeislandedLabelMapNode = slicer.vtkMRMLLabelMapVolumeNode()
        DeislandedLabelMapNode.SetName(WorkingLabelMap.GetName())
        slicer.mrmlScene.AddNode(DeislandedLabelMapNode)
        SegLogic.ExportSegmentsToLabelmapNode(ConvSeg, LabelMapName,
                                              DeislandedLabelMapNode)

        # Update mrmlScene and UI
        #slicer.mrmlScene.AddNode(LabelMapIslandsRemoved)
        self.WorkingLabelMapStorage.setCurrentNode(DeislandedLabelMapNode)
        self.UpdateSegmentationNode()

        return True
    def applyTransform(self, image, roi, transform):
        # create new volumes
        roiNew = slicer.vtkMRMLLabelMapVolumeNode()
        roiNew.SetName(image.GetName() + '-label')
        slicer.mrmlScene.AddNode(roiNew)

        transform.Inverse()

        # resample roi using inverse transform
        parameters = {}
        parameters["inputVolume"] = roi
        parameters["referenceVolume"] = image
        parameters["outputVolume"] = roiNew
        parameters["pixelType"] = "int"
        parameters["warpTransform"] = transform
        parameters["interpolationMode"] = "NearestNeighbor"
        # call module
        cliNode = None
        cliNode = slicer.cli.run(slicer.modules.brainsresample, cliNode,
                                 parameters)
        print(cliNode.AddObserver('ModifiedEvent', self.printStatus))

        return roiNew
Пример #37
0
    def convertSegmentation(self, segPath, volPath, binLabelOutPath):
        """This function will take in the path to a segmentation file,
    a nrrd volume file, and the desired output path for the binary labelmap.
    It will load the segmentation into slicer, find the segmentation id for
    the colon segment, and convert that segment into a binary labelmap.
    It will save it to the output path parameter. """
        success, segNode = slicer.util.loadSegmentation(segPath,
                                                        returnNode=True)
        segmentation = segNode.GetSegmentation()
        segID = segmentation.GetSegmentIdBySegmentName('colon')
        segment = segmentation.GetSegment(segID)

        labelMapNode = slicer.vtkMRMLLabelMapVolumeNode()
        slicer.mrmlScene.AddNode(labelMapNode)

        success, referenceNode = slicer.util.loadVolume(volPath,
                                                        returnNode=True)
        segToExport = vtk.vtkStringArray()
        segToExport.InsertNextValue(segID)
        slicer.modules.segmentations.logic().ExportSegmentsToLabelmapNode(
            segNode, segToExport, labelMapNode, referenceNode)
        slicer.util.saveNode(labelMapNode, binLabelOutPath)
        logging.info("Saved: " + binLabelOutPath)
    def baselineSpace(self, baselineImage, rois, transforms):

        for x in range(1, len(rois)):
            if (rois[x].GetName() != None):
                # create new volumes
                roiNew = slicer.vtkMRMLLabelMapVolumeNode()
                roiNew.SetName(rois[x].GetName() + '_baselineSpace')
                slicer.mrmlScene.AddNode(roiNew)

                # resample roi using inverse transform
                parameters = {}
                parameters["inputVolume"] = rois[x]
                parameters["referenceVolume"] = baselineImage
                parameters["outputVolume"] = roiNew
                parameters["pixelType"] = "int"
                parameters["warpTransform"] = transforms[x - 1]
                parameters["interpolationMode"] = "NearestNeighbor"
                # call module
                cliNode = None
                cliNode = slicer.cli.run(slicer.modules.brainsresample,
                                         cliNode, parameters)
                print(cliNode.AddObserver('ModifiedEvent', self.printStatus))

        return roiNew
Пример #39
0
  def findLargest2DRegion(segmentationNode):
    qrLogic = CustomSegmentEditorLogic
    segmentationsLogic = slicer.modules.segmentations.logic()

    largestLM = None
    largestSize = 0
    for segment in qrLogic.getAllSegments(segmentationNode):
      imageData = vtkSegmentationCore.vtkOrientedImageData()
      segmentID = segmentationNode.GetSegmentation().GetSegmentIdBySegment(segment)
      segmentationsLogic.GetSegmentBinaryLabelmapRepresentation(segmentationNode, segmentID, imageData)
      extent = imageData.GetExtent()

      if extent[1] != -1 and extent[3] != -1 and extent[5] != -1:
        tempLabel = slicer.vtkMRMLLabelMapVolumeNode()
        tempLabel.SetName(segment.GetName() + "CentroidHelper")
        segmentationsLogic.CreateLabelmapVolumeFromOrientedImageData(imageData, tempLabel)

        dims = tempLabel.GetImageData().GetDimensions()
        size = dims[0]*dims[1]
        if size > largestSize:
          largestSize = size
          largestLM = tempLabel

    return largestLM
Пример #40
0
  def test_SEGExporterSelfTest1(self):
    """ Test DICOM import, segmentation, export
    """
    self.messageDelay = 50

    import os
    self.delayDisplay("Starting the DICOM SEG Export test")

    #
    # first, get the data - a zip file of dicom data
    #
    filePath = self.logic.downloadSampleData()
    self.delayDisplay('Finished with download\n')

    self.delayDisplay("Unzipping")
    dicomFilesDirectory = self.logic.unzipSampleData(filePath)

    try:
      self.delayDisplay("Switching to temp database directory")
      tempDatabaseDirectory = slicer.app.temporaryPath + '/tempDICOMDatabase'
      import shutil
      try:
        shutil.rmtree(tempDatabaseDirectory)
      except OSError:
        pass
      qt.QDir().mkpath(tempDatabaseDirectory)
      if slicer.dicomDatabase:
        originalDatabaseDirectory = os.path.split(slicer.dicomDatabase.databaseFilename)[0]
      else:
        originalDatabaseDirectory = None
        settings = qt.QSettings()
        settings.setValue('DatabaseDirectory', tempDatabaseDirectory)
      dicomWidget = slicer.modules.dicom.widgetRepresentation().self()
      dicomWidget.onDatabaseDirectoryChanged(tempDatabaseDirectory)

      self.delayDisplay('Importing DICOM')
      mainWindow = slicer.util.mainWindow()
      mainWindow.moduleSelector().selectModule('DICOM')

      self.logic.importIntoDICOMDatabase(dicomFilesDirectory)

      dicomWidget.detailsPopup.open()

      # load the data by series UID
      mrHeadSeriesUID = "2.16.840.1.113662.4.4168496325.1025306170.548651188813145058"
      dicomWidget.detailsPopup.offerLoadables(mrHeadSeriesUID, 'Series')
      dicomWidget.detailsPopup.examineForLoading()
      self.delayDisplay('Loading Selection')
      dicomWidget.detailsPopup.loadCheckedLoadables()

      #
      # create a label map and set it for editing
      #
      masterNode = slicer.util.getNode('2: SAG*')
      volumesLogic = slicer.modules.volumes.logic()
      mergeNode = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, masterNode, masterNode.GetName() + '-label' )
      mergeNode.GetDisplayNode().SetAndObserveColorNodeID('vtkMRMLColorTableNodeFileGenericAnatomyColors.txt')
      selectionNode = slicer.app.applicationLogic().GetSelectionNode()
      selectionNode.SetReferenceActiveVolumeID( masterNode.GetID() )
      selectionNode.SetReferenceActiveLabelVolumeID( mergeNode.GetID() )
      slicer.app.applicationLogic().PropagateVolumeSelection(0)

      #
      # go to the editor and do some drawing
      #
      slicer.util.selectModule('Editor')

      import EditorLib
      from EditorLib.EditUtil import EditUtil
      parameterNode = EditUtil.getParameterNode()
      parameterNode.SetParameter("LabelEffect,paintThreshold", "1")
      parameterNode.SetParameter("LabelEffect,paintThresholdMin", "70.0")
      parameterNode.SetParameter("LabelEffect,paintThresholdMax", "279.75")
      parameterNode.SetParameter("PaintEffect,radius", "40")
      parameterNode.SetParameter("PaintEffect,sphere", "1")

      self.delayDisplay("Paint some things")
      parameterNode = EditUtil.getParameterNode()
      lm = slicer.app.layoutManager()
      paintEffect = EditorLib.PaintEffectOptions()
      paintEffect.setMRMLDefaults()
      paintEffect.__del__()
      sliceWidget = lm.sliceWidget('Red')
      paintTool = EditorLib.PaintEffectTool(sliceWidget)
      EditUtil.setLabel(1)
      paintTool.paintAddPoint(100,100)
      paintTool.paintApply()
      EditUtil.setLabel(2)
      paintTool.paintAddPoint(200,200)
      paintTool.paintApply()
      paintTool.cleanup()
      paintTool = None

      # save these to compare with the one we read back
      originalSegmentationArray = slicer.util.array(mergeNode.GetID())
      originalSegmentationNodeCopy = slicer.vtkMRMLLabelMapVolumeNode()
      originalSegmentationNodeCopy.CopyOrientation(mergeNode)

      # export the volumes into a SEG
      tempSEGDirectory = slicer.app.temporaryPath + '/tempDICOMSEG'
      qt.QDir().mkpath(tempSEGDirectory)
      segFilePath = os.path.join(tempSEGDirectory, "test.SEG.dcm")


      self.delayDisplay('spliting...', 200)
      EditUtil.splitPerStructureVolumes(masterNode, mergeNode)

      self.delayDisplay('exporting...', 200)
      EditUtil.exportAsDICOMSEG(masterNode)

      # close scene re-load the input data and SEG
      slicer.mrmlScene.Clear(0)
      indexer = ctk.ctkDICOMIndexer()
      indexer.addDirectory(slicer.dicomDatabase, tempSEGDirectory, None)
      indexer.waitForImportFinished()

      mrHeadStudyUID = "2.16.840.1.113662.4.4168496325.1025305873.7118351817185979330"
      dicomWidget.detailsPopup.offerLoadables(mrHeadStudyUID, 'Study')
      dicomWidget.detailsPopup.examineForLoading()
      self.delayDisplay('Loading Selection')
      dicomWidget.detailsPopup.loadCheckedLoadables()

      # confirm that segmentations are correctly reloaded
      headLabelName = '2: SAG/RF-FAST/VOL/FLIP 30-label'
      reloadedLabel = slicer.util.getNode(headLabelName)
      reloadedSegmentationArray = slicer.util.array(reloadedLabel.GetID())

      import numpy
      self.assertTrue(numpy.alltrue(originalSegmentationArray == reloadedSegmentationArray))
      geometryWarnings = volumesLogic.CompareVolumeGeometry(mergeNode, reloadedLabel)
      print(geometryWarnings)
      self.assertTrue(geometryWarnings == '')

      # re-export

      # close scene re-load the input data and SEG

      # confirm that segmentations are available again as per-structure volumes


      self.delayDisplay('Test passed!')
    except Exception, e:
      import traceback
      traceback.print_exc()
      self.delayDisplay('Test caused exception!\n' + str(e))
Пример #41
0
    def run(self, inputVolume, Index):

        logging.info('Processing started')

        DosiFilmImage = inputVolume

        logging.info(DosiFilmImage)
        date = datetime.datetime.now()
        savepath = u"//s-grp/grp/RADIOPHY/Personnel/Aurélien Corroyer-Dulmont/3dSlicer/Field_Center_vs_Jaw_setting_TOMOTHERAPY_QC_Results/Results_" + str(
            date.day) + str(date.month) + str(date.year) + ".txt"

        logging.info(savepath)
        logging.info(Index)

        #### To get background intensity for the thershold value of the bloc
        # Create segmentation
        segmentationNode = slicer.vtkMRMLSegmentationNode()
        slicer.mrmlScene.AddNode(segmentationNode)
        segmentationNode.CreateDefaultDisplayNodes()  # only needed for display
        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
            DosiFilmImage)

        # Create segment
        backgroundSeed = vtk.vtkSphereSource()
        backgroundSeed.SetCenter(-40, -30, 0)
        backgroundSeed.SetRadius(5)
        backgroundSeed.Update()
        segmentationNode.AddSegmentFromClosedSurfaceRepresentation(
            backgroundSeed.GetOutput(), "Segment A", [1.0, 0.0, 0.0])

        mergedLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
        slicer.mrmlScene.AddNode(mergedLabelmapNode)
        sa = vtk.vtkStringArray()
        sa.InsertNextValue("Segment A")
        slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentsToLabelmapNode(
            segmentationNode, sa, mergedLabelmapNode, DosiFilmImage)

        label = su.PullVolumeFromSlicer("LabelMapVolume")
        image = su.PullVolumeFromSlicer(DosiFilmImage)
        stat_filter_backgroundSeed = sitk.LabelIntensityStatisticsImageFilter()
        stat_filter_backgroundSeed.Execute(label, image)  #attention à l'ordre
        meanBackground = stat_filter_backgroundSeed.GetMean(1)
        print(meanBackground)

        # Stockage du nom de la machine en utilisant le choix de l'utilisateur dans la class Widget
        if Index == 0:
            machineName = 'Tomotherapy 1'
        else:
            machineName = 'Tomotherapy 2'

        # Création de la segmentation
        segmentationNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentationNode")
        segmentationNode.CreateDefaultDisplayNodes()
        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
            DosiFilmImage)

        logging.info(segmentationNode)

        # Création des segments editors temporaires
        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentEditorNode")
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(segmentationNode)
        segmentEditorWidget.setMasterVolumeNode(DosiFilmImage)

        # Création d'un segment après seuillage
        addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment(
            "IrradiatedBlocks")
        segmentEditorNode.SetSelectedSegmentID(addedSegmentID)
        segmentEditorWidget.setActiveEffectByName("Threshold")
        effect = segmentEditorWidget.activeEffect()
        #effect.setParameter("MinimumThreshold",str(22000))
        #effect.setParameter("MaximumThreshold",str(55000))
        effect.setParameter("MinimumThreshold", str(meanBackground / 5))
        effect.setParameter("MaximumThreshold", str(meanBackground / 1.2))
        effect.self().onApply()

        # Passage en mode closed surface pour calcul des centres
        n = slicer.util.getNode('Segmentation_1')
        s = n.GetSegmentation()
        ss = s.GetSegment('IrradiatedBlocks')
        ss.AddRepresentation('Closed surface', vtk.vtkPolyData())

        # Division du segment en plusieurs segments (un par bloc d'irradiation)
        segmentEditorWidget.setActiveEffectByName("Islands")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("Operation", str("SPLIT_ISLANDS_TO_SEGMENTS"))
        effect.setParameter("MinimumSize", 1000)
        effect.self().onApply()

        ######### Initialisation des variables fixes d'intérêt###########
        Segmentation_Name = 'Segmentation_1'
        Segment_Name = [
            "IrradiatedBlocks", "IrradiatedBlocks -_1", "IrradiatedBlocks -_2",
            "IrradiatedBlocks -_3", "IrradiatedBlocks -_4",
            "IrradiatedBlocks -_5", "IrradiatedBlocks -_6"
        ]
        ListYaxisCenterOfBlock = [
            0, 0, 0, 0, 0, 0, 0
        ]  # initialisation de la liste contenant les valeurs Y centrales des blocs

        # Boucle de calcul des centres pour les 7 blocs (segment)
        i = 0
        while i < len(Segment_Name):
            n = slicer.util.getNode(Segmentation_Name)
            s = n.GetSegmentation()
            ss = s.GetSegment(Segment_Name[i])
            pd = ss.GetRepresentation('Closed surface')
            com = vtk.vtkCenterOfMass()
            com.SetInputData(pd)
            com.Update()
            com.GetCenter()  # A voir mais je pense que cette ligne est inutile
            CenterOfBlock = com.GetCenter(
            )  # CenterOfBlock est alors un tuple avec plusieurs variables (coordonées x,y,z)
            YaxisCenterOfBlock = (
                CenterOfBlock[1]
            )  # Sélection de la 2ème valeur du tuple (indice 1) qui est la valeur dans l'axe Y qui est l'unique valeure d'intérêt
            YaxisCenterOfBlock = abs(
                YaxisCenterOfBlock)  # On passe en valeur absolue
            ListYaxisCenterOfBlock[i] = YaxisCenterOfBlock
            i += 1

        logging.info(ListYaxisCenterOfBlock)

        ######### Calcul de la différence en Y entre les centres des différents blocs###########
        MaxYaxisCenter = max(ListYaxisCenterOfBlock)
        MinYaxisCenter = min(ListYaxisCenterOfBlock)
        DifferenceMaxInPixelYCenters = MaxYaxisCenter - MinYaxisCenter
        DifferenceMaxInMmYCenters = float(DifferenceMaxInPixelYCenters)
        DifferenceMaxInMmYCenters = DifferenceMaxInMmYCenters * 0.3528  # Pas élégant mais si je ne fais pas ça, il initialise DifferenceMaxInMmYCenters en tuple et pas en variable...

        ### Enonciation des résultats ###
        logging.info("Coordonnee Max en Y : " + str(MaxYaxisCenter))
        logging.info("Coordonnee Min en Y : " + str(MinYaxisCenter))
        logging.info("Difference maximale entre les blocs (en pixel) : " +
                     str(DifferenceMaxInPixelYCenters))
        logging.info("Difference maximale entre les blocs (en mm) : " +
                     str(DifferenceMaxInMmYCenters))

        ######### Création et remplissage fichier text pour stocker les résultats###########
        file = open(savepath, 'w')

        ### encodage du fichier pour écriture incluant les "é" ###
        file = codecs.open(savepath, encoding='utf-8')
        txt = file.read()
        file = codecs.open(savepath, "w", encoding='mbcs')

        date = datetime.datetime.now()
        file.write(u"Résultats test -Field Center vs Jaw setting-")
        file.write("\n\n")
        file.write("Machine : " + str(machineName))
        file.write("\n\n")
        file.write("Date : " + str(date.day) + "/" + str(date.month) + "/" +
                   str(date.year))
        file.write("\n\n")
        file.write("\n\n")
        i = 0

        for i in range(
                len(ListYaxisCenterOfBlock)
        ):  # Boucle pour obtenir les coordonées Y des centres des 7 blocs
            file.write(u"Coordonnée Y du centre du bloc n°" + str(i + 1) +
                       ": ")
            file.write(str(ListYaxisCenterOfBlock[i]))
            file.write("\n\n")

        file.write("\n\n")
        file.write(u"Coordonnée Max en Y : " + str(MaxYaxisCenter))
        file.write("\n\n")
        file.write(u"Coordonnée Min en Y : " + str(MinYaxisCenter))
        file.write("\n\n")
        file.write(u"Différence maximale entre les blocs (en pixel) : " +
                   str(DifferenceMaxInPixelYCenters))
        file.write("\n\n")
        file.write(u"Différence maximale entre les blocs (en mm) : " +
                   str(DifferenceMaxInMmYCenters))

        ######### Calcul de la conformité et mention dans le fichier résultats###########
        if 0 <= DifferenceMaxInMmYCenters < 0.5:
            Result = "Conforme"
        elif DifferenceMaxInMmYCenters > 0.5:
            Result = "Hors tolerance"
        else:
            Result = "Limite"  #car si pas < ou > à 0.5 alors = à 0.5

        if DifferenceMaxInMmYCenters < 0:
            logging.info(
                u"Valeur de la différence négative, problème dans l'image ou dans le programme, contactez Aurélien Corroyer-Dulmont tel : 5768"
            )

        logging.info(Result)

        file.write("\n\n")
        file.write("\n\n")
        file.write(u"Résultat : " + str(Result))
        file.close()

        logging.info('Processing completed')
        logging.info('\n\nResults are in the following file : ' + savepath)
        return True
  def TestSection_3_ImportExportSegment(self):
    # Import/export, both one label and all labels
    logging.info('Test section 3: Import/export segment')
    
    # Export single segment to model node
    bodyModelNode = slicer.vtkMRMLModelNode()
    bodyModelNode.SetName('BodyModel')
    slicer.mrmlScene.AddNode(bodyModelNode)
    
    bodySegment = self.inputSegmentationNode.GetSegmentation().GetSegment('Body_Contour')
    result = vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(bodySegment, bodyModelNode)
    self.assertTrue(result)
    self.assertIsNotNone(bodyModelNode.GetPolyData())
    self.assertEqual(bodyModelNode.GetPolyData().GetNumberOfPoints(), 302)
    #TODO: On Linux and Windows it is 588, on Mac it is 580. Need to investigate
    # self.assertEqual(bodyModelNode.GetPolyData().GetNumberOfCells(), 588)
    self.assertTrue(bodyModelNode.GetPolyData().GetNumberOfCells() == 588 or bodyModelNode.GetPolyData().GetNumberOfCells() == 580)

    # Export single segment to volume node
    bodyLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
    bodyLabelmapNode.SetName('BodyLabelmap')
    slicer.mrmlScene.AddNode(bodyLabelmapNode)
    result = vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(bodySegment, bodyLabelmapNode)
    self.assertTrue(result)
    bodyImageData = bodyLabelmapNode.GetImageData()
    self.assertIsNotNone(bodyImageData)
    imageStat = vtk.vtkImageAccumulate()
    imageStat.SetInputData(bodyImageData)
    imageStat.Update()
    self.assertEqual(imageStat.GetVoxelCount(), 648)
    self.assertEqual(imageStat.GetMin()[0], 0)
    self.assertEqual(imageStat.GetMax()[0], 1)

    # Export multiple segments to volume node
    allSegmentsLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
    allSegmentsLabelmapNode.SetName('AllSegmentsLabelmap')
    slicer.mrmlScene.AddNode(allSegmentsLabelmapNode)
    result = vtkSlicerSegmentationsModuleLogic.ExportAllSegmentsToLabelmapNode(self.inputSegmentationNode, allSegmentsLabelmapNode)
    self.assertTrue(result)
    allSegmentsImageData = allSegmentsLabelmapNode.GetImageData()
    self.assertIsNotNone(allSegmentsImageData)
    imageStat = vtk.vtkImageAccumulate()
    imageStat.SetInputData(allSegmentsImageData)
    imageStat.SetComponentExtent(0,5,0,0,0,0)
    imageStat.SetComponentOrigin(0,0,0)
    imageStat.SetComponentSpacing(1,1,1)
    imageStat.Update()
    self.assertEqual(imageStat.GetVoxelCount(), 54872000)
    imageStatResult = imageStat.GetOutput()
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(0,0,0,0), 46678738)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(1,0,0,0), 0)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(2,0,0,0), 7618805)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(3,0,0,0), 128968)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(4,0,0,0), 0) # Built from color table and color four is removed in previous test section
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(5,0,0,0), 445489)

    # Import model to segment
    modelImportSegmentationNode = vtkMRMLSegmentationNode()
    modelImportSegmentationNode.SetName('ModelImport')
    modelImportSegmentationNode.GetSegmentation().SetMasterRepresentationName(self.closedSurfaceReprName)
    slicer.mrmlScene.AddNode(modelImportSegmentationNode)
    modelSegment = vtkSlicerSegmentationsModuleLogic.CreateSegmentFromModelNode(bodyModelNode)
    modelSegment.UnRegister(None) # Need to release ownership
    self.assertIsNotNone(modelSegment)
    self.assertIsNotNone(modelSegment.GetRepresentation(self.closedSurfaceReprName))

    # Import multi-label labelmap to segmentation
    multiLabelImportSegmentationNode = vtkMRMLSegmentationNode()
    multiLabelImportSegmentationNode.SetName('MultiLabelImport')
    multiLabelImportSegmentationNode.GetSegmentation().SetMasterRepresentationName(self.binaryLabelmapReprName)
    slicer.mrmlScene.AddNode(multiLabelImportSegmentationNode)
    result = vtkSlicerSegmentationsModuleLogic.ImportLabelmapToSegmentationNode(allSegmentsLabelmapNode, multiLabelImportSegmentationNode)
    self.assertTrue(result)
    self.assertEqual(multiLabelImportSegmentationNode.GetSegmentation().GetNumberOfSegments(), 3)

    # Import labelmap into single segment
    singleLabelImportSegmentationNode = vtkMRMLSegmentationNode()
    singleLabelImportSegmentationNode.SetName('SingleLabelImport')
    singleLabelImportSegmentationNode.GetSegmentation().SetMasterRepresentationName(self.binaryLabelmapReprName)
    slicer.mrmlScene.AddNode(singleLabelImportSegmentationNode)
    # Should not import multi-label labelmap to segment
    nullSegment = vtkSlicerSegmentationsModuleLogic.CreateSegmentFromLabelmapVolumeNode(allSegmentsLabelmapNode)
    self.assertIsNone(nullSegment)
    logging.info('(This error message tests an impossible scenario, it is supposed to appear)')
    # Make labelmap single-label and import again
    threshold = vtk.vtkImageThreshold()
    threshold.ThresholdByUpper(0.5)
    threshold.SetInValue(1)
    threshold.SetOutValue(0)
    threshold.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR)
    if vtk.VTK_MAJOR_VERSION <= 5:
      threshold.SetInput(allSegmentsLabelmapNode.GetImageData())
    else:
      threshold.SetInputData(allSegmentsLabelmapNode.GetImageData())
    threshold.SetOutput(allSegmentsLabelmapNode.GetImageData())
    threshold.Update()
    labelSegment = vtkSlicerSegmentationsModuleLogic.CreateSegmentFromLabelmapVolumeNode(allSegmentsLabelmapNode)
    labelSegment.UnRegister(None) # Need to release ownership
    self.assertIsNotNone(labelSegment)
    self.assertIsNotNone(labelSegment.GetRepresentation(self.binaryLabelmapReprName))

    # Import/export with transforms
    logging.info('Test section 4/2: Import/export with transforms')

    # Create transform node that will be used to transform the tested nodes
    bodyModelTransformNode = slicer.vtkMRMLLinearTransformNode()
    slicer.mrmlScene.AddNode(bodyModelTransformNode)
    bodyModelTransform = vtk.vtkTransform()
    bodyModelTransform.Translate(1000.0, 0.0, 0.0)
    bodyModelTransformNode.ApplyTransformMatrix(bodyModelTransform.GetMatrix())
    
    # Set transform as parent to input segmentation node
    self.inputSegmentationNode.SetAndObserveTransformNodeID(bodyModelTransformNode.GetID())

    # Export single segment to model node from transformed segmentation
    bodyModelNodeTransformed = slicer.vtkMRMLModelNode()
    bodyModelNodeTransformed.SetName('BodyModelTransformed')
    slicer.mrmlScene.AddNode(bodyModelNodeTransformed)
    bodySegment = self.inputSegmentationNode.GetSegmentation().GetSegment('Body_Contour')
    result = vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(bodySegment, bodyModelNodeTransformed)
    self.assertTrue(result)
    self.assertIsNotNone(bodyModelNodeTransformed.GetParentTransformNode())

    # Export single segment to volume node from transformed segmentation
    bodyLabelmapNodeTransformed = slicer.vtkMRMLLabelMapVolumeNode()
    bodyLabelmapNodeTransformed.SetName('BodyLabelmapTransformed')
    slicer.mrmlScene.AddNode(bodyLabelmapNodeTransformed)
    result = vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(bodySegment, bodyLabelmapNodeTransformed)
    self.assertTrue(result)
    self.assertIsNotNone(bodyLabelmapNodeTransformed.GetParentTransformNode())

    # Create transform node that will be used to transform the tested nodes
    modelTransformedImportSegmentationTransformNode = slicer.vtkMRMLLinearTransformNode()
    slicer.mrmlScene.AddNode(modelTransformedImportSegmentationTransformNode)
    modelTransformedImportSegmentationTransform = vtk.vtkTransform()
    modelTransformedImportSegmentationTransform.Translate(-500.0, 0.0, 0.0)
    modelTransformedImportSegmentationTransformNode.ApplyTransformMatrix(modelTransformedImportSegmentationTransform.GetMatrix())

    # Import transformed model to segment in transformed segmentation
    modelTransformedImportSegmentationNode = vtkMRMLSegmentationNode()
    modelTransformedImportSegmentationNode.SetName('ModelImportTransformed')
    modelTransformedImportSegmentationNode.GetSegmentation().SetMasterRepresentationName(self.closedSurfaceReprName)
    slicer.mrmlScene.AddNode(modelTransformedImportSegmentationNode)
    modelTransformedImportSegmentationNode.SetAndObserveTransformNodeID(modelTransformedImportSegmentationTransformNode.GetID())
    modelSegmentTranformed = vtkSlicerSegmentationsModuleLogic.CreateSegmentFromModelNode(bodyModelNodeTransformed, modelTransformedImportSegmentationNode)
    modelSegmentTranformed.UnRegister(None) # Need to release ownership
    self.assertIsNotNone(modelSegmentTranformed)
    modelSegmentTransformedPolyData = modelSegmentTranformed.GetRepresentation(self.closedSurfaceReprName)
    self.assertIsNotNone(modelSegmentTransformedPolyData)
    self.assertEqual(int(modelSegmentTransformedPolyData.GetBounds()[0]), 1332)
    self.assertEqual(int(modelSegmentTransformedPolyData.GetBounds()[1]), 1675)

    # Clean up temporary nodes
    slicer.mrmlScene.RemoveNode(bodyModelNode)
    slicer.mrmlScene.RemoveNode(bodyLabelmapNode)
    slicer.mrmlScene.RemoveNode(allSegmentsLabelmapNode)
    slicer.mrmlScene.RemoveNode(modelImportSegmentationNode)
    slicer.mrmlScene.RemoveNode(multiLabelImportSegmentationNode)
    slicer.mrmlScene.RemoveNode(singleLabelImportSegmentationNode)
    slicer.mrmlScene.RemoveNode(bodyModelTransformNode)
    slicer.mrmlScene.RemoveNode(bodyModelNodeTransformed)
    slicer.mrmlScene.RemoveNode(bodyLabelmapNodeTransformed)
    slicer.mrmlScene.RemoveNode(modelTransformedImportSegmentationNode)
Пример #43
0
  def TestSection_ImportExportSegment(self):
    # Import/export, both one label and all labels
    logging.info('Test section: Import/export segment')

    # Export single segment to model node
    bodyModelNode = slicer.vtkMRMLModelNode()
    bodyModelNode.SetName('BodyModel')
    slicer.mrmlScene.AddNode(bodyModelNode)

    bodySegment = self.inputSegmentationNode.GetSegmentation().GetSegment(self.bodySegmentName)
    result = slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(bodySegment, bodyModelNode)
    self.assertTrue(result)
    self.assertIsNotNone(bodyModelNode.GetPolyData())
    #TODO: Number of points increased to 1677 due to end-capping, need to investigate!
    #self.assertEqual(bodyModelNode.GetPolyData().GetNumberOfPoints(), 302)
    #TODO: On Linux and Windows it is 588, on Mac it is 580. Need to investigate
    # self.assertEqual(bodyModelNode.GetPolyData().GetNumberOfCells(), 588)
    #self.assertTrue(bodyModelNode.GetPolyData().GetNumberOfCells() == 588 or bodyModelNode.GetPolyData().GetNumberOfCells() == 580)

    # Export single segment to volume node
    bodyLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
    bodyLabelmapNode.SetName('BodyLabelmap')
    slicer.mrmlScene.AddNode(bodyLabelmapNode)
    result = slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(bodySegment, bodyLabelmapNode)
    self.assertTrue(result)
    bodyImageData = bodyLabelmapNode.GetImageData()
    self.assertIsNotNone(bodyImageData)
    imageStat = vtk.vtkImageAccumulate()
    imageStat.SetInputData(bodyImageData)
    imageStat.Update()
    self.assertEqual(imageStat.GetVoxelCount(), 792)
    self.assertEqual(imageStat.GetMin()[0], 0)
    self.assertEqual(imageStat.GetMax()[0], 1)

    # Export multiple segments to volume node
    allSegmentsLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
    allSegmentsLabelmapNode.SetName('AllSegmentsLabelmap')
    slicer.mrmlScene.AddNode(allSegmentsLabelmapNode)
    result = slicer.vtkSlicerSegmentationsModuleLogic.ExportAllSegmentsToLabelmapNode(self.inputSegmentationNode, allSegmentsLabelmapNode)
    self.assertTrue(result)
    allSegmentsImageData = allSegmentsLabelmapNode.GetImageData()
    self.assertIsNotNone(allSegmentsImageData)
    imageStat = vtk.vtkImageAccumulate()
    imageStat.SetInputData(allSegmentsImageData)
    imageStat.SetComponentExtent(0,5,0,0,0,0)
    imageStat.SetComponentOrigin(0,0,0)
    imageStat.SetComponentSpacing(1,1,1)
    imageStat.Update()
    imageStatResult = imageStat.GetOutput()
    for i in range(4):
      logging.info("Volume {0}: {1}".format(i, imageStatResult.GetScalarComponentAsDouble(i,0,0,0)))
    self.assertEqual(imageStat.GetVoxelCount(), 127109360)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(0,0,0,0), 78967249)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(1,0,0,0), 39705288)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(2,0,0,0), 890883)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(3,0,0,0), 7545940)
    # Import model to segment
    modelImportSegmentationNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSegmentationNode', 'ModelImport')
    modelImportSegmentationNode.GetSegmentation().SetMasterRepresentationName(self.closedSurfaceReprName)
    modelSegment = slicer.vtkSlicerSegmentationsModuleLogic.CreateSegmentFromModelNode(bodyModelNode)
    modelSegment.UnRegister(None) # Need to release ownership
    self.assertIsNotNone(modelSegment)
    self.assertIsNotNone(modelSegment.GetRepresentation(self.closedSurfaceReprName))

    # Import multi-label labelmap to segmentation
    multiLabelImportSegmentationNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSegmentationNode', 'MultiLabelImport')
    multiLabelImportSegmentationNode.GetSegmentation().SetMasterRepresentationName(self.binaryLabelmapReprName)
    result = slicer.vtkSlicerSegmentationsModuleLogic.ImportLabelmapToSegmentationNode(allSegmentsLabelmapNode, multiLabelImportSegmentationNode)
    self.assertTrue(result)
    self.assertEqual(multiLabelImportSegmentationNode.GetSegmentation().GetNumberOfSegments(), 3)

    # Import labelmap into single segment
    singleLabelImportSegmentationNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSegmentationNode', 'SingleLabelImport')
    singleLabelImportSegmentationNode.GetSegmentation().SetMasterRepresentationName(self.binaryLabelmapReprName)
    # Should not import multi-label labelmap to segment
    nullSegment = slicer.vtkSlicerSegmentationsModuleLogic.CreateSegmentFromLabelmapVolumeNode(allSegmentsLabelmapNode)
    self.assertIsNone(nullSegment)
    logging.info('(This error message is a result of testing an impossible scenario, it is supposed to appear)')
    # Make labelmap single-label and import again
    threshold = vtk.vtkImageThreshold()
    threshold.SetInValue(0)
    threshold.SetOutValue(1)
    threshold.ReplaceInOn()
    threshold.ThresholdByLower(0)
    threshold.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR)
    if vtk.VTK_MAJOR_VERSION <= 5:
      threshold.SetInput(allSegmentsLabelmapNode.GetImageData())
    else:
      threshold.SetInputData(allSegmentsLabelmapNode.GetImageData())
    threshold.Update()
    allSegmentsLabelmapNode.GetImageData().ShallowCopy(threshold.GetOutput())
    labelSegment = slicer.vtkSlicerSegmentationsModuleLogic.CreateSegmentFromLabelmapVolumeNode(allSegmentsLabelmapNode)
    labelSegment.UnRegister(None) # Need to release ownership
    self.assertIsNotNone(labelSegment)
    self.assertIsNotNone(labelSegment.GetRepresentation(self.binaryLabelmapReprName))

    # Import/export with transforms
    logging.info('Test subsection: Import/export with transforms')

    # Create transform node that will be used to transform the tested nodes
    bodyModelTransformNode = slicer.vtkMRMLLinearTransformNode()
    slicer.mrmlScene.AddNode(bodyModelTransformNode)
    bodyModelTransform = vtk.vtkTransform()
    bodyModelTransform.Translate(1000.0, 0.0, 0.0)
    bodyModelTransformNode.ApplyTransformMatrix(bodyModelTransform.GetMatrix())

    # Set transform as parent to input segmentation node
    self.inputSegmentationNode.SetAndObserveTransformNodeID(bodyModelTransformNode.GetID())

    # Export single segment to model node from transformed segmentation
    bodyModelNodeTransformed = slicer.vtkMRMLModelNode()
    bodyModelNodeTransformed.SetName('BodyModelTransformed')
    slicer.mrmlScene.AddNode(bodyModelNodeTransformed)
    bodySegment = self.inputSegmentationNode.GetSegmentation().GetSegment(self.bodySegmentName)
    result = slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(bodySegment, bodyModelNodeTransformed)
    self.assertTrue(result)
    self.assertIsNotNone(bodyModelNodeTransformed.GetParentTransformNode())

    # Export single segment to volume node from transformed segmentation
    bodyLabelmapNodeTransformed = slicer.vtkMRMLLabelMapVolumeNode()
    bodyLabelmapNodeTransformed.SetName('BodyLabelmapTransformed')
    slicer.mrmlScene.AddNode(bodyLabelmapNodeTransformed)
    result = slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(bodySegment, bodyLabelmapNodeTransformed)
    self.assertTrue(result)
    self.assertIsNotNone(bodyLabelmapNodeTransformed.GetParentTransformNode())

    # Create transform node that will be used to transform the tested nodes
    modelTransformedImportSegmentationTransformNode = slicer.vtkMRMLLinearTransformNode()
    slicer.mrmlScene.AddNode(modelTransformedImportSegmentationTransformNode)
    modelTransformedImportSegmentationTransform = vtk.vtkTransform()
    modelTransformedImportSegmentationTransform.Translate(-500.0, 0.0, 0.0)
    modelTransformedImportSegmentationTransformNode.ApplyTransformMatrix(modelTransformedImportSegmentationTransform.GetMatrix())

    # Import transformed model to segment in transformed segmentation
    modelTransformedImportSegmentationNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSegmentationNode', 'ModelImportTransformed')
    modelTransformedImportSegmentationNode.GetSegmentation().SetMasterRepresentationName(self.closedSurfaceReprName)
    modelTransformedImportSegmentationNode.SetAndObserveTransformNodeID(modelTransformedImportSegmentationTransformNode.GetID())
    modelSegmentTranformed = slicer.vtkSlicerSegmentationsModuleLogic.CreateSegmentFromModelNode(bodyModelNodeTransformed, modelTransformedImportSegmentationNode)
    modelSegmentTranformed.UnRegister(None) # Need to release ownership
    self.assertIsNotNone(modelSegmentTranformed)
    modelSegmentTransformedPolyData = modelSegmentTranformed.GetRepresentation(self.closedSurfaceReprName)
    self.assertIsNotNone(modelSegmentTransformedPolyData)
    self.assertEqual(int(modelSegmentTransformedPolyData.GetBounds()[0]), 1332)
    self.assertEqual(int(modelSegmentTransformedPolyData.GetBounds()[1]), 1675)

    # Clean up temporary nodes
    slicer.mrmlScene.RemoveNode(bodyModelNode)
    slicer.mrmlScene.RemoveNode(bodyLabelmapNode)
    slicer.mrmlScene.RemoveNode(allSegmentsLabelmapNode)
    slicer.mrmlScene.RemoveNode(modelImportSegmentationNode)
    slicer.mrmlScene.RemoveNode(multiLabelImportSegmentationNode)
    slicer.mrmlScene.RemoveNode(singleLabelImportSegmentationNode)
    slicer.mrmlScene.RemoveNode(bodyModelTransformNode)
    slicer.mrmlScene.RemoveNode(bodyModelNodeTransformed)
    slicer.mrmlScene.RemoveNode(bodyLabelmapNodeTransformed)
    slicer.mrmlScene.RemoveNode(modelTransformedImportSegmentationNode)
  def exportAsDICOMSEG(self, exportablesCollection):
    """Export the given node to a segmentation object and load it in the
    DICOM database
    
    This function was copied and modified from the EditUtil.py function of the same name in Slicer.
    """

    import logging
    
    if hasattr(slicer.modules, 'segmentations'):
    
      exportable = exportablesCollection.GetItemAsObject(0)
      subjectHierarchyNode = slicer.mrmlScene.GetNodeByID(exportable.GetNodeID())

      instanceUIDs = subjectHierarchyNode.GetAttribute("DICOM.ReferencedInstanceUIDs").split()

      if instanceUIDs == "":
          raise Exception("Editor master node does not have DICOM information")

      # get the list of source DICOM files
      inputDICOMImageFileNames = ""
      for instanceUID in instanceUIDs:
        inputDICOMImageFileNames += slicer.dicomDatabase.fileForInstance(instanceUID) + ","
      inputDICOMImageFileNames = inputDICOMImageFileNames[:-1] # strip last comma

      # save the per-structure volumes in the temp directory
      inputSegmentationsFileNames = ""

      import random # TODO: better way to generate temp file names?
      import vtkITK
      writer = vtkITK.vtkITKImageWriter()
      rasToIJKMatrix = vtk.vtkMatrix4x4()

      import vtkSegmentationCore
      import vtkSlicerSegmentationsModuleLogic
      logic = vtkSlicerSegmentationsModuleLogic.vtkSlicerSegmentationsModuleLogic()

      segmentationTransform = vtk.vtkMatrix4x4()
      segmentationNode = subjectHierarchyNode.GetAssociatedNode()

      mergedSegmentationImageData = segmentationNode.GetImageData()
      mergedSegmentationLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()

      segmentationNode.GetRASToIJKMatrix(rasToIJKMatrix)
      mergedSegmentationLabelmapNode.SetRASToIJKMatrix(rasToIJKMatrix)
      mergedSegmentationLabelmapNode.SetAndObserveImageData(mergedSegmentationImageData)
      mergedSegmentationOrientedImageData = logic.CreateOrientedImageDataFromVolumeNode(mergedSegmentationLabelmapNode)

      segmentation = segmentationNode.GetSegmentation()

      segmentIDs = vtk.vtkStringArray()
      segmentation.GetSegmentIDs(segmentIDs)
      segmentationName = segmentationNode.GetName()

      for i in range(0, segmentIDs.GetNumberOfValues()):
        segmentID = segmentIDs.GetValue(i)
        segment = segmentation.GetSegment(segmentID)

        segmentName = segment.GetName()
        structureName = segmentName[len(segmentationName)+1:-1*len('-label')]

        structureFileName = structureName + str(random.randint(0,vtk.VTK_INT_MAX)) + ".nrrd"
        filePath = os.path.join(slicer.app.temporaryPath, structureFileName)
        writer.SetFileName(filePath)

        segmentImageData = segment.GetRepresentation(vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName())
        paddedImageData = vtkSegmentationCore.vtkOrientedImageData()
        vtkSegmentationCore.vtkOrientedImageDataResample.PadImageToContainImage(segmentImageData, mergedSegmentationOrientedImageData, paddedImageData)

        labelmapImageData = slicer.vtkMRMLLabelMapVolumeNode()
        logic.CreateLabelmapVolumeFromOrientedImageData(paddedImageData, labelmapImageData)

        writer.SetInputDataObject(labelmapImageData.GetImageData())

        labelmapImageData.GetRASToIJKMatrix(rasToIJKMatrix)
        writer.SetRasToIJKMatrix(rasToIJKMatrix)
        logging.debug("Saving to %s..." % filePath)
        writer.Write()
        inputSegmentationsFileNames += filePath + ","
      inputSegmentationsFileNames = inputSegmentationsFileNames[:-1] # strip last comma

      # save the per-structure volumes label attributes
      colorNode = segmentationNode.GetNodeReference('colorNodeID')

      terminologyName = colorNode.GetAttribute("TerminologyName")
      colorLogic = slicer.modules.colors.logic()
      if not terminologyName or not colorLogic:
        raise Exception("No terminology or color logic - cannot export")

      inputLabelAttributesFileNames = ""

      for i in range(0, segmentIDs.GetNumberOfValues()):
        segmentID = segmentIDs.GetValue(i)
        segment = segmentation.GetSegment(segmentID)

        segmentName = segment.GetName()
        structureName = segmentName[len(segmentationName)+1:-1*len('-label')]
        labelIndex = colorNode.GetColorIndexByName( structureName )

        rgbColor = [0,]*4
        colorNode.GetColor(labelIndex, rgbColor)
        rgbColor = map(lambda e: e*255., rgbColor)

        # get the attributes and conver to format CodeValue,CodeMeaning,CodingSchemeDesignator
        # or empty strings if not defined
        propertyCategoryWithColons = colorLogic.GetSegmentedPropertyCategory(labelIndex, terminologyName)
        if propertyCategoryWithColons == '':
          logging.debug ('ERROR: no segmented property category found for label ',str(labelIndex))
          # Try setting a default as this section is required
          propertyCategory = "C94970,NCIt,Reference Region"
        else:
          propertyCategory = propertyCategoryWithColons.replace(':',',')

        propertyTypeWithColons = colorLogic.GetSegmentedPropertyType(labelIndex, terminologyName)
        propertyType = propertyTypeWithColons.replace(':',',')

        propertyTypeModifierWithColons = colorLogic.GetSegmentedPropertyTypeModifier(labelIndex, terminologyName)
        propertyTypeModifier = propertyTypeModifierWithColons.replace(':',',')

        anatomicRegionWithColons = colorLogic.GetAnatomicRegion(labelIndex, terminologyName)
        anatomicRegion = anatomicRegionWithColons.replace(':',',')

        anatomicRegionModifierWithColons = colorLogic.GetAnatomicRegionModifier(labelIndex, terminologyName)
        anatomicRegionModifier = anatomicRegionModifierWithColons.replace(':',',')

        structureFileName = structureName + str(random.randint(0,vtk.VTK_INT_MAX)) + ".info"
        filePath = os.path.join(slicer.app.temporaryPath, structureFileName)

        # EncodeSEG is expecting a file of format:
        # labelNum;SegmentedPropertyCategory:codeValue,codeScheme,codeMeaning;SegmentedPropertyType:v,m,s etc
        attributes = "%d" % labelIndex
        attributes += ";SegmentedPropertyCategory:"+propertyCategory
        if propertyType != "":
          attributes += ";SegmentedPropertyType:" + propertyType
        if propertyTypeModifier != "":
          attributes += ";SegmentedPropertyTypeModifier:" + propertyTypeModifier
        if anatomicRegion != "":
          attributes += ";AnatomicRegion:" + anatomicRegion
        if anatomicRegionModifier != "":
          attributes += ";AnatomicRegionModifer:" + anatomicRegionModifier
        attributes += ";SegmentAlgorithmType:AUTOMATIC"
        attributes += ";SegmentAlgorithmName:SlicerSelfTest"
        attributes += ";RecommendedDisplayRGBValue:%g,%g,%g" % tuple(rgbColor[:-1])
        fp = open(filePath, "w")
        fp.write(attributes)
        fp.close()
        logging.debug ("filePath: %s", filePath)
        logging.debug ("attributes: %s", attributes)
        inputLabelAttributesFileNames += filePath + ","
      inputLabelAttributesFileNames = inputLabelAttributesFileNames[:-1] # strip last comma'''

      try:
        user = os.environ['USER']
      except KeyError:
        user = "******"
      segFileName = "editor_export.SEG" + str(random.randint(0,vtk.VTK_INT_MAX)) + ".dcm"
      segFilePath = os.path.join(slicer.app.temporaryPath, segFileName)
      # TODO: define a way to set parameters like description
      # TODO: determine a good series number automatically by looking in the database
      parameters = {
        "inputDICOMImageFileNames": inputDICOMImageFileNames,
        "inputSegmentationsFileNames": inputSegmentationsFileNames,
        "inputLabelAttributesFileNames": inputLabelAttributesFileNames,
        "readerId": user,
        "sessionId": "1",
        "timePointId": "1",
        "seriesDescription": "SlicerEditorSEGExport",
        "seriesNumber": "100",
        "instanceNumber": "1",
        "bodyPart": "HEAD",
        "algorithmDescriptionFileName": "Editor",
        "outputSEGFileName": segFilePath,
        "skipEmptySlices": False,
        "compress": False,
        }

      encodeSEG = slicer.modules.encodeseg
      cliNode = None

      cliNode = slicer.cli.run(encodeSEG, cliNode, parameters, delete_temporary_files=False)
      waitCount = 0
      while cliNode.IsBusy() and waitCount < 20:
        slicer.util.delayDisplay( "Running SEG Encoding... %d" % waitCount, 1000 )
        waitCount += 1

      if cliNode.GetStatusString() != 'Completed':
        raise Exception("encodeSEG CLI did not complete cleanly")

      logging.info("Added segmentation to DICOM database (%s)", segFilePath)
      slicer.dicomDatabase.insert(segFilePath)