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)
Example #3
0
 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
Example #4
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 #5
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:
Example #6
0
 def LoadFirstPatientIntoSlicer(self):
     # Choose first patient from the patient list
     patient = slicer.dicomDatabase.patients()[0]
     DICOMUtils.loadPatientByUID(patient)
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
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()
Example #10
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)
 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, e:
      print(e)