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)
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
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}
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
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
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
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()
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()
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()
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
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 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!')
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()")
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
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
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)
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 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!")
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 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))
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}
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
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
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
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
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
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))
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)
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)