I have this file structure:
Main Folder:
W001-W100
.Subfolder:
W001
- Around 500 DICOM files (I am working with CT data).
Subfolder:
W002
- Around 500 DICOM files (I am working with CT data).
Subfolder:
...
Subfolder:
W100
- Around 500 DICOM files (I am working with CT data).
I am using Slicer software and Python to automate the process of getting surface meshes automatically.
This is the Python script I wrote that needs to be run in each subfolder.
As you can see, there are two lines with the location of the subfolder:
- Second line, specifying the location of the subfolder
- Almost the last line, indicating where to save the
.ply
file.
As I have around 1000 subfolders, I don't want to run the script changing those lines. In other words, I wan to automate the process.
I am much more familiar with R than with Python. So:
- could please indicate me how can I automate the process in detail by using Python?
- could you please edit the code to adapt to my needs?
- could you please show me a step-by-step process?
# Load DICOM filesdicomDataDir = "C:/Users/mario.modesto/Desktop/DICOM/W001" # input folder with DICOM filesimport os baboon_skull = os.path.basename(dicomDataDir)loadedNodeIDs = [] # this list will contain the list of all loaded node IDsfrom DICOMLib import DICOMUtilswith DICOMUtils.TemporaryDICOMDatabase() as db: DICOMUtils.importDicom(dicomDataDir, db) patientUIDs = db.patients() for patientUID in patientUIDs: loadedNodeIDs.extend(DICOMUtils.loadPatientByUID(patientUID))# Display volume renderinglogic = slicer.modules.volumerendering.logic()volumeNode = slicer.mrmlScene.GetNodeByID('vtkMRMLScalarVolumeNode1')displayNode = logic.CreateVolumeRenderingDisplayNode()displayNode.UnRegister(logic)slicer.mrmlScene.AddNode(displayNode)volumeNode.AddAndObserveDisplayNodeID(displayNode.GetID())logic.UpdateDisplayNodeFromVolumeNode(displayNode, volumeNode)# find the files NodeIDvolumeNode = getNode('2: Facial Bones 0.75 H70h')#create a blank Markup ROIroiNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsROINode")#set the new markup ROI to the dimensions of the volumecropVolumeParameters = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLCropVolumeParametersNode")cropVolumeParameters.SetInputVolumeNodeID(volumeNode.GetID())cropVolumeParameters.SetROINodeID(roiNode.GetID())slicer.modules.cropvolume.logic().SnapROIToVoxelGrid(cropVolumeParameters) # optional (rotates the ROI to match the volume axis directions)slicer.modules.cropvolume.logic().FitROIToInputVolume(cropVolumeParameters)slicer.mrmlScene.RemoveNode(cropVolumeParameters)#set the cropping parameterscropVolumeLogic = slicer.modules.cropvolume.logic()cropVolumeParameterNode = slicer.vtkMRMLCropVolumeParametersNode()cropVolumeParameterNode.SetIsotropicResampling(True)#set the output resolution to 2 millimeters. units in slicer is always in mm. cropVolumeParameterNode.SetSpacingScalingConst(2)cropVolumeParameterNode.SetROINodeID(roiNode.GetID())cropVolumeParameterNode.SetInputVolumeNodeID(volumeNode.GetID())#do the croppingcropVolumeLogic.Apply(cropVolumeParameterNode)#obtain the nodeID of the cropped volume croppedVolume = slicer.mrmlScene.GetNodeByID(cropVolumeParameterNode.GetOutputVolumeNodeID())# SegmentationsegmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")segmentationNode.CreateDefaultDisplayNodes() # only needed for displaysegmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(croppedVolume)addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment("skull")# Create segment editor to get access to effectssegmentEditorWidget = slicer.qMRMLSegmentEditorWidget()segmentEditorWidget.setMRMLScene(slicer.mrmlScene)segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)segmentEditorWidget.setSegmentationNode(segmentationNode)segmentEditorWidget.setMasterVolumeNode(croppedVolume)# ThresholdingsegmentEditorWidget.setActiveEffectByName("Threshold")effect = segmentEditorWidget.activeEffect()effect.setParameter("MinimumThreshold","115")effect.setParameter("MaximumThreshold","3071")effect.self().onApply()# Clean upsegmentEditorWidget = Noneslicer.mrmlScene.RemoveNode(segmentEditorNode)# Make segmentation results visible in 3DsegmentationNode.CreateClosedSurfaceRepresentation()# Creatint surface mesh and savingsurfaceMesh = segmentationNode.GetClosedSurfaceInternalRepresentation(addedSegmentID)writer = vtk.vtkPLYWriter()writer.SetInputData(surfaceMesh)writer.SetFileName("C:/Users/mario.modesto/Desktop/DICOM/"+baboon_skull+"_surfaceMesh.ply")writer.Update()
I would really appreciate your help.