Example #1
0
  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)
Example #2
0
    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
Example #3
0
    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
Example #4
0
    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')
Example #5
0
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
Example #6
0
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
Example #7
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)
Example #9
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(
            "-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)
Example #10
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)
Example #12
0
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)