def section_LoadDicomData(self): try: # Download and unzip test CT DICOM data import urllib downloads = ( ('http://slicer.kitware.com/midas3/download/item/137843/TestDicomCT.zip', self.dicomZipFilePath), ) downloaded = 0 for url,filePath in downloads: if not os.path.exists(filePath) or os.stat(filePath).st_size == 0: if downloaded == 0: self.delayDisplay('Downloading input data to folder\n' + self.dicomZipFilePath + '.\n\n It may take a few minutes...',self.delayMs) print('Requesting download from %s...' % (url)) urllib.urlretrieve(url, filePath) downloaded += 1 else: self.delayDisplay('Input data has been found in folder ' + self.dicomZipFilePath, self.delayMs) if downloaded > 0: self.delayDisplay('Downloading input data finished',self.delayMs) numOfFilesInDicomDataDir = len([name for name in os.listdir(self.dicomDataDir) if os.path.isfile(self.dicomDataDir + '/' + name)]) if (numOfFilesInDicomDataDir != self.expectedNumOfFilesInDicomDataDir): slicer.app.applicationLogic().Unzip(self.dicomZipFilePath, self.dicomDataDir) self.delayDisplay("Unzipping done",self.delayMs) numOfFilesInDicomDataDirTest = len([name for name in os.listdir(self.dicomDataDir) if os.path.isfile(self.dicomDataDir + '/' + name)]) self.assertEqual( numOfFilesInDicomDataDirTest, self.expectedNumOfFilesInDicomDataDir ) # Open test database and empty it with DICOMUtils.TemporaryDICOMDatabase(self.dicomDatabaseDir, True) as db: self.assertTrue( db.isOpen ) self.assertEqual( slicer.dicomDatabase, db) # Import test data in database indexer = ctk.ctkDICOMIndexer() self.assertIsNotNone( indexer ) indexer.addDirectory( slicer.dicomDatabase, self.dicomDataDir ) self.assertEqual( len(slicer.dicomDatabase.patients()), 1 ) self.assertIsNotNone( slicer.dicomDatabase.patients()[0] ) # Load test data numOfScalarVolumeNodesBeforeLoad = len( slicer.util.getNodes('vtkMRMLScalarVolumeNode*') ) self.assertEqual( len( slicer.util.getNodes('vtkMRMLSubjectHierarchyNode*') ), 1 ) patient = slicer.dicomDatabase.patients()[0] DICOMUtils.loadPatientByUID(patient) self.assertEqual( len( slicer.util.getNodes('vtkMRMLScalarVolumeNode*') ), numOfScalarVolumeNodesBeforeLoad + 1 ) self.assertEqual( len( slicer.util.getNodes('vtkMRMLSubjectHierarchyNode*') ), 1 ) except Exception, e: import traceback traceback.print_exc() self.delayDisplay('Test caused exception!\n' + str(e),self.delayMs*2)
def section_LoadDicomData(self): try: # Download and unzip test CT DICOM data import urllib downloads = ( ('http://slicer.kitware.com/midas3/download/item/137843/TestDicomCT.zip', self.dicomZipFilePath), ) downloaded = 0 for url,filePath in downloads: if not os.path.exists(filePath) or os.stat(filePath).st_size == 0: if downloaded == 0: self.delayDisplay('Downloading input data to folder\n' + self.dicomZipFilePath + '.\n\n It may take a few minutes...',self.delayMs) print('Requesting download from %s...' % (url)) urllib.urlretrieve(url, filePath) downloaded += 1 else: self.delayDisplay('Input data has been found in folder ' + self.dicomZipFilePath, self.delayMs) if downloaded > 0: self.delayDisplay('Downloading input data finished',self.delayMs) numOfFilesInDicomDataDir = len([name for name in os.listdir(self.dicomDataDir) if os.path.isfile(self.dicomDataDir + '/' + name)]) if (numOfFilesInDicomDataDir != self.expectedNumOfFilesInDicomDataDir): slicer.app.applicationLogic().Unzip(self.dicomZipFilePath, self.dicomDataDir) self.delayDisplay("Unzipping done",self.delayMs) numOfFilesInDicomDataDirTest = len([name for name in os.listdir(self.dicomDataDir) if os.path.isfile(self.dicomDataDir + '/' + name)]) self.assertEqual( numOfFilesInDicomDataDirTest, self.expectedNumOfFilesInDicomDataDir ) # Open test database and empty it with DICOMUtils.TemporaryDICOMDatabase(self.dicomDatabaseDir, True) as db: self.assertTrue( db.isOpen ) self.assertEqual( slicer.dicomDatabase, db) # Import test data in database indexer = ctk.ctkDICOMIndexer() self.assertIsNotNone( indexer ) indexer.addDirectory( slicer.dicomDatabase, self.dicomDataDir ) self.assertEqual( len(slicer.dicomDatabase.patients()), 1 ) self.assertIsNotNone( slicer.dicomDatabase.patients()[0] ) # Load test data numOfScalarVolumeNodesBeforeLoad = len( slicer.util.getNodes('vtkMRMLScalarVolumeNode*') ) numOfSubjectHierarchyNodesBeforeLoad = len( slicer.util.getNodes('vtkMRMLSubjectHierarchyNode*') ) patient = slicer.dicomDatabase.patients()[0] DICOMUtils.loadPatientByUID(patient) self.assertEqual( len( slicer.util.getNodes('vtkMRMLScalarVolumeNode*') ), numOfScalarVolumeNodesBeforeLoad + 1 ) self.assertEqual( len( slicer.util.getNodes('vtkMRMLSubjectHierarchyNode*') ), numOfSubjectHierarchyNodesBeforeLoad + 3 ) except Exception, e: import traceback traceback.print_exc() self.delayDisplay('Test caused exception!\n' + str(e),self.delayMs*2)
def LoadFirstPatientIntoSlicer(self): # Choose first non-empty patient from the patient list all_patients = slicer.dicomDatabase.patients() for patient in all_patients: try: DICOMUtils.loadPatientByUID(patient) return except OSError as e: # Failed to load patient, probably no studies are associated with it pass
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( "-p", "--patient", "--patients", dest="patients", default=[], required=False, nargs='+', help="Process particular patients in the 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( "--stop-on-error", dest="stop_on_error", default=False, required=False, action='store_true', help="Halt the script if processing a patient fails") parser.add_argument( "--do-not-exit", dest="do_not_exit", default=False, required=False, action='store_true', help="Don't exit Slicer after performing conversion(s)") args = parser.parse_args(argv) logging.info("Running with arguments:") logging.info(args) # Check required arguments if args.input_folder == "-": logging.error("Please specify input DICOM study folder!") sys.exit(-1) if args.output_folder == ".": logging.error( "Current directory is selected as output folder (default). To change it, please specify --output-folder" ) sys.exit(-1) if len(args.patients) > 0 and not args.exist_db: logging.error("Can only specify patients in an existing database") sys.exit(-1) # 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): 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("Save screen shots to directory " + output_dir) logic.SaveSegmentScreenShots(output_dir) logging.info("DONE saving to %s" % output_dir) def create_results_page(output_folder, converted_patients, skipped_patients, failed_patients): """Make an html page that summarizes the results with thumbnails for the screenshots""" fp = open(os.path.join(output_folder, "index.html"), "w") fp.write(''' <style> /* based on: https://www.w3schools.com/howto/howto_css_thumbnail.asp */ img { border: 1px solid #ddd; /* Gray border */ border-radius: 4px; /* Rounded border */ padding: 5px; /* Some padding */ width: 550px; /* Set a small width */ } /* Add a hover effect (blue shadow) */ img:hover { box-shadow: 0 0 2px 1px rgba(0, 140, 186, 0.5); } </style> <body> ''') fp.write("<p>converted: %s</p>" % converted_patients) fp.write("<p>skipped: %s</p>" % skipped_patients) fp.write("<p>failed: %s</p>" % failed_patients) for patient in converted_patients: fp.write(''' <a target="_blank" href="%s/GTV-1.png"> <img src="%s/GTV-1.png" alt="%s"> </a> <p>Patient: %s</p> ''' % ( patient, patient, patient, patient, )) fp.write("</body>") fp.close() if exist_db: logging.info("BatchStructureSet Running in Existing Database Mode") database_start_time = time.time() logic.LoadDatabase(input_folder) all_patients = slicer.dicomDatabase.patients() if len(args.patients) > 0: all_patients = args.patients logging.info("Must Process Patients %s" % len(all_patients)) converted_patients = [] skipped_patients = [] failed_patients = [] for patient in all_patients: patient_start_time = time.time() try: slicer.mrmlScene.Clear(0) # clear the scene if len(slicer.dicomDatabase.studiesForPatient( patient)) == 0: logging.warning( "Skipping patient with no studies: %s" % patient) skipped_patients.append(patient) continue 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) converted_patients.append(patient) except Exception, e: import traceback traceback.print_exc() logging.error("Failed to convert patient: %s", patient) failed_patients.append(patient) if args.stop_on_error: logging.warning( "Stopped processing after failure on patient %s" % patient) sys.exit(-1) logging.info("Finished patient %s in %d seconds" % (patient, time.time() - patient_start_time)) create_results_page(output_folder, converted_patients, skipped_patients, failed_patients) logging.info("\n------------") logging.info("Results") logging.info("------------\n") logging.info("Finished database in %d seconds" % (time.time() - database_start_time)) logging.info("Converted %d patients" % len(converted_patients)) logging.info("Skipped %d patients" % len(skipped_patients)) logging.error("Conversion failed on %d patients" % len(failed_patients)) logging.error("Failed patients:") logging.error(failed_patients) else:
def LoadFirstPatientIntoSlicer(self): # Choose first patient from the patient list patient = slicer.dicomDatabase.patients()[0] DICOMUtils.loadPatientByUID(patient)
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)
db = slicer.dicomDatabase print("indexing {}".format(args.input)) indexer.addDirectory(db, args.input) indexer.waitForImportFinished() slicer.util.selectModule('DICOM') fileLists = [] for patient in db.patients(): print("Patient:" + patient) for study in db.studiesForPatient(patient): print("Study:" + study) for series in db.seriesForStudy(study): print("Series:" + series) fileLists.append(db.filesForSeries(series)) for patientUID in db.patients(): loadedNodeIDs.extend(DICOMUtils.loadPatientByUID(patientUID)) nodes = slicer.util.getNodesByClass('vtkMRMLScalarVolumeNode') node = nodes[0] referenceVolumeNode.GetOrigin() niftiVolumeNody.SetIJKToRASDirectionMatrix(vtkmat) vtkmat = vtkMatrixFromArray(np.eye(4)) o = referenceVolumeNode.GetIJKToRASDirectionMatrix(vtkmat) import shutil shutil.rmtree("/tmp/SlicerDB") sys.exit()
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)
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)