def test_SimpleITK_SlicerPushPull(self): """ Download the MRHead node """ import SampleData SampleData.downloadSample("MRHead") volumeNode1 = slicer.util.getNode('MRHead') self.assertEqual(volumeNode1.GetName(), "MRHead") """ Verify that pulling SimpleITK image from Slicer and then pushing it back creates an identical volume. """ sitkimage = su.PullVolumeFromSlicer(volumeNode1) self.assertIsNotNone(sitkimage) volumeNode1Copy = su.PushVolumeToSlicer( sitkimage, name="MRHead", className="vtkMRMLScalarVolumeNode") self.assertIsNotNone(volumeNode1Copy) """ Verify that image is not overwritten but a new one is created """ self.assertEqual(volumeNode1, slicer.util.getNode('MRHead'), 'Original volume is changed') self.assertNotEqual(volumeNode1, volumeNode1Copy, 'Copy of original volume is not created') """ Few modification of the image : Direction, Origin """ sitkimage.SetDirection((-1.0, 1.0, 0.0, 0.0, -1.0, 1.0, 1.0, 0.0, 1.0)) sitkimage.SetOrigin((100.0, 100.0, 100.0)) """ Few pixel changed """ size = sitkimage.GetSize() for x in range(0, size[0], int(size[0] / 10)): for y in range(0, size[1], int(size[1] / 10)): for z in range(0, size[2], int(size[2] / 10)): sitkimage.SetPixel(x, y, z, 0) volumeNode1Modified = su.PushVolumeToSlicer( sitkimage, name="ImageChanged", className="vtkMRMLScalarVolumeNode") self.assertEqual(volumeNode1Modified.GetName(), "ImageChanged", 'Volume name is not set correctly') self.assertNotEqual(volumeNode1.GetMTime(), volumeNode1Modified.GetMTime(), 'Error Push Pull: Modify Time are the same') """ Test the consistency between sitkimage and volumeNode1Modified """ tmp = volumeNode1Modified.GetOrigin() valToCompare = (-tmp[0], -tmp[1], tmp[2]) self.assertEqual(valToCompare, sitkimage.GetOrigin(), 'Modified origin mismatch') """ Test push with all parameter combinations """ for volumeClassName in [ 'vtkMRMLScalarVolumeNode', 'vtkMRMLLabelMapVolumeNode' ]: volumeNodeTested = None volumeNodeNew = None for pushToNewNode in [True, False]: print("volumeClassName : %s" % volumeClassName) print("pushToNewNode : %s " % pushToNewNode) if pushToNewNode: volumeNodeTested = su.PushVolumeToSlicer( sitkimage, name='volumeNode-' + volumeClassName + "-" + str(pushToNewNode), className=volumeClassName) existingVolumeNode = volumeNodeTested else: volumeNodeTested = su.PushVolumeToSlicer( sitkimage, existingVolumeNode) self.assertEqual(volumeNodeTested.GetClassName(), volumeClassName, 'Created volume node class is incorrect') slicer.mrmlScene.Clear(0)
def registerVolume(self, json_path, fixedNode, fixedMaskNode, outputVolumeNode=None): modules = slicer.modules if hasattr(modules, 'ParsePathJsonWidget'): widgetPresent = True else: widgetPresent = False if widgetPresent: self.cmdStartEvent() slicer.app.processEvents() if not self.logic: import sys sys.path.append(os.path.join(self.scriptPath, "Resources", "Utils")) import ParsePathJsonUtils as ppju self.logic = ppju.ParsePathJsonUtils() self.logic.setPath(json_path) if not self.logic.successfulInitialization: success = self.logic.initComponents() if not success: qt.QMessageBox.critical( slicer.util.mainWindow(), "Error", "Failure to load json. Check path!") return if not str(self.logic.path) == str(json_path): self.logic.setPath(json_path) if not self.logic.successfulInitialization: success = self.logic.initComponents() if not success: qt.QMessageBox.critical( slicer.util.mainWindow(), "Error", "Failure to load json. Check path!") return if outputVolumeNode: import sitkUtils slicer.app.processEvents() self.logic.pathologyVolume.imagingContraint = sitkUtils.PullVolumeFromSlicer( fixedNode) self.logic.pathologyVolume.imagingContraintMask = sitkUtils.PullVolumeFromSlicer( fixedMaskNode) self.logic.pathologyVolume.registerSlices(True) outputVolume = self.logic.pathologyVolume.loadRgbVolume() sitkUtils.PushVolumeToSlicer(outputVolume, targetNode=outputVolumeNode) selectionNode = slicer.app.applicationLogic().GetSelectionNode() selectionNode.SetReferenceActiveVolumeID(outputVolumeNode.GetID()) slicer.app.applicationLogic().PropagateVolumeSelection(0) else: qt.QMessageBox.critical(slicer.util.mainWindow(), "No Output", "Output Volume was not set!") if widgetPresent: self.cmdEndEvent()
Author : Jason Github : https://github.com/yuquant Description : """ import SimpleITK as sitk import slicer from slicer.util import * import sitkUtils # 导入nii图像和标签 image_path = r'D:/data/test_nii/prostate2label/images.nii.gz' label_path = r'D:/data/test_nii/prostate2label/labels.nii.gz' image_node = loadVolume(image_path) label = sitk.ReadImage(label_path) tmp_node = sitkUtils.PushVolumeToSlicer(sitkimage=label, targetNode=None, name='tmp', className='vtkMRMLLabelMapVolumeNode') seg_node = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSegmentationNode') # seg_node_name = 'labels' # seg_node = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSegmentationNode', seg_node_name) seg_node.SetName('seg') # seg_node.CreateDefaultDisplayNodes() # seg_node.GetSegmentation().AddEmptySegment() # 如果不添加上边这两行,就会发生下边的现象(如果不经过标注,也会导致标注无法修改),可能是seg node 的创建方式不对 # segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode() # 在现有标签的基础上叠加 # 由于缺少reference图像,似乎导入的像素会按照最小外接矩形切割,导致影响标注(区域外无法标注) # 目前存在的一个问题是标签的值的种类决定了标签数量,万一一个标签为空,则会导致所有顺序错位 slicer.modules.segmentations.logic().ImportLabelmapToSegmentationNode( tmp_node, seg_node)
def doCropping(self, inputVolume, point, croppingLength ): print("================= Begin cropping ... =====================") print("Cochlea location: " + str(point) + " cropping length: " + str(croppingLength) ) # resampling spacing self.RSx= self.RSxyz[0] ; self.RSy= self.RSxyz[1]; self.RSz= self.RSxyz[2] #Get input image information spacing = inputVolume.GetSpacing() imgData = inputVolume.GetImageData() dimensions = imgData.GetDimensions() # compute cropping bounds from image information and cropping parameters croppingBounds = [[0,0,0],[0,0,0]]; size = [0,0,0]; lower = [0,0,0] ; upper = [0,0,0] for i in range(0,3): size[i] = int((self.croppingLength[i]/spacing[i])/2) lower[i] = int(point[i]) - int(size[i]) upper[i] = dimensions[i] - int(point[i]+size[i]) # Check if calculated boundaries exceed image dimensions if lower[i] < 0: lower[i] = 0 #endif if upper[i] > dimensions[i]: upper[i] = int(dimensions[i]) #endif #endfor croppingBounds = [lower,upper] # Call SimpleITK CropImageFilter print("Cropping with " + str(croppingBounds[0]) + " and " + str(croppingBounds[1]) + ".") inputImage = sitkUtils.PullVolumeFromSlicer(inputVolume.GetID()) cropper = sitkUtils.sitk.CropImageFilter() croppedImage = cropper.Execute(inputImage, croppingBounds[0], croppingBounds[1]) nodeName = str(inputVolume.GetName()) + "_crop" self.inputCropPath = os.path.splitext(inputVolume.GetStorageNode().GetFileName())[0] + "_crop.nrrd" # Make a node with cropped image sitkUtils.PushVolumeToSlicer(croppedImage, None, nodeName , 'vtkMRMLScalarVolumeNode' ) crNodes = slicer.util.getNodesByClass("vtkMRMLScalarVolumeNode") for f in crNodes: if nodeName in f.GetName(): f.SetName(nodeName) break #endif #endfor self.croppedNode = slicer.util.getNode(nodeName) print("self.inputCropPath : " + str(self.inputCropPath )) #------------------------------------------------------- # Resampling: this produces better looking models #------------------------------------------------------- #Run slicer cli module: resample scalar volume params = {} params['InputVolume'] = self.croppedNode params['OutputVolume'] = self.croppedNode #Resample the cropped image inplace params['outputPixelSpacing'] = str(self.RSx) + "," + str(self.RSy) + "," + str(self.RSz) params['interpolationType'] = 'bspline' print("....... Resampling") slicer.cli.runSync(slicer.modules.resamplescalarvolume, None, params) # Save the resulted image to be used in elastix properties = {} properties["fileType"] = ".nrrd" self.inputCropPath = os.path.splitext(inputVolume.GetStorageNode().GetFileName())[0] + "_crop_iso.nrrd" print(" Cropping and resampling are done !!! ") # Save cropped image in directory of the original volume slicer.util.saveNode( self.croppedNode, self.inputCropPath) return self.inputCropPath
def updateSegmentationMask(self, extreme_points, in_file, modelInfo, overwriteCurrentSegment=False): start = time.time() logging.debug('Update Segmentation Mask from: {}'.format(in_file)) if in_file is None or os.path.exists(in_file) is False: return False segmentationNode = self.scriptedEffect.parameterSetNode( ).GetSegmentationNode() segmentation = segmentationNode.GetSegmentation() currentSegment = self.currentSegment() labelImage = sitk.ReadImage(in_file) labelmapVolumeNode = sitkUtils.PushVolumeToSlicer( labelImage, None, className='vtkMRMLLabelMapVolumeNode') numberOfExistingSegments = segmentation.GetNumberOfSegments() slicer.modules.segmentations.logic().ImportLabelmapToSegmentationNode( labelmapVolumeNode, segmentationNode) slicer.mrmlScene.RemoveNode(labelmapVolumeNode) modelLabels = modelInfo['labels'] numberOfAddedSegments = segmentation.GetNumberOfSegments( ) - numberOfExistingSegments logging.debug('Adding {} segments'.format(numberOfAddedSegments)) addedSegmentIds = [ segmentation.GetNthSegmentID(numberOfExistingSegments + i) for i in range(numberOfAddedSegments) ] for i, segmentId in enumerate(addedSegmentIds): segment = segmentation.GetSegment(segmentId) if i == 0 and overwriteCurrentSegment and currentSegment: logging.debug( 'Update current segment with id: {} => {}'.format( segmentId, segment.GetName())) # Copy labelmap representation to the current segment then remove the imported segment labelmap = slicer.vtkOrientedImageData() segmentationNode.GetBinaryLabelmapRepresentation( segmentId, labelmap) self.scriptedEffect.modifySelectedSegmentByLabelmap( labelmap, slicer.qSlicerSegmentEditorAbstractEffect. ModificationModeSet) segmentationNode.RemoveSegment(segmentId) else: logging.debug( 'Setting new segmentation with id: {} => {}'.format( segmentId, segment.GetName())) if i < len(modelLabels): segment.SetName(modelLabels[i]) else: # we did not get enough labels (for exampe annotation_mri_prostate_cg_and_pz model returns a labelmap with # 2 labels but in the model infor only 1 label is provided) segment.SetName("unknown {}".format(i)) # Save extreme points into first segment if extreme_points: logging.debug('Extreme Points: {}'.format(extreme_points)) if overwriteCurrentSegment and currentSegment: segment = currentSegment else: segment = segmentation.GetNthSegment(numberOfExistingSegments) if segment: segment.SetTag("AIAA.DExtr3DExtremePoints", json.dumps(extreme_points)) os.unlink(in_file) logging.info( "Time consumed by updateSegmentationMask: {0:3.1f}".format( time.time() - start)) return True
def run(self, inputVolume, fiducialMarker): """ Run the actual algorithm """ inputVolume_origin = inputVolume.GetOrigin() inputVolume_spacing = inputVolume.GetSpacing() inputVolume_size = inputVolume.GetImageData().GetDimensions() spine_img = sitkUtils.PullVolumeFromSlicer(inputVolume) size_of_bbox = np.ceil( np.array([128, 128, 64]) / np.array(inputVolume_spacing)).astype( np.int) fiducial_coords_world_hold = [0, 0, 0, 0] numFids = fiducialMarker.GetNumberOfFiducials() for idx in range(numFids): fiducialMarker.GetNthFiducialWorldCoordinates( idx, fiducial_coords_world_hold) fiducial_coords_world = fiducial_coords_world_hold fiducial_coords_world[0] = fiducial_coords_world[0] * (-1) fiducial_coords_world[1] = fiducial_coords_world[1] * (-1) # Bounding box is [128, 128, 64] in mm with respect to the world coordinates fiducial_coords = np.floor( spine_img.TransformPhysicalPointToIndex( fiducial_coords_world[:3])).astype(np.int) ROI = sitk.RegionOfInterestImageFilter() ROI.SetSize([ int(size_of_bbox[0]), int(size_of_bbox[1]), int(size_of_bbox[2]) ]) ROI_initial_index = fiducial_coords - size_of_bbox / 2 ROI_initial_index = [ roi_idx if roi_idx > 0 else 0 for roi_idx in ROI_initial_index ] ROI.SetIndex([ int(ROI_initial_index[0]), int(ROI_initial_index[1]), int(ROI_initial_index[2]) ]) spine_img_cropped = ROI.Execute(spine_img) # Resample cropped spine image spacingOut = [1.0, 1.0, 1.0] resample = sitk.ResampleImageFilter() resample.SetReferenceImage(spine_img_cropped) resample.SetInterpolator(sitk.sitkLinear) shapeIn = spine_img_cropped.GetSize() spacingIn = spine_img_cropped.GetSpacing() newSize = [ int(shapeIn[0] * spacingIn[0] / spacingOut[0]), int(shapeIn[1] * spacingIn[1] / spacingOut[1]), int(shapeIn[2] * spacingIn[2] / spacingOut[2]) ] resample.SetSize(newSize) resample.SetOutputSpacing(spacingOut) spine_img_resampled = resample.Execute(spine_img_cropped) # Second cropping to ensure image is the right size. Could be off my a 1 due to rounding. ROI = sitk.RegionOfInterestImageFilter() ROI.SetSize([128, 128, 64]) ROI.SetIndex([0, 0, 0]) spine_img_resampled = ROI.Execute(spine_img_resampled) # Get the spine data in a numpy array. spine_data = sitk.GetArrayFromImage(spine_img_resampled) y_pred_np = self.segment_vertebrae(spine_data) y_pred_sitk = sitk.GetImageFromArray(y_pred_np) y_pred_sitk.CopyInformation(spine_img_resampled) resample_back = sitk.ResampleImageFilter() resample_back.SetReferenceImage(spine_img) affine = sitk.AffineTransform(3) resample_back.SetTransform(affine) resample_back.SetInterpolator(sitk.sitkNearestNeighbor) y_pred_sitk_full_size = resample_back.Execute(y_pred_sitk) #self.seg_pred = sitkUtils.PushVolumeToSlicer(y_pred_sitk) self.segVolumeNode = sitkUtils.PushVolumeToSlicer( y_pred_sitk_full_size, name='segPrediction', className='vtkMRMLLabelMapVolumeNode') return True
def generateSurfaceModel(self, markupsNode, modelNode, pointDistanceFactor): svnode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLScalarVolumeNode') print('Generating a surface model from tracking data... ') ## Generate a scalar volume node # Get the bounding box print('Calculating bounding box... ') bounds = [0.0] * 6 markupsNode.GetBounds(bounds) print(bounds) b = numpy.array(bounds) b = b.reshape((3, 2)) origin = numpy.mean(b, axis=1) fov = numpy.abs(b[:, 1] - b[:, 0]) fovMax = numpy.max(fov) boundingBoxRange = ( fovMax * 1.5 ) / 2.0 # 1.5 times larger than the bounding box; from the center to the end (1/2 of each dimension) b[:, 0] = origin - boundingBoxRange b[:, 1] = origin + boundingBoxRange bounds = b.reshape(-1) print(bounds) res = 256 print('Converting fiducials to poly data...') poly = self.fiducialsToPoly(markupsNode) #Note: Altenatively, vtkImageEllipsoidSource may be used to generate a volume. # Generate density field from points # Use fixed radius print('Running vtkPointDensityFilter...') dens = vtk.vtkPointDensityFilter() dens.SetInputData(poly) # TODO - is the resolution good enoguh? dens.SetSampleDimensions(res, res, res) dens.SetDensityEstimateToFixedRadius() # TODO - Does this radius work for every case? pixelSize = boundingBoxRange * 2 / res # Note: the algorithm fails when the bounding box is too small.. if pixelSize < 0.5: pixelSize = 0.5 radius = pixelSize dens.SetRadius(radius) #dens.SetDensityEstimateToRelativeRadius() #dens.SetRelativeRadius(2.5) #dens.SetDensityFormToVolumeNormalized() dens.SetDensityFormToNumberOfPoints() dens.SetModelBounds(bounds) dens.ComputeGradientOn() dens.Update() print('Creating an image node...') # Crete an image node - geometric parameters (origin, spacing) must be moved to the node object #imnode = slicer.vtkMRMLScalarVolumeNode() imnode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLScalarVolumeNode') imnode.SetName('MRTracking_SurfaceMap_tmp') imdata = dens.GetOutput() imnode.SetAndObserveImageData(imdata) imnode.SetOrigin(imdata.GetOrigin()) imnode.SetSpacing(imdata.GetSpacing()) #imdata.SetOrigin([0.0, 0.0, 0.0]) #imdata.SetSpacing([1.0, 1.0, 1.0]) slicer.mrmlScene.AddNode(imnode) print('Applying BinaryThreshold...') image = sitkUtils.PullVolumeFromSlicer(imnode.GetID()) binImage = sitk.BinaryThreshold(image, lowerThreshold=1.0, upperThreshold=256, insideValue=1, outsideValue=0) # Calculate the radius parameter for dilation and erosion radiusInPixel = int(numpy.ceil(pointDistanceFactor / pixelSize)) if radiusInPixel < 1.0: radiusInPixel = 1 # Dilate the target label print('Dilating the image...') dilateFilter = sitk.BinaryDilateImageFilter() dilateFilter.SetBoundaryToForeground(False) dilateFilter.SetKernelRadius(radiusInPixel) dilateFilter.SetKernelType(sitk.sitkBall) dilateFilter.SetForegroundValue(1) dilateFilter.SetBackgroundValue(0) dilateImage = dilateFilter.Execute(binImage) # Fill holes in the target label print('Filling holes...') fillHoleFilter = sitk.BinaryFillholeImageFilter() fillHoleFilter.SetForegroundValue(1) fillHoleFilter.SetFullyConnected(True) fillHoleImage = fillHoleFilter.Execute(dilateImage) # Erode the label print('Eroding the image...') erodeFilter = sitk.BinaryErodeImageFilter() erodeFilter.SetBoundaryToForeground(False) erodeFilter.SetKernelType(sitk.sitkBall) erodeFilter.SetKernelRadius( radiusInPixel - 1) # 1 pixel smaller than the radius for dilation. erodeFilter.SetForegroundValue(1) erodeFilter.SetBackgroundValue(0) erodeImage = erodeFilter.Execute(fillHoleImage) print('Pushing the volume to the MRML scene...') sitkUtils.PushVolumeToSlicer(erodeImage, imnode.GetName(), 0, True) imdata = imnode.GetImageData() imdata.SetOrigin(imnode.GetOrigin()) imdata.SetSpacing(imnode.GetSpacing()) print('Running marching cubes...') poly = self.marchingCubes(imdata) modelNode.SetAndObservePolyData(poly) slicer.mrmlScene.RemoveNode(imnode) print('Done.')
def run(self, gtCTVolumeName, sCTVolumeName, maskVolumeName, outputVolume): """ Run accuracy assessment. """ # Get sitk/numpy images from Slicer gtCT_sitk = sitk.Cast(sitkUtils.PullVolumeFromSlicer(gtCTVolumeName), sitk.sitkFloat32) sCT_sitk = sitk.Cast(sitkUtils.PullVolumeFromSlicer(sCTVolumeName), sitk.sitkFloat32) mask_sitk = sitk.Cast(sitkUtils.PullVolumeFromSlicer(maskVolumeName), sitk.sitkLabelUInt8) mask_sitk = sitk.LabelMapToBinary(mask_sitk) #TODO: investigate better if mask is binary or not here gtCT = sitk.GetArrayFromImage(gtCT_sitk).astype(np.float32) sCT = sitk.GetArrayFromImage(sCT_sitk).astype(np.float32) mask = self.binarizeNumpyMask(sitk.GetArrayFromImage(mask_sitk)) # Compute MAE and ME img_difference = gtCT - sCT img_difference[mask == 0] = -1000 img_difference_sitk = sitk.GetImageFromArray(img_difference) img_difference_sitk.CopyInformation(gtCT_sitk) img_difference[mask == 0] = np.nan mae = np.nanmean(np.abs(img_difference).flatten()) me = np.nanmean(img_difference.flatten()) # If the table does not exist, create it if self.hasTable == False: self.hasTable = True # Create table self.tableNode = slicer.mrmlScene.AddNewNodeByClass( "vtkMRMLTableNode") self.table = self.tableNode.GetTable() arrX = vtk.vtkFloatArray() arrX.SetName("HU") self.table.AddColumn(arrX) arrY = vtk.vtkFloatArray() arrY.SetName("DSC") self.table.AddColumn(arrY) # Create plot node plotSeriesNode = slicer.mrmlScene.AddNewNodeByClass( "vtkMRMLPlotSeriesNode", "Bone threshold segmentation") plotSeriesNode.SetAndObserveTableNodeID(self.tableNode.GetID()) plotSeriesNode.SetXColumnName("HU") plotSeriesNode.SetYColumnName("DSC") plotSeriesNode.SetPlotType( slicer.vtkMRMLPlotSeriesNode.PlotTypeScatter) plotSeriesNode.SetMarkerStyle( slicer.vtkMRMLPlotSeriesNode.MarkerStyleSquare) plotSeriesNode.SetUniqueColor() # Create plot chart node self.plotChartNode = slicer.mrmlScene.AddNewNodeByClass( "vtkMRMLPlotChartNode") self.plotChartNode.AddAndObservePlotSeriesNodeID( plotSeriesNode.GetID()) self.plotChartNode.SetTitle('Bone threshold assessment') self.plotChartNode.SetXAxisTitle('[HU]') self.plotChartNode.SetYAxisTitle('DSC') self.plotChartNode.LegendVisibilityOff() # Fill table with DSC value for bone thrs = np.arange(100.0, 1100.0, 100.0) self.table.SetNumberOfRows(len(thrs)) overlap_measures_filter = sitk.LabelOverlapMeasuresImageFilter() for i, thr in enumerate(thrs): gtCT_bin = sitk.BinaryThreshold(sitk.Mask(gtCT_sitk, mask_sitk, outsideValue=-1000), lowerThreshold=thr, upperThreshold=1500.0, insideValue=1, outsideValue=0) sCT_bin = sitk.BinaryThreshold(sitk.Mask(sCT_sitk, mask_sitk, outsideValue=-1000), lowerThreshold=thr, upperThreshold=1500.0, insideValue=1, outsideValue=0) overlap_measures_filter.Execute(gtCT_bin, sCT_bin) dsc = overlap_measures_filter.GetDiceCoefficient() # TODO: empty table before each run? self.table.SetValue(i, 0, thr) self.table.SetValue(i, 1, dsc) # Switch to a layout that contains a plot view to create a plot widget layoutManager = slicer.app.layoutManager() layoutWithPlot = slicer.modules.plots.logic().GetLayoutWithPlot( layoutManager.layout) layoutManager.setLayout(layoutWithPlot) # Select chart in plot view plotWidget = layoutManager.plotWidget(0) plotViewNode = plotWidget.mrmlPlotViewNode() plotViewNode.SetPlotChartNodeID(self.plotChartNode.GetID()) # Show diff image outputVolume = sitkUtils.PushVolumeToSlicer(img_difference_sitk, outputVolume) setSliceViewerLayers(background=outputVolume) displayNode = outputVolume.GetDisplayNode() displayNode.SetAndObserveColorNodeID('vtkMRMLColorTableNodeRainbow') return mae, me
def updateSegmentationMask(self, extreme_points, in_file, modelInfo): start = time.time() logging.debug('Update Segmentation Mask from: {}'.format(in_file)) if in_file is None or os.path.exists(in_file) is False: return False segmentationNode = self.scriptedEffect.parameterSetNode( ).GetSegmentationNode() selectedSegmentId = self.scriptedEffect.parameterSetNode( ).GetSelectedSegmentID() segmentation = segmentationNode.GetSegmentation() segment = segmentation.GetSegment(selectedSegmentId) color = segment.GetColor() label = segment.GetName() labelImage = sitk.ReadImage(in_file) labelmapVolumeNode = sitkUtils.PushVolumeToSlicer( labelImage, None, className='vtkMRMLLabelMapVolumeNode') labelmapVolumeNode.SetName(label) # [success, labelmapVolumeNode] = slicer.util.loadLabelVolume(in_file, {'name': label}, returnNode=True) logging.debug( 'Removing temp segmentation with id: {} with color: {}'.format( selectedSegmentId, color)) segmentationNode.RemoveSegment(selectedSegmentId) originalSegments = dict() for i in range(segmentation.GetNumberOfSegments()): segmentId = segmentation.GetNthSegmentID(i) originalSegments[segmentId] = i slicer.modules.segmentations.logic().ImportLabelmapToSegmentationNode( labelmapVolumeNode, segmentationNode) slicer.mrmlScene.RemoveNode(labelmapVolumeNode) addedSegments = 0 modelLabels = modelInfo.get('labels') for i in range(segmentation.GetNumberOfSegments()): segmentId = segmentation.GetNthSegmentID(i) segment = segmentation.GetSegment(segmentId) if originalSegments.get(segmentId) is not None: logging.debug( 'No change for existing segment with id: {} => {}'.format( segmentId, segment.GetName())) continue logging.debug('Setting new segmentation with id: {} => {}'.format( segmentId, segment.GetName())) if addedSegments == 0: segment.SetColor(color) segment.SetName(label) self.scriptedEffect.parameterSetNode().SetSelectedSegmentID( segmentId) logging.debug('Extreme Points: {}'.format(extreme_points)) if extreme_points is not None: segment.SetTag("DExtr3DExtremePoints", json.dumps(extreme_points)) else: segment.SetName(modelLabels[addedSegments]) addedSegments = addedSegments + 1 logging.debug('Total Added Segments for {}: {}'.format( label, addedSegments)) self.extremePoints[label] = extreme_points os.unlink(in_file) logging.info("++ Time consumed by updateSegmentationMask: {}".format( time.time() - start)) return True