def runBinaryThresholdImageFilter(self, inputNode, outputNode): # run Simple ITK threshold Filter inputImage = sitkUtils.PullVolumeFromSlicer(inputNode) myFilter = sitk.BinaryThresholdImageFilter() myFilter.SetLowerThreshold(0.5) outputImage = myFilter.Execute(inputImage) sitkUtils.PushVolumeToSlicer(outputImage, outputNode) # run Simple ITK fill holes Filter inputImage = sitkUtils.PullVolumeFromSlicer(outputNode) myFilter = sitk.BinaryFillholeImageFilter() outputImage = myFilter.Execute(inputImage) sitkUtils.PushVolumeToSlicer(outputImage, outputNode)
def applyITKOtsuFilter(self, volume): inputVolume = sitk.Cast(sitkUtils.PullVolumeFromSlicer(volume.GetID()), sitk.sitkInt16) self.otsuFilter.SetInsideValue(0) self.otsuFilter.SetOutsideValue(1) otsuITKVolume = self.otsuFilter.Execute(inputVolume) return sitkUtils.PushToSlicer(otsuITKVolume, "otsuITKVolume", 0, True)
def run(self, SegSelectList, spineNode): seg_encode_list = [] seg_full = None for idx, seg_select in enumerate(SegSelectList): seg_node = seg_select.currentNode() if seg_node is None: continue seg_img = sitkUtils.PullVolumeFromSlicer(seg_node) seg_img_encode = sitk.Multiply(seg_img, vert_encode[vert_list[idx]]) if seg_full is None: seg_full = seg_img_encode else: seg_full = sitk.Add(seg_full, seg_img_encode) seg_name = spineNode.GetName() self.segCombineVol = sitkUtils.PushVolumeToSlicer( seg_full, name=seg_name + '_seg', className='vtkMRMLLabelMapVolumeNode') slicer.util.setSliceViewerLayers(label=self.segCombineVol, labelOpacity=1) return self.segCombineVol
def BiasFieldCorrection(self, image): # Generate mask for N4ITK image = sitk.Cast(image, sitk.sitkFloat32) rescaled = sitk.RescaleIntensity(image, 0.0, 1.0) kmeans = sitk.ScalarImageKmeans(rescaled, [0.1, 0.3, 0.5, 0.7, 0.9]) biasFieldCorrectionMask = sitk.Greater(kmeans, 0) # Create scene nodes inputNode = sitkUtils.PushVolumeToSlicer(image) maskNode = sitkUtils.PushVolumeToSlicer(biasFieldCorrectionMask) outputNode = slicer.mrmlScene.AddNewNodeByClass( 'vtkMRMLScalarVolumeNode') # Run N4ITK CLI module n4itk = slicer.modules.n4itkbiasfieldcorrection parameters = {} parameters['inputImageName'] = inputNode.GetID() parameters['maskImageName'] = maskNode.GetID() parameters['outputImageName'] = outputNode.GetID() parameters['bfFWHM'] = 0.4 slicer.cli.runSync(n4itk, None, parameters) # Retrieve output image outputImage = sitkUtils.PullVolumeFromSlicer(outputNode) # Clean up nodes slicer.mrmlScene.RemoveNode(inputNode) slicer.mrmlScene.RemoveNode(maskNode) slicer.mrmlScene.RemoveNode(outputNode) return outputImage
def getScoresVolumeNode(self, scoresDict, colorNode, parcellationLabelMapNode): parcellationImage = su.PullVolumeFromSlicer(parcellationLabelMapNode) parcellationArray = sitk.GetArrayViewFromImage(parcellationImage) scoresArray = np.zeros_like(parcellationArray) if scoresDict is not None: for (label, score) in scoresDict.items(): label = int(label) score = float(score) labelMask = parcellationArray == label scoresArray[labelMask] = score scoresImage = self.getImageFromArray(scoresArray, parcellationImage) scoresName = 'Scores' scoresVolumeNode = su.PushVolumeToSlicer(scoresImage, name=scoresName) displayNode = scoresVolumeNode.GetDisplayNode() displayNode.SetAutoThreshold(False) displayNode.SetAndObserveColorNodeID(colorNode.GetID()) displayNode.SetLowerThreshold(1) displayNode.ApplyThresholdOn() displayNode.SetAutoWindowLevel(False) windowMin = scoresArray[ scoresArray > 0].min() if scoresArray.any() else 0 windowMax = scoresArray.max() displayNode.SetWindowLevelMinMax(windowMin, windowMax) return scoresVolumeNode
def doCropping(self, inputVolume, point): print("================= Begin cropping ... =====================") print("Cochlea location: " + str(point)) spacing = inputVolume.GetSpacing() imgData = inputVolume.GetImageData() dimensions = imgData.GetDimensions() croppingBounds = [[0, 0, 0], [0, 0, 0]] croppingBounds = self.calculateCroppingBounds(dimensions, spacing, point) # 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]) # Calculate file name and path of cropped image storageNode = inputVolume.GetStorageNode() pathWithoutExtension = os.path.splitext(storageNode.GetFileName())[0] savepath = pathWithoutExtension + "_crop.nrrd" # Save cropped image in directory of the original volume sitkUtils.PushVolumeToSlicer(croppedImage, None, inputVolume.GetName() + "_crop", 'vtkMRMLScalarVolumeNode') nodeName = str(inputVolume.GetName()) + "_crop" print("savepath" + str(savepath)) slicer.util.saveNode(slicer.util.getNode(nodeName), savepath) print("================= Cropping finished =====================") return savepath
def Execute(self, inputVolume): sitkInput = su.PullVolumeFromSlicer(inputVolume) # Calculation required to generate distance map distanceFilter = sitk.DanielssonDistanceMapImageFilter() sitkOutput = distanceFilter.Execute(sitkInput) # Commumication by pushing to slicer distance_map_Volume = su.PushVolumeToSlicer(sitkOutput, None, 'distanceMap_obstacle') return distance_map_Volume
def rescaleImage(self, inputNode, outputNode, minValue, maxValue): print("Rescale image...") import sitkUtils import SimpleITK as sitk sitkImg = sitkUtils.PullVolumeFromSlicer(inputNode) sitkImgResc = sitk.RescaleIntensity(sitkImg, minValue, maxValue) sitkUtils.PushVolumeToSlicer(sitkImgResc, outputNode)
def applyOtsuFilter(volume): otsuFilter = sitk.OtsuThresholdImageFilter() otsuFilter.SetInsideValue(0) otsuFilter.SetOutsideValue(1) inputVolume = sitk.Cast(sitkUtils.PullVolumeFromSlicer(volume.GetID()), sitk.sitkInt16) outputITKVolume = otsuFilter.Execute(inputVolume) outputVolume = sitkUtils.PushToSlicer(outputITKVolume, "ZFrame_Otsu_Output", 0, True) return outputVolume
def test_CalculateDistanceImageFromLabelMap_output(self): self.delayDisplay("Starting test: CalculateDistanceImageFromLabelMap Check output") inputObstacle = slicer.util.getNode('ventricles'); sitkInput = su.PullVolumeFromSlicer(inputObstacle) # compute distance map distanceFilter = sitk.DanielssonDistanceMapImageFilter(); sitkOutput = distanceFilter.Execute(sitkInput) # push to slicer distance_map_Volume = su.PushVolumeToSlicer(sitkOutput, None, 'distanceMap_obstacle') self.assertIsNotNone(distance_map_Volume) self.delayDisplay('Test passed! Output is as expected')
def onApplyZFrameRegistrationButtonClicked(self): zFrameTemplateVolume = self.logic.templateVolume try: if self.zFrameRegistrationClass is OpenSourceZFrameRegistration: self.annotationLogic.SetAnnotationLockedUnlocked( self.coverTemplateROI.GetID()) self.zFrameCroppedVolume = self.logic.createCroppedVolume( zFrameTemplateVolume, self.coverTemplateROI) self.zFrameLabelVolume = self.logic.createLabelMapFromCroppedVolume( self.zFrameCroppedVolume, "labelmap") self.zFrameMaskedVolume = self.logic.createMaskedVolume( zFrameTemplateVolume, self.zFrameLabelVolume, outputVolumeName="maskedTemplateVolume") self.zFrameMaskedVolume.SetName( zFrameTemplateVolume.GetName() + "-label") if not self.zFrameRegistrationManualIndexesGroupBox.checked: start, center, end = self.logic.getROIMinCenterMaxSliceNumbers( self.coverTemplateROI) inputVolume = sitk.Cast( sitkUtils.PullVolumeFromSlicer( self.zFrameMaskedVolume.GetID()), sitk.sitkInt16) self.logic.otsuFilter.SetInsideValue(0) self.logic.otsuFilter.SetOutsideValue(1) otsuITKVolume = self.logic.otsuFilter.Execute(inputVolume) otsuOutputVolume = sitkUtils.PushToSlicer( otsuITKVolume, "otsuITKVolume", 0, True) self.logic.dilateMask(otsuOutputVolume) start, end = self.logic.getStartEndWithConnectedComponents( otsuOutputVolume, center) self.zFrameRegistrationStartIndex.value = start self.zFrameRegistrationEndIndex.value = end else: start = self.zFrameRegistrationStartIndex.value end = self.zFrameRegistrationEndIndex.value self.logic.runZFrameRegistration(self.zFrameMaskedVolume, self.zFrameRegistrationClass, startSlice=start, endSlice=end) else: self.logic.runZFrameRegistration(zFrameTemplateVolume, self.zFrameRegistrationClass) self.applyZFrameTransform() except AttributeError as exc: slicer.util.errorDisplay( "An error occurred. For further information click 'Show Details...'", windowTitle=self.__class__.__name__, detailedText=str(exc.message)) else: self.setBackgroundToVolumeID(zFrameTemplateVolume.GetID()) self.approveZFrameRegistrationButton.enabled = True self.retryZFrameRegistrationButton.enabled = True
def __call__(self, inputVolumeNode, outputVolumeNode): image = su.PullVolumeFromSlicer(inputVolumeNode) data, affine = torchio.io.sitk_to_nib(image) tensor = torch.from_numpy(data.astype( np.float32)) # why do I need this? Open a TorchIO issue? if inputVolumeNode.IsA('vtkMRMLScalarVolumeNode'): image = torchio.ScalarImage(tensor=tensor, affine=affine) elif inputVolumeNode.IsA('vtkMRMLLabelMapVolumeNode'): image = torchio.LabelMap(tensor=tensor, affine=affine) transformed = self.getTransform()(image) image = torchio.io.nib_to_sitk(transformed.data, transformed.affine) su.PushVolumeToSlicer(image, targetNode=outputVolumeNode) return outputVolumeNode
def ComputeDistanceMap(self, input): sitkInput = su.PullVolumeFromSlicer(input) distanceFilter = sitk.DanielssonDistanceMapImageFilter() sitkOutput = distanceFilter.Execute(sitkInput) outputVolume = su.PushVolumeToSlicer(sitkOutput, None, 'distanceMap') mat = vtk.vtkMatrix4x4() outputVolume.GetRASToIJKMatrix(mat) transform = vtk.vtkTransform() transform.SetMatrix(mat) return outputVolume, transform
def processVolume(self, workingSelector, processingSelector, tempMin, tempMax, coordinates, name): print("processing") inputImage = sitkUtils.PullVolumeFromSlicer( workingSelector.currentNode()) volumesLogic = slicer.modules.volumes.logic() processedVolume = volumesLogic.CloneVolume( slicer.mrmlScene, workingSelector.currentNode(), name) #extract image from volume zslice = 0 size = list(inputImage.GetSize()) size[2] = 0 index = [0, 0, zslice] Extractor = sitk.ExtractImageFilter() Extractor.SetSize(size) Extractor.SetIndex(index) outputImage = Extractor.Execute(inputImage) # step 1)filtering: noise reduction imgSmooth = sitk.CurvatureFlow(image1=outputImage, timeStep=0.125, numberOfIterations=5) # step 2) filtering: segmentation # aux = self.rasToXYZ(coordinates) # coordinates=[197, 140, 190,2] lstSeeds = [()] lstSeeds[0] = tuple(coordinates[0:2]) print(lstSeeds) print(coordinates) labelLeftHand = 1 imgLeftHand = sitk.ConnectedThreshold(image1=imgSmooth, seedList=lstSeeds, lower=tempMin, upper=tempMax, replaceValue=labelLeftHand) #step 3) create image to display imgSmoothInt = sitk.Cast(sitk.RescaleIntensity(imgSmooth), imgLeftHand.GetPixelID()) # Use 'LabelOverlay' to overlay 'imgSmooth' and 'imgWhiteMatter' outI = sitk.LabelOverlay(imgSmoothInt, imgLeftHand) outI2 = sitk.Multiply(imgSmooth, sitk.Cast(imgLeftHand, sitk.sitkFloat64)) return outI2
def __call__(self, inputVolumeNode, outputVolumeNode): image = su.PullVolumeFromSlicer(inputVolumeNode) tensor, affine = torchio.io.sitk_to_nib(image) if inputVolumeNode.IsA('vtkMRMLScalarVolumeNode'): image = torchio.ScalarImage(tensor=tensor, affine=affine) elif inputVolumeNode.IsA('vtkMRMLLabelMapVolumeNode'): image = torchio.LabelMap(tensor=tensor, affine=affine) subject = torchio.Subject(image=image) # to get transform history transformed = self.getTransform()(subject) deterministicApplied = transformed.get_applied_transforms()[0] logging.info(f'Applied transform: {deterministicApplied}') transformedImage = transformed.image image = torchio.io.nib_to_sitk(transformedImage.data, transformedImage.affine) su.PushVolumeToSlicer(image, targetNode=outputVolumeNode) return outputVolumeNode
def image2points(self,inputImg): print("====================================================") print("= Image to Points =") print("====================================================") # clone the input image nimg = sitkUtils.PullVolumeFromSlicer(inputImg.GetID()) sz= inputImg.GetImageData().GetDimensions() tmpImgArray = slicer.util.array(inputImg.GetID()) nimgMax = tmpImgArray.max() nimgMin = tmpImgArray.min() b= zip( *np.where(tmpImgArray > (nimgMax/2 ) ) ) NoPts = len(b) ptsIJK =np.zeros((NoPts,4)) ptsIJKtmp=np.zeros((NoPts,4)) print("Number of points imported: " + str(NoPts)) for j in range (0,NoPts): x= b[j][2] ; y= b[j][1] ; z= b[j][0] ptsIJK[j][0:3] =[ x ,y, z ] ptsIJKtmp[j][0:3] =[ x ,y, z ] ptsIJKtmp[j][3] = tmpImgArray[z][y][x] #end for ptsIJKtmp= sorted(ptsIJKtmp, key = lambda t: t[-1]) self.markupsNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode") self.markupsNode.CreateDefaultDisplayNodes() self.markupsNode.SetName("P") mrk=slicer.modules.markups.logic() mrk.SetDefaultMarkupsDisplayNodeColor(9) mrk.SetDefaultMarkupsDisplayNodeGlyphScale(1.5) mrk.SetDefaultMarkupsDisplayNodeTextScale(0.20) ptsRAS =np.zeros((NoPts,3)) for j in range (0,NoPts): ptsIJK[j][0:3] = ptsIJKtmp[j][0:3] ptsRAS[j]= self.ptIJK2RAS(ptsIJK[j],inputImg) x = ptsRAS[j][0]; y = ptsRAS[j][1] ; z = ptsRAS[j][2] self.markupsNode.AddFiducial(x,y,z) #endfor # get the file name at the first of the plugin # this keeps the fiducials with short name self.markupsNode.SetName(self.inputFnm + "StPts") # Remove image points slicer.mrmlScene.RemoveNode(self.resImgPtsNode)
def dilate(labelmapNode, spread): outNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLLabelMapVolumeNode") # kernel radius kernel_radius = int(spread / labelmapNode.GetSpacing()[0]) # TODO: anisotropic # sitk filter myFilter = sitk.BinaryDilateImageFilter() myFilter.SetBackgroundValue(0.0) myFilter.SetBoundaryToForeground(False) myFilter.SetDebug(False) myFilter.SetForegroundValue(1.0) myFilter.SetKernelRadius((kernel_radius, kernel_radius, kernel_radius)) myFilter.SetKernelType(1) inputImage = sitkUtils.PullVolumeFromSlicer(labelmapNode) outputImage = myFilter.Execute(inputImage) sitkUtils.PushVolumeToSlicer(outputImage, outNode) return outNode
def getDistanceMap(labelMapNode): # labelmap to scalar outNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLScalarVolumeNode') slicer.modules.volumes.logic().CreateScalarVolumeFromVolume( slicer.mrmlScene, outNode, labelMapNode) # cast type to int imageCast = vtk.vtkImageCast() imageCast.SetInputData(outNode.GetImageData()) imageCast.SetOutputScalarTypeToInt() imageCast.Update() outNode.SetAndObserveImageData(imageCast.GetOutput()) # replace values above 1 to 1 a = slicer.util.array(outNode.GetID()) a[a > 0] = 1 outNode.Modified() # filter myFilter = sitk.ApproximateSignedDistanceMapImageFilter() myFilter.SetDebug(False) myFilter.SetInsideValue(1.0) myFilter.SetOutsideValue(0.0) inputImage = sitkUtils.PullVolumeFromSlicer(outNode) outputImage = myFilter.Execute(inputImage) sitkUtils.PushVolumeToSlicer(outputImage, outNode) return outNode
def doCropping(self, inputVolume, point): print("================= Begin cropping ... =====================") print("Cochlea location: " + str(point)) spacing = inputVolume.GetSpacing() imgData = inputVolume.GetImageData() dimensions = imgData.GetDimensions() croppingBounds = [[0, 0, 0], [0, 0, 0]] size = [0, 0, 0] for i in range(0, 3): size[i] = int((self.croppingLength / spacing[i]) / 2) # Calculate lower and upper cropping bounds lower = [0, 0, 0] for i in range(0, 3): lower[i] = point[i] - size[i] upper = [0, 0, 0] for i in range(0, 3): upper[i] = dimensions[i] - (point[i] + size[i]) # Check if calculated boundaries exceed image dimensions for i in [lower, upper]: for j in range(0, 3): if i[j] < 0: i[j] = 0 if i[j] > dimensions[j]: i[j] = dimensions[j] croppingBounds = [lower, upper] # Call SimpleITK CropImageFilter print("Cropping with " + str(croppingBounds[0]) + " and " + str(croppingBounds[1]) + ".") inputImage = sitkUtils.PullVolumeFromSlicer(self.inputNode.GetID()) cropper = sitkUtils.sitk.CropImageFilter() #this generates itk image croppedImage = cropper.Execute(inputImage, croppingBounds[0], croppingBounds[1]) self.inputCropPath = os.path.splitext( self.inputNode.GetStorageNode().GetFileName())[0] + "_crop.nrrd" # Make a node with cropped image sitkUtils.PushVolumeToSlicer(croppedImage, None, inputVolume.GetName() + "_crop", 'vtkMRMLScalarVolumeNode') nodeName = str(inputVolume.GetName()) + "_crop" 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(self.inputNode.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 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 runProcessing(self, workingSelector, processingSelector, tempMin, tempMax): # outputVolume=workingSelector.currentNode() inputImage = sitkUtils.PullVolumeFromSlicer( workingSelector.currentNode()) # extract image from volume zslice = 0 size = list(inputImage.GetSize()) size[2] = 0 index = [0, 0, zslice] Extractor = sitk.ExtractImageFilter() Extractor.SetSize(size) Extractor.SetIndex(index) outputImage = Extractor.Execute(inputImage) if processingSelector.currentText == "original": # original print("no processing required ") return elif processingSelector.currentText == "image smoothing": # step 1)filtering: noise reduction outI2 = sitk.CurvatureFlow(image1=outputImage, timeStep=0.125, numberOfIterations=5) elif processingSelector.currentText == "image segmentation": # step 1)filtering: noise reduction imgSmooth = sitk.CurvatureFlow(image1=outputImage, timeStep=0.125, numberOfIterations=5) # step 2) filtering: segmentation lstSeeds = [(247, 86)] labelLeftHand = 1 imgLeftHand = sitk.ConnectedThreshold(image1=imgSmooth, seedList=lstSeeds, lower=tempMin, upper=tempMax, replaceValue=labelLeftHand) # step 3) create image to display imgSmoothInt = sitk.Cast(sitk.RescaleIntensity(imgSmooth), imgLeftHand.GetPixelID()) # Use 'LabelOverlay' to overlay 'imgSmooth' and 'imgWhiteMatter' outI2 = sitk.Multiply(imgSmooth, sitk.Cast(imgLeftHand, sitk.sitkFloat64)) elif processingSelector.currentText == "image segmentation + no holes": # step 1)filtering: noise reduction imgSmooth = sitk.CurvatureFlow(image1=outputImage, timeStep=0.125, numberOfIterations=5) # step 2) filtering: segmentation lstSeeds = [(247, 86)] labelLeftHand = 1 imgLeftHand = sitk.ConnectedThreshold(image1=imgSmooth, seedList=lstSeeds, lower=tempMin, upper=tempMax, replaceValue=labelLeftHand) # step 3) create image to display imgSmoothInt = sitk.Cast(sitk.RescaleIntensity(imgSmooth), imgLeftHand.GetPixelID()) # Use 'LabelOverlay' to overlay 'imgSmooth' and 'imgWhiteMatter' imgLeftHandNoHoles = sitk.VotingBinaryHoleFilling( image1=imgLeftHand, radius=[2] * 3, majorityThreshold=1, backgroundValue=0, foregroundValue=labelLeftHand) #outI2 = sitk.Multiply(imgSmooth, sitk.Cast(imgLeftHandNoHoles, sitk.sitkFloat64)) outI2 = imgLeftHandNoHoles elif processingSelector.currentText == "contouring": # step 1)filtering: noise reduction imgSmooth = sitk.CurvatureFlow(image1=outputImage, timeStep=0.125, numberOfIterations=5) # step 2) filtering: segmentation lstSeeds = [(247, 86)] labelLeftHand = 1 imgLeftHand = sitk.ConnectedThreshold(image1=imgSmooth, seedList=lstSeeds, lower=tempMin, upper=tempMax, replaceValue=labelLeftHand) # step 3) create image to display imgSmoothInt = sitk.Cast(sitk.RescaleIntensity(imgSmooth), imgLeftHand.GetPixelID()) # Use 'LabelOverlay' to overlay 'imgSmooth' and 'imgWhiteMatter' imgLeftHandNoHoles = sitk.VotingBinaryHoleFilling( image1=imgLeftHand, radius=[2] * 3, majorityThreshold=1, backgroundValue=0, foregroundValue=labelLeftHand) #imageContourning=sitk.Cast(sitk.LabelContour(imgLeftHandNoHoles), sitk.sitkUInt16) #outI2 = imageContourning*16383 imageContourning = (sitk.Cast( sitk.LabelContour(imgLeftHandNoHoles), sitk.sitkFloat64)) * 16383 # outI2 = sitk.LabelOverlay(imgSmoothInt, sitk.LabelContour(imgLeftHandNoHoles )) outI2 = sitk.LabelOverlay( imgSmoothInt, sitk.Cast(sitk.LabelContour(imgLeftHandNoHoles), imgLeftHand.GetPixelID())) #outI2 = sitk.Cast(outI, sitk.sitkFloat64) else: print("unknown processing") # step4) Push image to VTK volume # if not processedVolume: # print("output node should exist and be selected before processing is performed") volumesLogic = slicer.modules.volumes.logic() processedVolume = volumesLogic.CloneVolume( slicer.mrmlScene, workingSelector.currentNode(), 'processedVolume') workingSelector.setCurrentNode(processedVolume) # processedVolume= workingSelector.currentNode() outNode = sitkUtils.PushVolumeToSlicer( outI2, targetNode=workingSelector.currentNode(), name=None, className='vtkMRMLScalarVolumeNode') # step 4) display image in green Slice viwer lm = slicer.app.layoutManager() green = lm.sliceWidget('green') greenLogic = green.sliceLogic() greenLogic.GetSliceCompositeNode().SetBackgroundVolumeID( workingSelector.currentNode().GetID()) green.setSliceOrientation('Axial') view = green.sliceView() view.forceRender() # Set the orientation to axial greenLogic.GetSliceNode().UpdateMatrices() greenLogic.EndSliceNodeInteraction() return
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()
for i in range(10, 61): slicer.mrmlScene.Clear(0) seg_path, mri_path = sorted(list(images_dir.glob(f'*_{i}.nii.gz'))) print(seg_path) print(mri_path) volumeNode = loadVolume(str(mri_path)) print(volumeNode.GetName()) labelNode = loadLabelVolume(str(seg_path)) segNode = loadSegmentation(str(seg_path)) a = array(labelNode.GetName()) index = np.array(np.where(a)).mean(axis=1)[::-1] # numpy to itk labelImage = su.PullVolumeFromSlicer(labelNode.GetName()) l, p, s = labelImage.TransformContinuousIndexToPhysicalPoint(index) r, a = -l, -p jump(r, a, s) slicer.mrmlScene.RemoveNode(labelNode) screenshot_path = screenshots_dir / mri_path.name.replace('.nii.gz', '_label.png') logic.captureImageFromView(None, str(screenshot_path)) displayNode = segNode.GetDisplayNode() displayNode.SetVisibility(False) screenshot_path = screenshots_dir / mri_path.name.replace('.nii.gz', '_resected.png') slicer.app.processEvents() logic.captureImageFromView(None, str(screenshot_path)) print() logic.showViewControllers(True)
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 xrange(0,size[0],(int)(size[0]/10)): for y in xrange(0,size[1],(int)(size[1]/10)): for z in xrange(0,size[2],(int)(size[2]/10)): sitkimage.SetPixel(x,y,z,0L) 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)
######\\\\\ import os import dicom import numpy import pandas as pd from __main__ import vtk, qt, ctk, slicer import sitkUtils print("Cropped CT volumes") inputVolume = ./mydata_folder.dcm" croppedImage_fol = "./myCroppedVolume.dcm" [success, inputVolume] = slicer.util.loadVolume(inputVolume, returnNode=True) inputImage = sitkUtils.PullVolumeFromSlicer(inputVolume.GetID()) cropper = sitkUtils.sitk.CropImageFilter() croppingBounds = [[178, 210, 67],[227, 195, 34] #input the dimensions of the region. croppedImage = cropper.Execute(inputImage, croppingBounds[0], croppingBounds[1]) croppedNode = sitkUtils.PushVolumeToSlicer(croppedImage, None, inputVolume.GetName() , 'vtkMRMLScalarVolumeNode' ) properties = {} properties["fileType"] = ".dcm" slicer.util.saveNode(croppedNode, croppedImage_fol, properties) exit() ## Convert all the cropped data into numpy!
def doClassification(self, testVolumes, testLabel, resultLabel, doWithThickness): print("Doing classification...") import numpy as np modulePath = os.path.dirname(slicer.modules.ticce.path) # Loads scaler from resources if platform.system() is "Windows": separator = "\\" else: separator = "/" # First, concatenate information from all voxels from all images in a single matrix featureList = [] # Loads scaler from resources from joblib import load # import pickle joblibPath = modulePath + separator + "Resources" + separator + "classifier_joblibs" # picklePath = modulePath + separator + "Resources" + separator + "classifier_pickles" if doWithThickness: scaler = load(joblibPath + separator + 'scaler.joblib') clf = load(joblibPath + separator + 'classifier.joblib') # scaler = pickle.load(open(picklePath + separator + 'scaler.p', 'rb')) # clf = pickle.load(open(picklePath + separator + 'classifier.p', 'rb')) else: scaler = load(joblibPath + separator + 'scaler_no_thickness.joblib') clf = load(joblibPath + separator + 'classifier_no_thickness.joblib') # scaler = pickle.load(open(picklePath + separator + 'scaler_no_thickness.p', 'rb')) # clf = pickle.load(open(picklePath + separator + 'classifier_no_thickness.p', 'rb')) dim = testVolumes[0].GetImageData().GetDimensions() xs = range(0, dim[0]) ys = range(0, dim[1]) zs = range(0, dim[2]) import itertools coords = itertools.product(xs, ys, zs) print("Length of list: ") print(len(testVolumes)) # Set output image resultLabel.SetOrigin(testLabel.GetOrigin()) resultLabel.SetSpacing(testLabel.GetSpacing()) import sitkUtils tempSitk = sitkUtils.PullVolumeFromSlicer(testLabel) sitkUtils.PushVolumeToSlicer(tempSitk, resultLabel) # Iterates through all coordinates and, if there is a label in that coordinate, adds feature values and class to # respective arrays indexList = [] testList = [] for v in coords: if (testLabel is not None): if (testLabel.GetImageData().GetScalarComponentAsFloat( v[0], v[1], v[2], 0) == 0): continue # Only interrupts if there IS testLabel and its value equals 0 coordFeatures = [] for volume in testVolumes: value = volume.GetImageData().GetScalarComponentAsFloat( v[0], v[1], v[2], 0) if np.isnan(value): value = 0 elif value > 10000: value = 10000 elif value < -10000: value = -10000 coordFeatures.append(value) indexList.append([v[0], v[1], v[2]]) testList.append(coordFeatures) print("Creating test array") testArray = np.array(testList) print("Predicting for array") pred = clf.predict(scaler.transform(testArray)) print("Populating output label mask") for p, v in zip(pred, indexList): resultLabel.GetImageData().SetScalarComponentFromFloat( v[0], v[1], v[2], 0, p)
def image2points(self, inputImg): # to avoid loading system ITK libs startTime = time.time() print("====================================================") print("= Image to Points =") print("====================================================") # clone an image #print(inputImg.GetName()) nimg = sitkUtils.PullVolumeFromSlicer(inputImg.GetID()) sz = inputImg.GetImageData().GetDimensions() tmpImgArray = slicer.util.array(inputImg.GetID()) nimgMax = tmpImgArray.max() nimgMin = tmpImgArray.min() b = zip(*np.where(tmpImgArray > (nimgMax / 2))) NoPts = len(b) ptsIJK = np.zeros((NoPts, 4)) ptsIJKtmp = np.zeros((NoPts, 4)) print("Number of points imported: " + str(NoPts)) for j in range(0, NoPts): x = b[j][2] y = b[j][1] z = b[j][0] ptsIJK[j][0:3] = [x, y, z] ptsIJKtmp[j][0:3] = [x, y, z] ptsIJKtmp[j][3] = tmpImgArray[z][y][x] ptsIJKtmp = sorted(ptsIJKtmp, key=lambda t: t[-1]) for j in range(0, NoPts): ptsIJK[j][0:3] = ptsIJKtmp[j][0:3] print(" Convert the points from IJK to RAS ") print("---------------------------------------------------") # Convert to RAS ptsRAS = self.ptsIJK2RAS(ptsIJK, inputImg) print(" Create new points from the input image ") # create fiducial points if NoPts >= 0: mrk = slicer.modules.markups.logic() mrk.SetDefaultMarkupsDisplayNodeColor(9) mrk.SetDefaultMarkupsDisplayNodeGlyphScale(1.5) mrk.SetDefaultMarkupsDisplayNodeTextScale(0.20) self.markupsNode = slicer.mrmlScene.AddNewNodeByClass( "vtkMRMLMarkupsFiducialNode") self.markupsNode.CreateDefaultDisplayNodes() self.markupsNode.SetName("P") for j in range(0, NoPts): x = ptsRAS[j][0] y = ptsRAS[j][1] z = ptsRAS[j][2] #print(self.ptsRAS[j][0:3]) self.markupsNode.AddFiducial(x, y, z) #endfor #endif # get the file name at the first of the plugin self.markupsNode.SetName(self.inputFnm + "StPts") # Remove image points slicer.mrmlScene.RemoveNode(self.resImgPtsNode)
def main(argv): inputfile = '' outputfile = '' bitdepth = '' try: opts, args = getopt.getopt(argv, "b:hi:o:", ["bitdepth=", "ifile=", "ofile="]) except getopt.GetoptError: print 'nhdr_create.py -i <inputfile> -o <outputfile> [-bitdpeth <sitkbitdepths>]' print 'see https://itk.org/SimpleITKDoxygen/html/namespaceitk_1_1simple.html#ae40bd64640f4014fba1a8a872ab4df98 for the bitdepth info' sys.exit(2) for opt, arg in opts: if opt == '-h': print 'test.py -i <inputfile> -o <outputfile>' sys.exit() elif opt in ("-i", "--ifile"): inputfile = arg elif opt in ("-o", "--ofile"): outputfile = arg elif opt in ("-b", "--bitdepth"): bitdepth = arg print 'bitdepth found"' + bitdepth + '"' infolder, inname = ntpath.split(inputfile) d_pos = inname.index('.') inname = inname[:d_pos] outfolder, outname = ntpath.split(outputfile) d_pos = outname.index('.') outname = outname[:d_pos] print 'Input file is "' + inputfile + '"' print 'Node Name is "' + inname + '"' print 'Output file is "' + outputfile + '"' if bitdepth: print 'Changing bitdepth output to "' + bitdepth + '"' loadVolume(inputfile) scene = slicer.mrmlScene volumes = scene.GetNodesByName(inname) vol = volumes.GetItemAsObject(volumes.GetNumberOfItems() - 1) vol.SetName(inname + 'in') inname = inname + 'in' outname = outname + '_out' #vol = volumes.GetItemAsObject(0) # Able to fix image intensity using scale image to right scale, then cast to 16bit. #vOut = slicer.modules.volumes.logic().CloneVolumeWithoutImageData(scene,vol,outname) #inputImage = sitkUtils.PullFromSlicer('MRHead') #filter = sitk.SignedMaurerDistanceMapImageFilter() #outputImage = filter.Execute(inputImage) #sitkUtils.PushToSlicer(outputImage,'outputImage') #from SimpleFilters import SimpleFiltersLogic #filter = SimpleFiltersLogic() #myFilter = sitk.RescaleIntensityImageFilter() #myFilter.SetDebug(False) #myFilter.SetNumberOfThreads(8) #myFilter.SetOutputMinimum(0.0) #myFilter.SetOutputMaximum(65535.0) #filter.run(myFilter, vOut, False, slicer.util.getNode(inname)) #filter.main_queue_running #while filter.main_queue_running: # sleep(0.5) scene = slicer.mrmlScene if not bitdepth: print "Not changing bitdepth." print "Getting vol from scene for save" volumes = scene.GetNodesByName(inname) else: print "Setting IM Max by bitdepth" if bitdepth == "UInt64": im_max = 4294967296 elif bitdepth == "UInt32": im_max = 4294967296 elif bitdepth == "UInt16": im_max = 65535 elif bitdepth == "UInt8": im_max = 255 elif bitdepth == "Int64": im_max = 2147483647 elif bitdepth == "Int32": im_max = 2147483647 elif bitdepth == "Int16": im_max = 32767 elif bitdepth == "Int8": im_max = 128 elif bitdepth == "LabelUInt64": im_max = 4294967296 elif bitdepth == "LabelUInt32": im_max = 4294967296 elif bitdepth == "LabelUInt16": im_max = 65535 elif bitdepth == "LabelUInt8": im_max = 255 else: raise NameError('UnsupportedBitDepthSpecified') print "Setting up rescale filter" myFilter = sitk.RescaleIntensityImageFilter() myFilter.SetDebug(False) myFilter.SetNumberOfThreads(8) # deprecated #in_im=sitkUtils.PullFromSlicer(inname) in_im = sitkUtils.PullVolumeFromSlicer(inname) print "execute rescale" out_im = myFilter.Execute(in_im, 0.0, im_max) print "Setting up cast filter" myFilter = sitk.CastImageFilter() myFilter.SetDebug(False) myFilter.SetNumberOfThreads(8) #sitk.sitkUInt16 #eval('sitk.sitkUInt16') bt = 'sitk.sitk' + bitdepth print "Using bitdepth code " + bt + "(" + str(eval(bt)) + ")" myFilter.SetOutputPixelType(eval(bt)) print "execute cast" out_im = myFilter.Execute(out_im) sitkUtils.PushToSlicer(out_im, outname) print "Getting vol from scene for save" volumes = scene.GetNodesByName(outname) ##### # example code #histoMap = #slicer.modules.volumes.logic().CreateAndAddLabelVolume(self.histoVolumeBW, # 'Histo_Final_Label_Map') #from SimpleFilters import SimpleFiltersLogic #filter = SimpleFiltersLogic() # subtractimagefilter has params, input input out. #filter.run(sitk.SubtractImageFilter(), histoMap, True, # slicer.util.getNode('Histo_Label_Map'), # slicer.util.getNode('Histo_Urethra_Label_Map')) ##### vOut = volumes.GetItemAsObject(volumes.GetNumberOfItems() - 1) print "saving node " + outname saveNode(vOut, outputfile)
def registerAndExtractZ(self, inputNode, outputNode, featureName, regMNItoRefTransform, generateRegistration): print("Register and extract Z...") modulePath = os.path.dirname(slicer.modules.ticce.path) import sitkUtils if platform.system() is "Windows": separator = "\\" else: separator = "/" templatePath = modulePath + separator + "Resources" + separator + "feature_templates" (readSuccess, meanNode) = slicer.util.loadVolume( templatePath + separator + featureName + "_mean.nii.gz", {}, True) (readSuccess, stdNode) = slicer.util.loadVolume( templatePath + separator + featureName + "_std.nii.gz", {}, True) mniMeanRef = slicer.vtkMRMLScalarVolumeNode() slicer.mrmlScene.AddNode(mniMeanRef) mniStdRef = slicer.vtkMRMLScalarVolumeNode() slicer.mrmlScene.AddNode(mniStdRef) if generateRegistration: # Get 0-255 images to perform registration: inputNodeResc = slicer.vtkMRMLScalarVolumeNode() slicer.mrmlScene.AddNode(inputNodeResc) self.rescaleImage(inputNode, inputNodeResc, 0, 255) meanNodeResc = slicer.vtkMRMLScalarVolumeNode() slicer.mrmlScene.AddNode(meanNodeResc) self.rescaleImage(meanNode, meanNodeResc, 0, 255) self.doNonLinearRegistration(inputNodeResc, meanNodeResc, None, regMNItoRefTransform, 0.10, "3,3,3", "useCenterOfHeadAlign", -1) slicer.mrmlScene.RemoveNode(inputNodeResc) slicer.mrmlScene.RemoveNode(meanNodeResc) self.applyRegistrationTransform(meanNode, inputNode, mniMeanRef, regMNItoRefTransform, False, False) self.applyRegistrationTransform(stdNode, inputNode, mniStdRef, regMNItoRefTransform, False, False) # Subtract and divide mean images featureImg = sitkUtils.PullVolumeFromSlicer(inputNode) mniMeanRefImg = sitkUtils.PullVolumeFromSlicer(mniMeanRef) mniStdRefImg = sitkUtils.PullVolumeFromSlicer(mniStdRef) # Prepare image types if featureImg.GetPixelIDTypeAsString() != "32-bit float": featureImg = sitk.Cast(featureImg, sitk.sitkFloat32) if mniMeanRefImg.GetPixelIDTypeAsString() != "32-bit float": mniMeanRefImg = sitk.Cast(mniMeanRefImg, sitk.sitkFloat32) if mniStdRefImg.GetPixelIDTypeAsString() != "32-bit float": mniStdRefImg = sitk.Cast(mniStdRefImg, sitk.sitkFloat32) zFeatureImg = (featureImg - mniMeanRefImg) / mniStdRefImg sitkUtils.PushVolumeToSlicer(zFeatureImg, outputNode) slicer.mrmlScene.RemoveNode(mniMeanRef) slicer.mrmlScene.RemoveNode(mniStdRef) slicer.mrmlScene.RemoveNode(meanNode) slicer.mrmlScene.RemoveNode(stdNode)
def run(self, inputVolume, fiducialMarker, segVolumeTotalNode): """ 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() self.build_model() 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) segVolumeNode = sitkUtils.PushVolumeToSlicer( y_pred_sitk_full_size, name='segPrediction', className='vtkMRMLLabelMapVolumeNode') # sitkUtils.PushVolumeToSlicer(y_pred_sitk_full_size, targetNode=segVolumeNode) segVolumeTotalNode.append(segVolumeNode) slicer.util.setSliceViewerLayers(label=segVolumeNode, labelOpacity=1) return segVolumeTotalNode