def checkAndSetLUT(self): # Default to module color table self.resourcesPath = os.path.join(slicer.modules.slicerpathology.path.replace(self.moduleName+".py",""), 'Resources') self.colorFile = os.path.join(self.resourcesPath, "Colors/SlicerPathology.csv") self.customLUTLabel.setText('Using Default LUT') try: self.editorWidget.helper.structureListWidget.merge = None except AttributeError: pass # setup the color table, make sure SlicerPathology LUT is a singleton allColorTableNodes = slicer.util.getNodes('vtkMRMLColorTableNode*').values() for ctn in allColorTableNodes: #print "color: "+ctn.GetName() if ctn.GetName() == 'SlicerPathologyColor': slicer.mrmlScene.RemoveNode(ctn) break self.SlicerPathologyColorNode = slicer.vtkMRMLColorTableNode() colorNode = self.SlicerPathologyColorNode colorNode.SetName('SlicerPathologyColor') slicer.mrmlScene.AddNode(colorNode) colorNode.SetTypeToUser() with open(self.colorFile) as f: n = sum(1 for line in f) colorNode.SetNumberOfColors(n-1) colorNode.NamesInitialisedOn() import csv self.structureNames = [] with open(self.colorFile, 'rb') as csvfile: reader = csv.DictReader(csvfile, delimiter=',') for index,row in enumerate(reader): success = colorNode.SetColor(index ,row['Label'],float(row['R'])/255,float(row['G'])/255,float(row['B'])/255,float(row['A'])) if not success: print "color %s could not be set" % row['Label'] self.structureNames.append(row['Label'])
def mutate(self): red_logic = slicer.app.layoutManager().sliceWidget("Red").sliceLogic() red_cn = red_logic.GetSliceCompositeNode() fgrdVolID = red_cn.GetBackgroundVolumeID() fgrdNode = slicer.util.getNode("WEB") fgrdVolID = fgrdNode.GetID() fMat=vtk.vtkMatrix4x4() fgrdNode.GetIJKToRASDirectionMatrix(fMat) bgrdName = fgrdNode.GetName() + '_gray' magnitude = vtk.vtkImageMagnitude() magnitude.SetInputData(fgrdNode.GetImageData()) magnitude.Update() bgrdNode = slicer.vtkMRMLScalarVolumeNode() bgrdNode.SetImageDataConnection(magnitude.GetOutputPort()) bgrdNode.SetName(bgrdName) bgrdNode.SetIJKToRASDirectionMatrix(fMat) slicer.mrmlScene.AddNode(bgrdNode) bgrdVolID = bgrdNode.GetID() red_cn.SetForegroundVolumeID(fgrdVolID) red_cn.SetBackgroundVolumeID(bgrdVolID) red_cn.SetForegroundOpacity(1) resourcesPath = os.path.join(slicer.modules.slicerpathology.path.replace("SlicerPathology.py",""), 'Resources') colorFile = os.path.join(resourcesPath, "Colors/SlicerPathology.csv") try: slicer.modules.EditorWidget.helper.structureListWidget.merge = None except AttributeError: pass allColorTableNodes = slicer.util.getNodes('vtkMRMLColorTableNode*').values() for ctn in allColorTableNodes: if ctn.GetName() == 'SlicerPathologyColor': slicer.mrmlScene.RemoveNode(ctn) break SlicerPathologyColorNode = slicer.vtkMRMLColorTableNode() colorNode = SlicerPathologyColorNode colorNode.SetName('SlicerPathologyColor') slicer.mrmlScene.AddNode(colorNode) colorNode.SetTypeToUser() with open(colorFile) as f: n = sum(1 for line in f) colorNode.SetNumberOfColors(n-1) colorNode.NamesInitialisedOn() import csv structureNames = [] with open(colorFile, 'rb') as csvfile: reader = csv.DictReader(csvfile, delimiter=',') for index,row in enumerate(reader): success = colorNode.SetColor(index ,row['Label'],float(row['R'])/255,float(row['G'])/255,float(row['B'])/255,float(row['A'])) if not success: print "color %s could not be set" % row['Label'] structureNames.append(row['Label']) volumesLogic = slicer.modules.volumes.logic() labelName = bgrdName+'-label' refLabel = volumesLogic.CreateAndAddLabelVolume(slicer.mrmlScene,bgrdNode,labelName) refLabel.GetDisplayNode().SetAndObserveColorNodeID(SlicerPathologyColorNode.GetID()) self.editorWidget.helper.setMasterVolume(bgrdNode)
def build_color_table(name, table_max): table = slicer.vtkMRMLColorTableNode() table.SetName(name) table.SetHideFromEditors(0) table.SetTypeToFile() table.NamesInitialisedOff() table.SetNumberOfColors(table_max) table.GetLookupTable().SetTableRange(0, table_max) table.NamesInitialisedOn() slicer.mrmlScene.AddNode(table) return table
def CreateDefaultGSIColorTable(self, overDoseOff): colorTableNode = slicer.vtkMRMLColorTableNode() if overDoseOff: nodeName = "GSIStandard_NoOverDose" else: nodeName = "GSIStandard_OverDose" colorTableNode.SetName(nodeName); colorTableNode.SetTypeToUser(); colorTableNode.SetAttribute("Category", "User Generated"); colorTableNode.HideFromEditorsOn(); colorTableNode.SetNumberOfColors(256); colorTableNode.GetLookupTable().SetTableRange(0,255) darkBlue = 47.0 lightBlue = 95.0 darkGreen = 142.0 lightGreen = 189.0 yellow = 225.0 red = 248.0 if overDoseOff: for i in range(0,256): if i>=0 and i<darkBlue: colorTableNode.AddColor(str(i), 0, 0 + i/darkBlue, 1, 0.2) elif i>=darkBlue and i<lightBlue: colorTableNode.AddColor(str(i), 0, 1-0.5*(i-darkBlue)/(lightBlue-darkBlue), 1 - (i-darkBlue)/(lightBlue-darkBlue), 0.2) elif i>=lightBlue and i<darkGreen: colorTableNode.AddColor(str(i), 0, 0.5 + 0.5*(i-lightBlue)/(darkGreen-lightBlue), 0, 0.2) elif i>=darkGreen and i<lightGreen: colorTableNode.AddColor(str(i), 0 + (i-darkGreen)/(lightGreen-darkGreen), 1, 0, 0.2) elif i>=lightGreen and i<236: colorTableNode.AddColor(str(i), 1, 1, 0, 0.2) else: colorTableNode.AddColor(str(i), 1, 0, 0, 0.2) else: for i in range(0,256): if i>=0 and i<darkBlue: colorTableNode.AddColor(str(i), 0, 0 + i/darkBlue, 1, 0.2) elif i>=darkBlue and i<lightBlue: colorTableNode.AddColor(str(i), 0, 1-0.5*(i-darkBlue)/(lightBlue-darkBlue), 1 - (i-darkBlue)/(lightBlue-darkBlue), 0.2) elif i>=lightBlue and i<darkGreen: colorTableNode.AddColor(str(i), 0, 0.5 + 0.5*(i-lightBlue)/(darkGreen-lightBlue), 0, 0.2) elif i>=darkGreen and i<lightGreen: colorTableNode.AddColor(str(i), 0 + (i-darkGreen)/(lightGreen-darkGreen), 1, 0, 0.2) elif i>=lightGreen and i<yellow: colorTableNode.AddColor(str(i), 1, 1, 0, 0.2) elif i<=red: colorTableNode.AddColor(str(i), 1, 0, 0, 0.2) else: colorTableNode.AddColor(str(i), 1, 0, 1, 0.2) slicer.mrmlScene.AddNode( colorTableNode ) return colorTableNode
def onSelectROI(self): merge=self.outputSelector.currentNode() master=self.masterSelector.currentNode() if master: if merge: if not merge.GetImageData(): self.newROI=True imd=vtk.vtkImageData() mim=master.GetImageData() imd.SetDimensions(mim.GetDimensions()) imd.SetSpacing(mim.GetSpacing()) imd.SetOrigin(mim.GetOrigin()) #imd.SetScalarType(vtk.VTK_SHORT) imd.AllocateScalars(vtk.VTK_SHORT,1) masterIJKToRAS = vtk.vtkMatrix4x4() master.GetIJKToRASMatrix(masterIJKToRAS) merge.SetIJKToRASMatrix(masterIJKToRAS) nd=slicer.vtkMRMLScalarVolumeDisplayNode() slicer.mrmlScene.AddNode(nd) merge.AddAndObserveDisplayNodeID(nd.GetID()) merge.SetAndObserveImageData(imd) #workaround to display ROI in Slicer?????? parameters={} parameters["InputVolume"]=merge.GetID() parameters["OutputVolume"]=merge.GetID() parameters["Type"]="Short" castIM=slicer.modules.castscalarvolume slicer.cli.run(castIM,None,parameters) coln=slicer.vtkMRMLColorTableNode() coln.SetTypeToUser() coln.SetNumberOfColors(2) coln.SetColor(0,'bg',0,0,0) coln.SetColor(1,'fg',1,0,0) coln.SetOpacity(0,0) coln.SetOpacity(1,1) slicer.mrmlScene.AddNode(coln) merge.GetDisplayNode().SetAndObserveColorNodeID(coln.GetID()) else: self.newROI=False warnings = self.checkForVolumeWarnings(master,merge) if warnings != "": self.errorDialog( "Warning: %s" % warnings ) self.outputSelector.setCurrentNode(None)
def createFociVisualizationColorMap(self,minimumValue,maximumValue): if (minimumValue<0): numberOfCoolColors = -(minimumValue) else: numberOfCoolColors = 0 if (maximumValue>0): numberOfHotColors = maximumValue+1 # includes zero else: numberOfHotColors = 0 if self.displayDebugInformation: print "number of cool colors = " + str(numberOfCoolColors) print "number of hot colors (including zero) = " + str(numberOfHotColors) colorNode = slicer.util.getNode(self.FOCI_ACONTRARIO_DETECTION_COLORMAP_NAME) if colorNode is None: colorNode = slicer.vtkMRMLColorTableNode() slicer.mrmlScene.AddNode(colorNode) colorNode.SetName(self.FOCI_ACONTRARIO_DETECTION_COLORMAP_NAME) colorNode.SetTypeToUser() colorNode.SetNumberOfColors(numberOfCoolColors + numberOfHotColors); colorNode.SetNamesFromColors() ''' cool color map in Matlab r = (0:m-1)'/max(m-1,1); c = [r 1-r ones(m,1)]; ''' for colorIndex in xrange(0,numberOfCoolColors): r = np.double(numberOfCoolColors -1 - colorIndex) / (numberOfCoolColors) colorNode.SetColor(colorIndex, r, 1-r, 1, 1.0); ''' hot color table in Matlab r = [(1:n)'/n; ones(m-n,1)]; g = [zeros(n,1); (1:n)'/n; ones(m-2*n,1)]; b = [zeros(2*n,1); (1:m-2*n)'/(m-2*n)]; ''' n=3*numberOfHotColors/8 # fix ''' hot color table in Python ''' r=np.concatenate((np.double(range(1,n+1))/n , np.ones(numberOfHotColors-n))) g=np.concatenate((np.zeros(n),np.double(range(1,n+1))/n,np.ones(numberOfHotColors-2*n))) b=np.concatenate((np.zeros(2*n),np.double(range(1,numberOfHotColors-2*n+1))/(numberOfHotColors-2*n))) for colorIndex in xrange(0,numberOfHotColors): colorNode.SetColor(numberOfCoolColors + colorIndex, r[colorIndex], g[colorIndex], b[colorIndex], 1.0); #print "hot color index = " + str(numberOfCoolColors + colorIndex) colorNode.SetOpacity(numberOfCoolColors,0);
def setupLobesColorTable(): if len(slicer.util.getNodes('lapdMouseLobes')) > 0: return colors = slicer.vtkMRMLColorTableNode() colors.SetTypeToUser() colors.SetAttribute("Category", "lapdMouse") colors.SetName('lapdMouseLobes') colors.SetHideFromEditors(True) colors.SetNumberOfColors(6) colors.NamesInitialisedOn() colors.GetLookupTable().SetRange(0, 5) colors.SetColor(0, 'background', 0, 0, 0, 0) colors.SetColor(1, 'left lobe', 1, 0, 0, 1) colors.SetColor(2, 'right cranial lobe', 0, 1, 0, 1) colors.SetColor(3, 'right middle lobe', 0, 0, 1, 1) colors.SetColor(4, 'right caudal lobe', 1, 1, 0, 1) colors.SetColor(5, 'right accessory lobe', 0, 1, 1, 1) slicer.mrmlScene.AddNode(colors)
def checkAndSetLUT(self): # Default to module color table self.resourcesPath = os.path.join( slicer.modules.slicerpathology.path.replace( self.moduleName + ".py", ""), 'Resources') self.colorFile = os.path.join(self.resourcesPath, "Colors/SlicerPathology.csv") self.customLUTLabel.setText('Using Default LUT') try: self.editorWidget.helper.structureListWidget.merge = None except AttributeError: pass # setup the color table, make sure SlicerPathology LUT is a singleton allColorTableNodes = slicer.util.getNodes( 'vtkMRMLColorTableNode*').values() for ctn in allColorTableNodes: #print "color: "+ctn.GetName() if ctn.GetName() == 'SlicerPathologyColor': slicer.mrmlScene.RemoveNode(ctn) break self.SlicerPathologyColorNode = slicer.vtkMRMLColorTableNode() colorNode = self.SlicerPathologyColorNode colorNode.SetName('SlicerPathologyColor') slicer.mrmlScene.AddNode(colorNode) colorNode.SetTypeToUser() with open(self.colorFile) as f: n = sum(1 for line in f) colorNode.SetNumberOfColors(n - 1) colorNode.NamesInitialisedOn() import csv self.structureNames = [] with open(self.colorFile, 'rb') as csvfile: reader = csv.DictReader(csvfile, delimiter=',') for index, row in enumerate(reader): success = colorNode.SetColor(index, row['Label'], float(row['R']) / 255, float(row['G']) / 255, float(row['B']) / 255, float(row['A'])) if not success: print "color %s could not be set" % row['Label'] self.structureNames.append(row['Label'])
def setupOutletsColorTable(): if len(slicer.util.getNodes('lapdMouseOutlets')) > 0: return numSegments = 5000 colors = slicer.vtkMRMLColorTableNode() colors.SetTypeToUser() colors.SetAttribute("Category", "lapdMouse") colors.SetName('lapdMouseOutlets') colors.SetHideFromEditors(True) colors.SetNumberOfColors(numSegments) colors.NamesInitialisedOn() colors.GetLookupTable().SetRange(0, numSegments) colors.SetColor(0, 'wall', 1, 0.67, 0, 1) import random random.seed( 3 ) # seed 3: nothing too dark and first few generations reasonably well contrasted for i in range(1, numSegments): colors.SetColor(i, str(i), random.uniform(0.0, 1.0), random.uniform(0.0, 1.0), random.uniform(0.0, 1.0), 1) slicer.mrmlScene.AddNode(colors)
def load(self,loadable): """ Load the DICOM SEG object """ print('DICOM SEG load()') labelNodes = vtk.vtkCollection() uid = None try: uid = loadable.uid print ('in load(): uid = ', uid) except AttributeError: return False res = False # make the output directory outputDir = os.path.join(slicer.app.temporaryPath,"QIICR","SEG",loadable.uid) try: os.makedirs(outputDir) except: pass # produces output label map files, one per segment, and information files with # the terminology information for each segment segFileName = slicer.dicomDatabase.fileForInstance(uid) if segFileName is None: print 'Failed to get the filename from the DICOM database for ', uid return False parameters = { "inputSEGFileName": segFileName, "outputDirName": outputDir, } seg2nrrd = None try: seg2nrrd = slicer.modules.seg2nrrd except AttributeError: print 'Unable to find CLI module SEG2NRRD, unable to load DICOM Segmentation object' return False cliNode = None cliNode = slicer.cli.run(seg2nrrd, cliNode, parameters, wait_for_completion=True) if cliNode.GetStatusString() != 'Completed': print 'SEG2NRRD did not complete successfully, unable to load DICOM Segmentation' return False # create a new color node to be set up with the colors in these segments colorLogic = slicer.modules.colors.logic() segmentationColorNode = slicer.vtkMRMLColorTableNode() segmentationColorNode.SetName(loadable.name) segmentationColorNode.SetTypeToUser(); segmentationColorNode.SetHideFromEditors(0) segmentationColorNode.SetAttribute("Category", "File") segmentationColorNode.NamesInitialisedOff() slicer.mrmlScene.AddNode(segmentationColorNode) # also create a new terminology and associate it with this color node colorLogic.CreateNewTerminology(segmentationColorNode.GetName()) import glob numberOfSegments = len(glob.glob(os.path.join(outputDir,'*.nrrd'))) # resize the color table to include the segments plus 0 for the background print ('number of segments = ',numberOfSegments) segmentationColorNode.SetNumberOfColors(numberOfSegments + 1) segmentationColorNode.SetColor(0, 'background', 0.0, 0.0, 0.0, 0.0) seriesName = self.referencedSeriesName(loadable) segmentNodes = [] for segmentId in range(numberOfSegments): # load each of the segments' segmentations # Initialize color and terminology from .info file # See SEG2NRRD.cxx and EncodeSEG.cxx for how it's written. # Format of the .info file (no leading spaces, labelNum, RGBColor, SegmentedPropertyCategory and # SegmentedPropertyCategory are required): # labelNum;RGB:R,G,B;SegmentedPropertyCategory:code,scheme,meaning;SegmentedPropertyType:code,scheme,meaning;SegmentedPropertyTypeModifier:code,scheme,meaning;AnatomicRegion:code,scheme,meaning;AnatomicRegionModifier:code,scheme,meaning # R, G, B are 0-255 in file, but mapped to 0-1 for use in color node # set defaults in case of missing fields, modifiers are optional rgb = (0., 0., 0.) colorIndex = segmentId + 1 categoryCode = 'T-D0050' categoryCodingScheme = 'SRT' categoryCodeMeaning = 'Tissue' typeCode = 'T-D0050' typeCodeMeaning = 'Tissue' typeCodingScheme = 'SRT' typeModCode = '' typeModCodingScheme = '' typeModCodeMeaning = '' regionCode = 'T-D0010' regionCodingScheme = 'SRT' regionCodeMeaning = 'Entire Body' regionModCode = '' regionModCodingScheme = '' regionModCodeMeaning = '' infoFileName = os.path.join(outputDir,str(segmentId+1)+".info") print ('Parsing info file', infoFileName) with open(infoFileName, 'r') as infoFile: for line in infoFile: line = line.rstrip() if len(line) == 0: # empty line continue terms = line.split(';') for term in terms: # label number is the first thing, no key if len(term.split(':')) == 1: colorIndex = int(term) else: key = term.split(':')[0] if key == "RGB": rgb255 = term.split(':')[1].split(',') rgb = map(lambda c: float(c) / 255., rgb255) elif key == "AnatomicRegion": # Get the Region information region = term.split(':')[1] # use partition to deal with any commas in the meaning regionCode, sep, regionCodingSchemeAndCodeMeaning = region.partition(',') regionCodingScheme, sep, regionCodeMeaning = regionCodingSchemeAndCodeMeaning.partition(',') elif key == "AnatomicRegionModifier": regionMod = term.split(':')[1] regionModCode, sep, regionModCodingSchemeAndCodeMeaning = regionMod.partition(',') regionModCodingScheme, sep, regionModCodeMeaning = regionModCodingSchemeAndCodeMeaning.partition(',') elif key == "SegmentedPropertyCategory": # Get the Category information category = term.split(':')[1] categoryCode, sep, categoryCodingSchemeAndCodeMeaning = category.partition(',') categoryCodingScheme, sep, categoryCodeMeaning = categoryCodingSchemeAndCodeMeaning.partition(',') elif key == "SegmentedPropertyType": # Get the Type information types = term.split(':')[1] typeCode, sep, typeCodingSchemeAndCodeMeaning = types.partition(',') typeCodingScheme, sep, typeCodeMeaning = typeCodingSchemeAndCodeMeaning.partition(',') elif key == "SegmentedPropertyTypeModifier": typeMod = term.split(':')[1] typeModCode, sep, typeModCodingSchemeAndCodeMeaning = typeMod.partition(',') typeModCodingScheme, sep, typeModCodeMeaning = typeModCodingSchemeAndCodeMeaning.partition(',') # set the color name from the terminology colorName = typeCodeMeaning segmentationColorNode.SetColor(colorIndex, colorName, *rgb) colorLogic.AddTermToTerminology(segmentationColorNode.GetName(), colorIndex, categoryCode, categoryCodingScheme, categoryCodeMeaning, typeCode, typeCodingScheme, typeCodeMeaning, typeModCode, typeModCodingScheme, typeModCodeMeaning, regionCode, regionCodingScheme, regionCodeMeaning, regionModCode, regionModCodingScheme, regionModCodeMeaning) # end of processing a line of terminology infoFile.close() #TODO: Create logic class that both CLI and this plugin uses so that we don't need to have temporary NRRD files and labelmap nodes #if not hasattr(slicer.modules, 'segmentations'): # load the segmentation volume file and name it for the reference series and segment color labelFileName = os.path.join(outputDir,str(segmentId+1)+".nrrd") segmentName = seriesName + "-" + colorName + "-label" (success,labelNode) = slicer.util.loadLabelVolume(labelFileName, properties = {'name' : segmentName}, returnNode=True) segmentNodes.append(labelNode) # point the label node to the color node we're creating labelDisplayNode = labelNode.GetDisplayNode() if labelDisplayNode == None: print ('Warning: no label map display node for segment ',segmentId,', creating!') labelNode.CreateDefaultDisplayNodes() labelDisplayNode = labelNode.GetDisplayNode() labelDisplayNode.SetAndObserveColorNodeID(segmentationColorNode.GetID()) # TODO: initialize referenced UID (and segment number?) attribute(s) # create Subject hierarchy nodes for the loaded series self.addSeriesInSubjectHierarchy(loadable, labelNode) # create a combined (merge) label volume node (only if a segment was created) if labelNode: volumeLogic = slicer.modules.volumes.logic() mergeNode = volumeLogic.CloneVolume(labelNode, seriesName + "-label") combiner = slicer.vtkImageLabelCombine() for segmentNode in segmentNodes: combiner.SetInputConnection(0, mergeNode.GetImageDataConnection() ) combiner.SetInputConnection(1, segmentNode.GetImageDataConnection() ) combiner.Update() mergeNode.GetImageData().DeepCopy( combiner.GetOutput() ) for segmentNode in segmentNodes: segmentNode.Modified() # sets the MTime so the editor won't think they are older than mergeNode # display the mergeNode selectionNode = slicer.app.applicationLogic().GetSelectionNode() selectionNode.SetReferenceActiveLabelVolumeID( mergeNode.GetID() ) slicer.app.applicationLogic().PropagateVolumeSelection(0) # finalize the color node segmentationColorNode.NamesInitialisedOn() # TODO: the outputDir should be cleaned up if hasattr(slicer.modules, 'segmentations'): import vtkSlicerSegmentationsModuleLogic import vtkSlicerSegmentationsModuleMRML import vtkSegmentationCore segmentationNode = vtkSlicerSegmentationsModuleMRML.vtkMRMLSegmentationNode() segmentationNode.SetName(seriesName) segmentationNode.AddNodeReferenceID('colorNodeID', segmentationColorNode.GetID()) slicer.mrmlScene.AddNode(segmentationNode) segmentationDisplayNode = vtkSlicerSegmentationsModuleMRML.vtkMRMLSegmentationDisplayNode() segmentationNode.SetAndObserveDisplayNodeID(segmentationDisplayNode.GetID()) slicer.mrmlScene.AddNode(segmentationDisplayNode) segmentation = vtkSegmentationCore.vtkSegmentation() segmentation.SetMasterRepresentationName(vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName()) segmentationNode.SetAndObserveSegmentation(segmentation) self.addSeriesInSubjectHierarchy(loadable, segmentationNode) colorID = 1 for segmentNode in segmentNodes: segment = vtkSegmentationCore.vtkSegment() segment.SetName(segmentNode.GetName()) segmentColor = [0,0,0,0] segmentationColorNode.GetColor(colorID, segmentColor) segment.SetDefaultColor(segmentColor[0:3]) colorID += 1 #TODO: when the logic class is created, this will need to be changed logic = vtkSlicerSegmentationsModuleLogic.vtkSlicerSegmentationsModuleLogic() orientedImage = logic.CreateOrientedImageDataFromVolumeNode(segmentNode) segment.AddRepresentation(vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName(), orientedImage) segmentation.AddSegment(segment) segmentDisplayNode = segmentNode.GetDisplayNode() slicer.mrmlScene.RemoveNode(segmentDisplayNode) slicer.mrmlScene.RemoveNode(segmentNode) segmentation.CreateRepresentation(vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationClosedSurfaceRepresentationName(), True) slicer.mrmlScene.RemoveNode(mergeNode) return True
def load(self, loadable): """ Call Reporting logic to load the DICOM SEG object """ print('DICOM SEG load()') labelNodes = vtk.vtkCollection() uid = None try: reportingLogic = slicer.modules.reporting.logic() uid = loadable.uid print('in load(): uid = ', uid) except AttributeError: return False res = False # make the output directory outputDir = os.path.join(slicer.app.temporaryPath, "QIICR", "SEG", loadable.uid) try: os.makedirs(outputDir) except: pass # produces output label map files, one per segment, and information files with # the terminology information for each segment res = reportingLogic.DicomSegRead(labelNodes, uid) # create a new color node to be set up with the colors in these segments colorLogic = slicer.modules.colors.logic() segmentationColorNode = slicer.vtkMRMLColorTableNode() segmentationColorNode.SetName(loadable.name) segmentationColorNode.SetTypeToUser() segmentationColorNode.SetHideFromEditors(0) segmentationColorNode.SetAttribute("Category", "File") segmentationColorNode.NamesInitialisedOff() slicer.mrmlScene.AddNode(segmentationColorNode) # also create a new terminology and associate it with this color node colorLogic.CreateNewTerminology(segmentationColorNode.GetName()) import glob numberOfSegments = len(glob.glob(os.path.join(outputDir, '*.nrrd'))) # resize the color table to include the segments plus 0 for the background print('number of segments = ', numberOfSegments) segmentationColorNode.SetNumberOfColors(numberOfSegments + 1) segmentationColorNode.SetColor(0, 'background', 0.0, 0.0, 0.0, 0.0) seriesName = self.referencedSeriesName(loadable) segmentNodes = [] for segmentId in range(numberOfSegments): # load each of the segments' segmentations # Initialize color and terminology from .info file # See SEG2NRRD.cxx and EncodeSEG.cxx for how it's written. # Format of the .info file (no leading spaces, labelNum, RGBColor, SegmentedPropertyCategory and # SegmentedPropertyCategory are required): # labelNum;RGB:R,G,B;SegmentedPropertyCategory:code,scheme,meaning;SegmentedPropertyType:code,scheme,meaning;SegmentedPropertyTypeModifier:code,scheme,meaning;AnatomicRegion:code,scheme,meaning;AnatomicRegionModifier:code,scheme,meaning # R, G, B are 0-255 in file, but mapped to 0-1 for use in color node # set defaults in case of missing fields, modifiers are optional rgb = (0., 0., 0.) colorIndex = segmentId + 1 categoryCode = 'T-D0050' categoryCodingScheme = 'SRT' categoryCodeMeaning = 'Tissue' typeCode = 'T-D0050' typeCodeMeaning = 'Tissue' typeCodingScheme = 'SRT' typeModCode = '' typeModCodingScheme = '' typeModCodeMeaning = '' regionCode = 'T-D0010' regionCodingScheme = 'SRT' regionCodeMeaning = 'Entire Body' regionModCode = '' regionModCodingScheme = '' regionModCodeMeaning = '' infoFileName = os.path.join(outputDir, str(segmentId + 1) + ".info") print('Parsing info file', infoFileName) with open(infoFileName, 'r') as infoFile: for line in infoFile: line = line.rstrip() if len(line) == 0: # empty line continue terms = line.split(';') for term in terms: # label number is the first thing, no key if len(term.split(':')) == 1: colorIndex = int(term) else: key = term.split(':')[0] if key == "RGB": rgb255 = term.split(':')[1].split(',') rgb = map(lambda c: float(c) / 255., rgb255) elif key == "AnatomicRegion": # Get the Region information region = term.split(':')[1] # use partition to deal with any commas in the meaning regionCode, sep, regionCodingSchemeAndCodeMeaning = region.partition( ',') regionCodingScheme, sep, regionCodeMeaning = regionCodingSchemeAndCodeMeaning.partition( ',') elif key == "AnatomicRegionModifier": regionMod = term.split(':')[1] regionModCode, sep, regionModCodingSchemeAndCodeMeaning = regionMod.partition( ',') regionModCodingScheme, sep, regionModCodeMeaning = regionModCodingSchemeAndCodeMeaning.partition( ',') elif key == "SegmentedPropertyCategory": # Get the Category information category = term.split(':')[1] categoryCode, sep, categoryCodingSchemeAndCodeMeaning = category.partition( ',') categoryCodingScheme, sep, categoryCodeMeaning = categoryCodingSchemeAndCodeMeaning.partition( ',') elif key == "SegmentedPropertyType": # Get the Type information types = term.split(':')[1] typeCode, sep, typeCodingSchemeAndCodeMeaning = types.partition( ',') typeCodingScheme, sep, typeCodeMeaning = typeCodingSchemeAndCodeMeaning.partition( ',') elif key == "SegmentedPropertyTypeModifier": typeMod = term.split(':')[1] typeModCode, sep, typeModCodingSchemeAndCodeMeaning = typeMod.partition( ',') typeModCodingScheme, sep, typeModCodeMeaning = typeModCodingSchemeAndCodeMeaning.partition( ',') # set the color name from the terminology colorName = typeCodeMeaning segmentationColorNode.SetColor(colorIndex, colorName, *rgb) colorLogic.AddTermToTerminology( segmentationColorNode.GetName(), colorIndex, categoryCode, categoryCodingScheme, categoryCodeMeaning, typeCode, typeCodingScheme, typeCodeMeaning, typeModCode, typeModCodingScheme, typeModCodeMeaning, regionCode, regionCodingScheme, regionCodeMeaning, regionModCode, regionModCodingScheme, regionModCodeMeaning) # end of processing a line of terminology infoFile.close() # load the segmentation volume file and name it for the reference series and segment color labelFileName = os.path.join(outputDir, str(segmentId + 1) + ".nrrd") segmentName = seriesName + "-" + colorName + "-label" (success, labelNode) = slicer.util.loadLabelVolume( labelFileName, properties={'name': segmentName}, returnNode=True) segmentNodes.append(labelNode) # point the label node to the color node we're creating labelDisplayNode = labelNode.GetDisplayNode() if labelDisplayNode == None: print('Warning: no label map display node for segment ', segmentId, ', creating!') labelNode.CreateDefaultDisplayNodes() labelDisplayNode = labelNode.GetDisplayNode() labelDisplayNode.SetAndObserveColorNodeID( segmentationColorNode.GetID()) # TODO: initialize referenced UID (and segment number?) attribute(s) # create Subject hierarchy nodes for the loaded series self.addSeriesInSubjectHierarchy(loadable, labelNode) # create a combined (merge) label volume node (only if a segment was created) if labelNode: volumeLogic = slicer.modules.volumes.logic() mergeNode = volumeLogic.CloneVolume(labelNode, seriesName + "-label") combiner = slicer.vtkImageLabelCombine() for segmentNode in segmentNodes: combiner.SetInputConnection(0, mergeNode.GetImageDataConnection()) combiner.SetInputConnection( 1, segmentNode.GetImageDataConnection()) combiner.Update() mergeNode.GetImageData().DeepCopy(combiner.GetOutput()) for segmentNode in segmentNodes: segmentNode.Modified( ) # sets the MTime so the editor won't think they are older than mergeNode # display the mergeNode selectionNode = slicer.app.applicationLogic().GetSelectionNode() selectionNode.SetReferenceActiveLabelVolumeID(mergeNode.GetID()) slicer.app.applicationLogic().PropagateVolumeSelection(0) # finalize the color node segmentationColorNode.NamesInitialisedOn() # TODO: the outputDir should be cleaned up return True
import math import slicer # Test that a custom color table is consistent across scene view saves # and restores colorNode = slicer.vtkMRMLColorTableNode() colorNode.SetName('CustomTest') colorNode.SetHideFromEditors(0) colorNode.SetTypeToFile() colorNode.NamesInitialisedOff() colorNode.SetNumberOfColors(3) if colorNode.GetLookupTable() is not None: colorNode.GetLookupTable().SetTableRange(0, 2) colorNode.SetColor(0, 'zero', 0.0, 0.0, 0.0, 0.0) colorNode.SetColor(1, 'one', 1.0, 1.0, 1.0, 1.0) colorNode.SetColor(2, 'two', 0.5, 0.5, 0.5) colorNode.SetColorName(0, 'zero') colorNode.SetColorName(1, 'one') colorNode.SetColorName(2, 'two') colorNode.NamesInitialisedOn() slicer.mrmlScene.AddNode(colorNode) filePath = slicer.app.temporaryPath + "/customColorTableSceneViewRestore.ctbl" colorStorageNode = slicer.vtkMRMLColorTableStorageNode() colorStorageNode.SetFileName(filePath)