def getImageFromDICOMInformation(self, dcmInfo): loadedNodeIDs = [] with DICOMUtils.TemporaryDICOMDatabase() as database: DICOMUtils.importDicom(os.path.join(self.path, 'DICOM'), database) series = SlicerDICOMDatabase().geSeriestMatchingDescriptionAndDateTime(dcmInfo['SeriesDescription'], dcmInfo['AcquisitionDateTime']) loadedNodeIDs.extend(DICOMUtils.loadSeriesByUID([series])) for nodeID in loadedNodeIDs[::-1]: volumeNode = slicer.util.getNode(nodeID) if re.search('.*' + dcmInfo['SeriesDescription'] + '.*', volumeNode.GetName()): return volumeNode raise RuntimeError('Unable to find image in DICOM: ' + self.path)
def loadTestData(self): #download data and add to dicom database zipFileUrl = 'http://slicer.kitware.com/midas3/download/item/257234/QIN-HEADNECK-01-0139-PET.zip' zipFilePath = self.tempDataDir + '/dicom.zip' zipFileData = self.tempDataDir + '/dicom' expectedNumOfFiles = 545 if not os.access(self.tempDataDir, os.F_OK): os.mkdir(self.tempDataDir) if not os.access(zipFileData, os.F_OK): os.mkdir(zipFileData) slicer.util.downloadAndExtractArchive(zipFileUrl, zipFilePath, zipFileData, expectedNumOfFiles) DICOMUtils.importDicom(zipFileData) # load dataset dicomFiles = slicer.util.getFilesInDirectory(zipFileData) loadablesByPlugin, loadEnabled = DICOMUtils.getLoadablesFromFileLists( [dicomFiles], ['DICOMScalarVolumePlugin']) loadedNodeIDs = DICOMUtils.loadLoadables(loadablesByPlugin) imageNode = slicer.mrmlScene.GetNodeByID(loadedNodeIDs[0]) imageNode.SetSpacing( 3.3940266832237, 3.3940266832237, 2.02490234375 ) # mimic spacing as produced by Slicer 4.10 for which the test was originally developed imageNode.SetOrigin( 285.367523193359375, 494.58682250976556816, -1873.3819580078125 ) # mimic origin as produced by Slicer 4.10 for which the test was originally developed # apply the SUVbw conversion factor and set units and quantity suvNormalizationFactor = 0.00040166400000000007 quantity = slicer.vtkCodedEntry() quantity.SetFromString( 'CodeValue:126400|CodingSchemeDesignator:DCM|CodeMeaning:Standardized Uptake Value' ) units = slicer.vtkCodedEntry() units.SetFromString( 'CodeValue:{SUVbw}g/ml|CodingSchemeDesignator:UCUM|CodeMeaning:Standardized Uptake Value body weight' ) multiplier = vtk.vtkImageMathematics() multiplier.SetOperationToMultiplyByK() multiplier.SetConstantK(suvNormalizationFactor) multiplier.SetInput1Data(imageNode.GetImageData()) multiplier.Update() imageNode.GetImageData().DeepCopy(multiplier.GetOutput()) imageNode.GetVolumeDisplayNode().SetWindowLevel(6, 3) imageNode.GetVolumeDisplayNode().SetAndObserveColorNodeID( 'vtkMRMLColorTableNodeInvertedGrey') imageNode.SetVoxelValueQuantity(quantity) imageNode.SetVoxelValueUnits(units) return imageNode
def loadTestData(self): self.patienName = 'UNIFORMITY^Bio-mCT' #download data and add to dicom database zipFileUrl = 'https://github.com/QIICR/SlicerPETPhantomAnalysis/releases/download/test-data/PETCylinderPhantom.zip' zipFilePath = self.tempDataDir + '/dicom.zip' zipFileData = self.tempDataDir + '/dicom' expectedNumOfFiles = 171 if not os.access(self.tempDataDir, os.F_OK): os.mkdir(self.tempDataDir) if not os.access(zipFileData, os.F_OK): # download DICOM test dataset os.mkdir(zipFileData) slicer.util.downloadAndExtractArchive(zipFileUrl, zipFilePath, zipFileData, expectedNumOfFiles) DICOMUtils.importDicom(zipFileData) # load dataset dicomFiles = slicer.util.getFilesInDirectory(zipFileData) loadablesByPlugin, loadEnabled = DICOMUtils.getLoadablesFromFileLists( [dicomFiles], ['DICOMScalarVolumePlugin']) loadedNodeIDs = DICOMUtils.loadLoadables(loadablesByPlugin) imageNode = slicer.mrmlScene.GetNodeByID(loadedNodeIDs[0]) # apply the SUVbw conversion factor and set units and quantity suvNormalizationFactor = 0.00012595161151 quantity = slicer.vtkCodedEntry() quantity.SetFromString( 'CodeValue:126400|CodingSchemeDesignator:DCM|CodeMeaning:Standardized Uptake Value' ) units = slicer.vtkCodedEntry() units.SetFromString( 'CodeValue:{SUVbw}g/ml|CodingSchemeDesignator:UCUM|CodeMeaning:Standardized Uptake Value body weight' ) multiplier = vtk.vtkImageMathematics() multiplier.SetOperationToMultiplyByK() multiplier.SetConstantK(suvNormalizationFactor) multiplier.SetInput1Data(imageNode.GetImageData()) multiplier.Update() imageNode.GetImageData().DeepCopy(multiplier.GetOutput()) imageNode.GetVolumeDisplayNode().SetWindowLevel(6, 3) imageNode.GetVolumeDisplayNode().SetAndObserveColorNodeID( 'vtkMRMLColorTableNodeInvertedGrey') imageNode.SetVoxelValueQuantity(quantity) imageNode.SetVoxelValueUnits(units) return imageNode
def load_DICOM(self): # create temporary database. Save original database path to restore # it when finished self.original_db_path = DICOMUtils.openTemporaryDatabase() #assert temporary database is open # import DICOM to database DICOMUtils.importDicom(self.locations_dict['DICOM'], slicer.dicomDatabase) # get patient name patient_name = slicer.dicomDatabase.nameForPatient( slicer.dicomDatabase.patients()[0]) # open DICOM by name DICOMUtils.loadPatientByName(patient_name) slicer.util.selectModule('SegmentationExtractionModule')
def import_T1_and_T2_data(input_folder, case_number): patient_dir1 = f"vs_gk_{case_number}_t1" patient_dir2 = f"vs_gk_{case_number}_t2" slicer.dicomDatabase.initializeDatabase() DICOMUtils.importDicom(os.path.join(input_folder, patient_dir1)) # import T1 folder files DICOMUtils.importDicom(os.path.join(input_folder, patient_dir2)) # import T2 folder files logging.info("Import DICOM data from " + os.path.join(input_folder, patient_dir1)) logging.info("Import DICOM data from " + os.path.join(input_folder, patient_dir2)) slicer.mrmlScene.Clear(0) # clear the scene logging.info(slicer.dicomDatabase.patients()) patient = slicer.dicomDatabase.patients()[0] # select the patient from the database (which has only one patient) # get all available series for the current patient studies = slicer.dicomDatabase.studiesForPatient(patient) series = [slicer.dicomDatabase.seriesForStudy(study) for study in studies] seriesUIDs = [uid for uidList in series for uid in uidList] # activate the selection window in the dicom widget dicomWidget = slicer.modules.dicom.widgetRepresentation().self() dicomWidget.browserWidget.onSeriesSelected(seriesUIDs) dicomWidget.browserWidget.examineForLoading() # get all available series that are loadable loadables = dicomWidget.browserWidget.loadableTable.loadables # loop over loadables and select for loading counter = 0 to_load = [] for key in loadables: name = loadables[key].name if "RTSTRUCT" in name or (("t1_" in name or "t2_" in name) and not " MR " in name): loadables[key].selected = True counter += 1 to_load.append(loadables[key].name) else: loadables[key].selected = False # check if exactly 4 loadables (2 images and 2 RT structures were selected) assert counter == 4, ( f"Not exactly 4, but {counter} files selected for loading of case {case_number}. \n" f"Selected files are {to_load}" ) # perform loading operation loadCheckedLoadables(dicomWidget.browserWidget) # # to load all loadables of the patient use instead: # DICOMUtils.loadPatientByUID(patient) # load selected patient into slicer ### finished dicom widged operations ### ### now in slicer data module ### # get RT structure nodes ns = getNodesByClass("vtkMRMLSegmentationNode") # gets the nodes that correspond to RT structures assert len(ns) == 2, f"Not exactly 2, but {len(ns)} node of class vtkMRMLSegmentationNode." RTSS1 = ns[0] # picks the first RT structure RTSS2 = ns[1] ref1 = RTSS1.GetNodeReference("referenceImageGeometryRef") ref2 = RTSS2.GetNodeReference("referenceImageGeometryRef") ref1_name = ref1.GetName() ref2_name = ref2.GetName() print(ref1_name) print(ref2_name) # make sure that 1-variables are always related to T1 image/segmentation if "t1_" in ref1_name and "t2_" in ref2_name: print("T1 first") elif "t2_" in ref1_name and "t1_" in ref2_name: print("T2 first") RTSS1, RTSS2 = RTSS2, RTSS1 ref1, ref2 = ref2, ref1 else: raise Error("Series names do not contain proper t1 or t2 identifiers.") return ref1, ref2, RTSS1, RTSS2
def main(argv): try: logging.info("Start batch RTSTRUCT conversion") # Parse command-line arguments parser = argparse.ArgumentParser( description="Batch Structure Set Conversion") parser.add_argument( "-i", "--input-folder", dest="input_folder", metavar="PATH", default="-", required=True, help= "Folder of input DICOM study (or database path to use existing)") parser.add_argument( "-r", "--ref-dicom-folder", dest="ref_dicom_folder", metavar="PATH", default="", required=False, help= "Folder containing reference anatomy DICOM image series, if stored outside the input study" ) parser.add_argument( "-u", "--use-ref-image", dest="use_ref_image", default=False, required=False, action='store_true', help= "Use anatomy image as reference when converting structure set to labelmap" ) parser.add_argument("-x", "--exist-db", dest="exist_db", default=False, required=False, action='store_true', help="Process an existing database") parser.add_argument("-m", "--export-images", dest="export_images", default=False, required=False, action='store_true', help="Export image data with labelmaps") parser.add_argument("-o", "--output-folder", dest="output_folder", metavar="PATH", default=".", help="Folder for output labelmaps") parser.add_argument("-s", "--export-surfaces", dest="export_surfaces", default=False, required=False, action='store_true', help="Export surface mesh representation") parser.add_argument( "-c", "--show-python-console", dest="show_python_console", default=False, required=False, action='store_true', help= "If this flag is specified then messages are displayed in an interactive Python console and the application does not quit when the script is finished." ) args = parser.parse_args(argv) if args.show_python_console: slicer.util.pythonShell().show() slicer.exit_when_finished = False # Check if SlicerRT is installed try: slicer.modules.dicomrtimportexport except AttributeError: logging.error("Please install SlicerRT extension") return 1 # Check required arguments if args.input_folder == "-": logging.warning('Please specify input DICOM study folder!') if args.output_folder == ".": logging.info( 'Current directory is selected as output folder (default). To change it, please specify --output-folder' ) # Convert to python path style input_folder = args.input_folder.replace('\\', '/') ref_dicom_folder = args.ref_dicom_folder.replace('\\', '/') output_folder = args.output_folder.replace('\\', '/') use_ref_image = args.use_ref_image exist_db = args.exist_db export_images = args.export_images export_surfaces = args.export_surfaces # Perform batch conversion logic = BatchStructureSetConversionLogic() def save_rtslices(output_dir, use_ref_image, ref_image_node_id=None): # package the saving code into a subfunction logging.info("Convert loaded structure set to labelmap volumes") labelmaps = logic.ConvertStructureSetToLabelmap( use_ref_image, ref_image_node_id) logging.info("Save labelmaps to directory " + output_dir) logic.SaveLabelmaps(labelmaps, output_dir) if export_surfaces: logic.SaveModels(output_dir) if export_images: logic.SaveImages(output_dir) logging.info("DONE") if exist_db: logging.info('BatchStructureSet running in existing database mode') DICOMUtils.openDatabase(input_folder) all_patients = slicer.dicomDatabase.patients() logging.info('Processing %d patients...' % len(all_patients)) for patient in all_patients: try: slicer.mrmlScene.Clear(0) # clear the scene DICOMUtils.loadPatientByUID(patient) output_dir = os.path.join(output_folder, patient) if not os.access(output_dir, os.F_OK): os.mkdir(output_dir) save_rtslices(output_dir, use_ref_image) except OSError as e: # Failed to load data from this patient, continue with the next one print(e) else: logging.info('BatchStructureSet running in file mode') ref_volume_file_path = None if os.path.isdir(ref_dicom_folder): # If reference DICOM folder is given and valid, then import reference patient and save its ID logging.info("Import reference anatomy DICOM data from " + ref_dicom_folder) DICOMUtils.openTemporaryDatabase() DICOMUtils.importDicom(ref_dicom_folder) # Save first volume to be used as reference logic.LoadFirstPatientIntoSlicer() scalarVolumeNodes = list( slicer.util.getNodes('vtkMRMLScalarVolume*').values()) if len(scalarVolumeNodes) > 0: refVolNode = scalarVolumeNodes[0] refVolStorageNode = refVolNode.CreateDefaultStorageNode() ref_volume_file_path = os.path.join( output_folder, 'refVolume.nrrd') refVolStorageNode.SetFileName(ref_volume_file_path) refVolStorageNode.WriteData(refVolNode) logging.info("Import DICOM data from " + input_folder) DICOMUtils.openTemporaryDatabase() DICOMUtils.importDicom(input_folder) all_patients = slicer.dicomDatabase.patients() logging.info('Processing %d patients...' % len(all_patients)) for patient in all_patients: try: slicer.mrmlScene.Clear(0) # clear the scene DICOMUtils.loadPatientByUID(patient) output_dir = os.path.join(output_folder, patient) if not os.access(output_dir, os.F_OK): os.mkdir(output_dir) ref_volume_node_id = None if ref_volume_file_path: try: refVolNode = slicer.util.loadVolume( ref_volume_file_path) ref_volume_node_id = refVolNode.GetID() except: pass save_rtslices(output_dir, use_ref_image, ref_volume_node_id) except OSError as e: # Failed to load data from this patient, continue with the next one print(e) except Exception as e: import traceback traceback.print_exc() print(e) return 1 return 0
def main(argv): try: # Parse command-line arguments parser = argparse.ArgumentParser(description="Batch Structure Set Conversion") parser.add_argument("-i", "--input-folder", dest="input_folder", metavar="PATH", default="-", required=True, help="Folder of input DICOM study (or database path to use existing)") parser.add_argument("-x", "--exist-db", dest="exist_db", default=False, required=False, action='store_true', help="Process an existing database") parser.add_argument("-m", "--export-images", dest="export_images", default=False, required=False, action='store_true', help="Export image data with labelmaps") parser.add_argument("-o", "--output-folder", dest="output_folder", metavar="PATH", default=".", help="Folder for output labelmaps") args = parser.parse_args(argv) # Check required arguments if args.input_folder == "-": logging.warning('Please specify input DICOM study folder!') if args.output_folder == ".": logging.info('Current directory is selected as output folder (default). To change it, please specify --output-folder') # Convert to python path style input_folder = args.input_folder.replace('\\', '/') output_folder = args.output_folder.replace('\\', '/') exist_db = args.exist_db export_images = args.export_images # Perform batch conversion logic = BatchStructureSetConversionLogic() def save_rtslices(output_dir): # package the saving code into a subfunction logging.info("Convert loaded structure set to labelmap volumes") labelmaps = logic.ConvertStructureSetToLabelmap() logging.info("Save labelmaps to directory " + output_dir) logic.SaveLabelmaps(labelmaps, output_dir) if export_images: logic.SaveImages(output_dir) logging.info("DONE") if exist_db: logging.info('BatchStructureSet running in existing database mode') DICOMUtils.openDatabase(input_folder) all_patients = slicer.dicomDatabase.patients() logging.info('Must Process Patients %s' % len(all_patients)) for patient in all_patients: slicer.mrmlScene.Clear(0) # clear the scene DICOMUtils.loadPatientByUID(patient) output_dir = os.path.join(output_folder,patient) if not os.access(output_dir, os.F_OK): os.mkdir(output_dir) save_rtslices(output_dir) else: logging.info("Import DICOM data from " + input_folder) DICOMUtils.openTemporaryDatabase() DICOMUtils.importDicom(input_folder) logging.info("Load first patient into Slicer") logic.LoadFirstPatientIntoSlicer() save_rtslices(output_folder) except Exception as e: print(e) sys.exit(0)
def ProceduralSegmentation(self, inputDir, outputDir): # Importing Dicom into temporary database dicomDataDir = inputDir from DICOMLib import DICOMUtils loadedNodeIDs = [] with DICOMUtils.TemporaryDICOMDatabase() as db: DICOMUtils.importDicom(dicomDataDir, db) patientUIDs = db.patients() for patientUID in patientUIDs: loadedNodeIDs.extend(DICOMUtils.loadPatientByUID(patientUID)) # Loading Dicom into scene seriesVolumeNode = slicer.util.getNode(loadedNodeIDs[0]) storageVolumeNode = seriesVolumeNode.CreateDefaultStorageNode() slicer.mrmlScene.AddNode(storageVolumeNode) storageVolumeNode.UnRegister(slicer.mrmlScene) seriesVolumeNode.SetAndObserveStorageNodeID(storageVolumeNode.GetID()) # Access segmentation module slicer.util.selectModule('Segment Editor') segmentationNode = slicer.mrmlScene.AddNewNodeByClass( "vtkMRMLSegmentationNode") slicer.mrmlScene.AddNode(segmentationNode) segmentationNode.CreateDefaultDisplayNodes() # only needed for display segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode( seriesVolumeNode) # TODO Automate creation of different segments in the future (using some form of -type argument) # Create spine segment segmentTypeID = "Spine" newSegment = slicer.vtkSegment() newSegment.SetName(segmentTypeID) newSegment.SetColor([0.89, 0.85, 0.78]) segmentationNode.GetSegmentation().AddSegment(newSegment, segmentTypeID) # Create segment editor widget to get access to effects segmentEditorWidget = slicer.qMRMLSegmentEditorWidget() segmentEditorWidget.setMRMLScene(slicer.mrmlScene) # Access segment editor node segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass( "vtkMRMLSegmentEditorNode") slicer.mrmlScene.AddNode(segmentEditorNode) segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode) segmentEditorWidget.setSegmentationNode(segmentationNode) segmentEditorWidget.setMasterVolumeNode(seriesVolumeNode) # Segment Editor Effect: Thresholding segmentEditorWidget.setActiveEffectByName("Threshold") effect = segmentEditorWidget.activeEffect() effect.setParameter("MinimumThreshold", "90") effect.setParameter("MaximumThreshold", "1600") effect.self().onApply() # Setting Closed Surface Representation Values segmentationNode.GetSegmentation().SetConversionParameter( "Oversampling factor", "1.0") segmentationNode.GetSegmentation().SetConversionParameter( "Joint smoothing", "0.50") segmentationNode.GetSegmentation().SetConversionParameter( "Smoothing factor", "0.50") # Segment Editor Effect: Smoothing segmentEditorWidget.setActiveEffectByName("Smoothing") effect = segmentEditorWidget.activeEffect() # 2mm MEDIAN Smoothing effect.setParameter("SmoothingMethod", "MEDIAN") effect.setParameter("KernelSizeMm", 2.5) effect.self().onApply() # 2mm OPEN Smoothing #effect.setParameter("SmoothingMethod", "MORPHOLOGICAL_OPENING") #effect.setParameter("KernelSizeMm", 2) #effect.self().onApply # 1.5mm CLOSED Smoothing #effect.setParameter("SmoothingMethod", "MORPHOLOGICAL_CLOSING") #effect.setParameter("KernelSizeMm", 1.5) #effect.self().onApply # Create Closed Surface Representation segmentationNode.CreateClosedSurfaceRepresentation() # Export Segmentation to Model Node shNode = slicer.mrmlScene.GetSubjectHierarchyNode() exportFolderItemId = shNode.CreateFolderItem(shNode.GetSceneItemID(), "Segments") slicer.modules.segmentations.logic().ExportAllSegmentsToModels( segmentationNode, exportFolderItemId) segmentID = segmentationNode.GetSegmentation().GetNthSegmentID(0) surfaceMesh = segmentationNode.GetClosedSurfaceInternalRepresentation( segmentID) # Decimate Model decimator = vtk.vtkDecimatePro() decimator.SplittingOff() decimator.PreserveTopologyOn() decimator.SetTargetReduction(0.95) decimator.SetInputData(surfaceMesh) decimator.Update() surfaceMesh = decimator.GetOutput() # Smooth the Model smoothingFactor = 0.5 smoother = vtk.vtkWindowedSincPolyDataFilter() smoother.SetInputData(surfaceMesh) smoother.SetNumberOfIterations(50) smoother.SetPassBand(pow(10.0, -4.0 * smoothingFactor)) smoother.BoundarySmoothingOff() smoother.FeatureEdgeSmoothingOff() smoother.NonManifoldSmoothingOn() smoother.NormalizeCoordinatesOn() smoother.Update() surfaceMesh = smoother.GetOutput() # Clean up Model cleaner = vtk.vtkCleanPolyData() #cleaner.PointMergingOff() #cleaner.ConvertLinesToPointsOn() #cleaner.ConvertPolysToLinesOn() #cleaner.ConvertStripsToPolysOn() cleaner.SetInputData(surfaceMesh) cleaner.Update() surfaceMesh = cleaner.GetOutput() # Write to OBJ File outputFileName = outputDir + "segmentation.obj" writer = vtk.vtkOBJWriter() writer.SetFileName(outputFileName) writer.SetInputData(surfaceMesh) writer.Update() # Clean up segmentEditorWidget = None slicer.mrmlScene.RemoveNode(segmentEditorNode)
def main(argv): try: # Parse command-line arguments parser = argparse.ArgumentParser( description="Batch Structure Set Conversion") parser.add_argument( "-i", "--input-folder", dest="input_folder", metavar="PATH", default="-", required=True, help= "Folder of input DICOM study (or database path to use existing)") parser.add_argument( "-r", "--ref-dicom-folder", dest="ref_dicom_folder", metavar="PATH", default="", required=False, help= "Folder containing reference anatomy DICOM image series, if stored outside the input study" ) parser.add_argument( "-u", "--use-ref-image", dest="use_ref_image", default=False, required=False, action='store_true', help= "Use anatomy image as reference when converting structure set to labelmap" ) parser.add_argument("-x", "--exist-db", dest="exist_db", default=False, required=False, action='store_true', help="Process an existing database") parser.add_argument("-m", "--export-images", dest="export_images", default=False, required=False, action='store_true', help="Export image data with labelmaps") parser.add_argument("-o", "--output-folder", dest="output_folder", metavar="PATH", default=".", help="Folder for output labelmaps") args = parser.parse_args(argv) # Check required arguments if args.input_folder == "-": logging.warning('Please specify input DICOM study folder!') if args.output_folder == ".": logging.info( 'Current directory is selected as output folder (default). To change it, please specify --output-folder' ) # Convert to python path style input_folder = args.input_folder.replace('\\', '/') ref_dicom_folder = args.ref_dicom_folder.replace('\\', '/') output_folder = args.output_folder.replace('\\', '/') use_ref_image = args.use_ref_image exist_db = args.exist_db export_images = args.export_images # Perform batch conversion logic = BatchStructureSetConversionLogic() def save_rtslices(output_dir, use_ref_image, ref_image_node_id=None): # package the saving code into a subfunction logging.info("Convert loaded structure set to labelmap volumes") labelmaps = logic.ConvertStructureSetToLabelmap( use_ref_image, ref_image_node_id) logging.info("Save labelmaps to directory " + output_dir) logic.SaveLabelmaps(labelmaps, output_dir) if export_images: logic.SaveImages(output_dir) logging.info("DONE") if exist_db: logging.info('BatchStructureSet running in existing database mode') DICOMUtils.openDatabase(input_folder) all_patients = slicer.dicomDatabase.patients() logging.info('Must Process Patients %s' % len(all_patients)) for patient in all_patients: slicer.mrmlScene.Clear(0) # clear the scene DICOMUtils.loadPatientByUID(patient) output_dir = os.path.join(output_folder, patient) if not os.access(output_dir, os.F_OK): os.mkdir(output_dir) save_rtslices(output_dir, use_ref_image) else: ref_image_node_id = None if os.path.isdir(ref_dicom_folder): # If reference DICOM folder is given and valid, then load that volume logging.info("Import reference anatomy DICOM data from " + ref_dicom_folder) DICOMUtils.openTemporaryDatabase() DICOMUtils.importDicom(ref_dicom_folder) logic.LoadFirstPatientIntoSlicer() # Remember first volume scalarVolumeNodes = list( slicer.util.getNodes('vtkMRMLScalarVolume*').values()) if len(scalarVolumeNodes) > 0: ref_image_node_id = scalarVolumeNodes[0].GetID() logging.info("Import DICOM data from " + input_folder) DICOMUtils.openTemporaryDatabase() DICOMUtils.importDicom(input_folder) logging.info("Load first patient into Slicer") logic.LoadFirstPatientIntoSlicer() save_rtslices(output_folder, use_ref_image, ref_image_node_id) except Exception as e: print(e) sys.exit(0)
import sys import os import DICOM import DICOMScalarVolumePlugin dicomDataDir = "/Users/JoshEhrlich/OneDrive - Queen's University/School/University/MSc/CISC881/Assignment1/DICOMFIleDownloadDirectory/PROSTATEx" # input folder with DICOM files loadedNodeIDs = [] # this list will contain the list of all loaded node IDs from DICOMLib import DICOMUtils with DICOMUtils.TemporaryDICOMDatabase() as db: DICOMUtils.importDicom(dicomDataDir, db) patientUIDs = db.patients() for patientUID in patientUIDs: print("Test") loadedNodeIDs.extend(DICOMUtils.loadPatientByUID(patientUID)) print("Test") DW = DICOM.DICOMWidget() DSVPC = DICOMScalarVolumePlugin.DICOMScalarVolumePluginClass() DW.detailsPopup.dicomApp.onImportDirectory(dicomDataDir) for patient in slicer.dicomDatabase.patients(): for study in slicer.dicomDatabase.studiesForPatient(patient): for series in slicer.dicomDatabase.seriesForStudy(study): files = slicer.dicomDatabase.filesForSeries(series) if slicer.dicomDatabase.descriptionForSeries(series) == ( "t2_tse_tra" ) or ("ADC" in slicer.dicomDatabase.descriptionForSeries(series) ) or ("BVAL" in slicer.dicomDatabase.descriptionForSeries(series)): volumeFile = DSVPC.load(DSVPC.examine([files])[0])
def main(argv): try: # Parse command-line arguments parser = argparse.ArgumentParser(description="Batch Structure Set Conversion") parser.add_argument("-i", "--input-folder", dest="input_folder", metavar="PATH", default="-", required=True, help="Folder of input DICOM study (or database path to use existing)") parser.add_argument("-x", "--exist-db", dest="exist_db", default=False, required=False, action='store_true', help="Process an existing database") parser.add_argument("-m", "--export-images", dest="export_images", default=False, required=False, action='store_true', help="Export image data with labelmaps") parser.add_argument("-o", "--output-folder", dest="output_folder", metavar="PATH", default=".", help="Folder for output labelmaps") args = parser.parse_args(argv) # Check required arguments if args.input_folder == "-": logging.warning('Please specify input DICOM study folder!') if args.output_folder == ".": logging.info('Current directory is selected as output folder (default). To change it, please specify --output-folder') # Convert to python path style input_folder = args.input_folder.replace('\\', '/') output_folder = args.output_folder.replace('\\', '/') exist_db = args.exist_db export_images = args.export_images # Perform batch conversion logic = BatchStructureSetConversionLogic() def save_rtslices(output_dir): # package the saving code into a subfunction logging.info("Convert loaded structure set to labelmap volumes") labelmaps = logic.ConvertStructureSetToLabelmap() logging.info("Save labelmaps to directory " + output_dir) logic.SaveLabelmaps(labelmaps, output_dir) if export_images: logic.SaveImages(output_dir) logging.info("DONE") if exist_db: logging.info('BatchStructureSet running in existing database mode') DICOMUtils.openDatabase(input_folder) all_patients = slicer.dicomDatabase.patients() logging.info('Must Process Patients %s' % len(all_patients)) for patient in all_patients: slicer.mrmlScene.Clear(0) # clear the scene DICOMUtils.loadPatientByUID(patient) output_dir = os.path.join(output_folder,patient) if not os.access(output_dir, os.F_OK): os.mkdir(output_dir) save_rtslices(output_dir) else: logging.info("Import DICOM data from " + input_folder) DICOMUtils.openTemporaryDatabase() DICOMUtils.importDicom(input_folder) logging.info("Load first patient into Slicer") logic.LoadFirstPatientIntoSlicer() save_rtslices(output_folder) except Exception, e: print(e)
parser.add_argument("--input", help="Input DICOM directory") parser.add_argument("--output", help="Where to write nrrd file") args = parser.parse_args() if args.dcmtk and args.gdcm: raise ValueError("Cannot specify both gdcm and dcmtk") if args.dcmtk: setDICOMReaderApproach('DCMTK') if args.gdcm: setDICOMReaderApproach('GDCM') from DICOMLib import DICOMUtils loadedNodeIDs = [] with DICOMUtils.TemporaryDICOMDatabase() as db: DICOMUtils.importDicom(args.input, db) patientUIDs = db.patients() for patientUID in patientUIDs: loadedNodeIDs.extend(DICOMUtils.loadPatientByUID(patientUID)) if len(loadedNodeIDs) > 1: print("Input dataset resulted in more than one scalar node! Aborting.") sys.exit(-1) elif len(loadedNodeIDs) == 0: print("No scalar volumes parsed from the input DICOM dataset! Aborting.") sys.exit(-2) else: print('Saving to ', args.output) node = slicer.util.getNode(loadedNodeIDs[0]) slicer.util.saveNode(node, args.output)