def execute_extraction(extractor, scan_path, msk_path, day_name, voxelbased, verbose):
    if verbose:
        rad.setVerbosity(20)
    
    print('Extracting features...')
    t0 = time.time()
    
    if voxelbased:
        results = extractor.execute(scan_path, msk_path, voxelBased=True)
    else:
        results = extractor.execute(scan_path, msk_path)
        
    features_list = get_features_list(results, extractor)
    data = {'Day':day_name}
    for feat in features_list:
        data[feat] = results[feat]
        
    tf = time.time()
    print('Feature extraction completed')
    
    if (tf-t0) > 3600:
        print('\tElapsed Time: %f hours'%((tf-t0)/3600))
    elif (tf-t0) > 60:
        print('\tElapsed Time: %f min'%((tf-t0)/60))
    else:
        print('\tElapsed Time: %f sec'%(tf-t0))
    return data
def extract_features_from_image(imagePath, maskPath, paramsPath):
    """
    ACTION: 
        Extract radiomic features from one image, given mask and parameters, 
        and return a dictionary with the feature values
    INPUT: 
        imagePath: path to image nrrd-file (without extension)
        maskPath: path to mask nrrd-file (without extension)
        paramsPath: path to file with radiomic feature extraction settings
    OUTPUT: 
        dictionary with all extracted features
    """

    img = imagePath + ".nrrd"
    mask = maskPath + ".nrrd"

    if not os.path.isfile(img):
        raise IOError('File does not exist: %s' % img)
    elif not os.path.isfile(mask):
        raise IOError('File does not exist: %s' % mask)
    elif not os.path.isfile(paramsPath):
        raise IOError('File does not exist: %s' % paramsPath)

    extractor = featureextractor.RadiomicsFeatureExtractor(paramsPath)
    setVerbosity(
        40
    )  # Set level of verbosity, 40=Errors, 30=Warnings, 20=Info, 10=Debug
    results = extractor.execute(img, mask)
    return results
示例#3
0
def _configureLogging(args):
    global scriptlogger, logging_config

    # Initialize Logging
    logLevel = getattr(logging, args.logging_level)
    rLogger = radiomics.logger
    logging_config['logLevel'] = logLevel

    fmt = logging.Formatter(
        "[%(asctime)-.19s] %(levelname)-.1s: %(name)s: %(message)s")
    rLogger.handlers[0].setFormatter(fmt)

    # Set up optional logging to file
    if args.log_file is not None:
        logging_config['logFile'] = args.log_file
        logHandler = logging.FileHandler(filename=args.log_file, mode='a')
        logHandler.setFormatter(fmt)
        logHandler.setLevel(logLevel)
        rLogger.addHandler(logHandler)
        if rLogger.level > logHandler.level:
            rLogger.level = logHandler.level

    # Set verbosity of output (stderr)
    verboseLevel = (6 - args.verbosity) * 10  # convert to python logging level
    radiomics.setVerbosity(verboseLevel)
    logging_config['verbosity'] = verboseLevel

    scriptlogger.debug('Logging initialized')
示例#4
0
def main():
    args = parser.parse_args()

    # Initialize Logging
    logLevel = getattr(logging, args.logging_level)
    rLogger = radiomics.logger

    # Set up optional logging to file
    if args.log_file is not None:
        rLogger.setLevel(logLevel)
        handler = logging.StreamHandler(args.log_file)
        handler.setFormatter(
            logging.Formatter("%(levelname)s:%(name)s: %(message)s"))
        rLogger.addHandler(handler)

    # Set verbosity of output (stderr)
    verboseLevel = (6 - args.verbosity) * 10  # convert to python logging level
    radiomics.setVerbosity(verboseLevel)

    # Initialize logging for script log messages
    logger = rLogger.getChild('script')

    # Initialize extractor
    try:
        if args.param is not None:
            extractor = featureextractor.RadiomicsFeaturesExtractor(
                args.param[0])
        else:
            extractor = featureextractor.RadiomicsFeaturesExtractor()
        logger.info(
            'Extracting features with kwarg settings: %s\n\tImage: %s\n\tMask: %s',
            str(extractor.kwargs), os.path.abspath(args.image),
            os.path.abspath(args.mask))
        featureVector = collections.OrderedDict()
        featureVector['image'] = os.path.basename(args.image)
        featureVector['mask'] = os.path.basename(args.mask)

        featureVector.update(
            extractor.execute(args.image, args.mask, args.label))

        if args.format == 'csv':
            writer = csv.writer(args.out, lineterminator='\n')
            writer.writerow(list(featureVector.keys()))
            writer.writerow(list(featureVector.values()))
        elif args.format == 'json':
            json.dump(featureVector, args.out)
            args.out.write('\n')
        else:
            for k, v in six.iteritems(featureVector):
                args.out.write('%s: %s\n' % (k, v))
    except Exception:
        logger.error('FEATURE EXTRACTION FAILED:\n%s', traceback.format_exc())

    args.out.close()
    if args.log_file is not None:
        args.log_file.close()
示例#5
0
def _configurParallelExtraction(parallel_config):
    """
  Initialize logging for parallel extraction. This needs to be done here, as it needs to be done for each thread that is
  created.
  """
    # Configure logging
    ###################

    rLogger = logging.getLogger('radiomics')

    # Add logging to file is specified
    logFile = parallel_config.get('logFile', None)
    if logFile is not None:
        logHandler = logging.FileHandler(filename=logFile, mode='a')
        logHandler.setLevel(parallel_config.get('logLevel', logging.INFO))
        rLogger.addHandler(logHandler)

    # Include thread name in Log-message output for all handlers.
    parallelFormatter = logging.Formatter(
        '[%(asctime)-.19s] %(levelname)-.1s: (%(threadName)s) %(name)s: %(message)s'
    )
    for h in rLogger.handlers:
        h.setFormatter(parallelFormatter)

    if parallel_config.get('addFilter', True):
        # Define filter that allows messages from specified filter and level INFO and up, and level WARNING and up from
        # other loggers.
        class info_filter(logging.Filter):
            def __init__(self, name):
                super(info_filter, self).__init__(name)
                self.level = logging.WARNING

            def filter(self, record):
                if record.levelno >= self.level:
                    return True
                if record.name == self.name and record.levelno >= logging.INFO:
                    return True
                return False

        # Adding the filter to the first handler of the radiomics logger limits the info messages on the output to just
        # those from radiomics.script, but warnings and errors from the entire library are also printed to the output.
        # This does not affect the amount of logging stored in the log file.
        outputhandler = rLogger.handlers[0]  # Handler printing to the output
        outputhandler.addFilter(info_filter('radiomics.script'))

    # Ensures that log messages are being passed to the filter with the specified level
    setVerbosity(parallel_config.get('verbosity', logging.INFO))

    # Ensure the entire extraction for each cases is handled on 1 thread
    ####################################################################

    sitk.ProcessObject_SetGlobalDefaultNumberOfThreads(1)
示例#6
0
def tqdmProgressbar():
  """
  This function will setup the progress bar exposed by the 'tqdm' package.
  Progress reporting is only used in PyRadiomics for the calculation of GLCM and GLSZM in full python mode, therefore
  enable GLCM and full-python mode to show the progress bar functionality

  N.B. This function will only work if the 'click' package is installed (not included in the PyRadiomics requirements)
  """
  global extractor

  radiomics.setVerbosity(logging.INFO)  # Verbosity must be at least INFO to enable progress bar

  import tqdm
  radiomics.progressReporter = tqdm.tqdm
示例#7
0
    def onApplyButton(self):
        if self.debuggingCheckBox.checked:
            # Setup debug logging for the pyradiomics toolbox
            # PyRadiomics logs to stderr by default, which is picked up by slicer and added to the slicer log.
            radiomics.setVerbosity(logging.DEBUG)
        else:
            radiomics.setVerbosity(logging.WARNING)

        if not self.outputTableSelector.currentNode():
            tableNode = slicer.vtkMRMLTableNode()
            slicer.mrmlScene.AddNode(tableNode)
            self.outputTableSelector.setCurrentNode(tableNode)

        logic = SlicerRadiomicsLogic()
        featureClasses = self.getCheckedFeatureClasses()

        # Lock GUI
        self.applyButton.text = 'Working...'
        self.applyButton.setEnabled(False)
        slicer.app.processEvents()

        # Compute features
        kwargs = {}
        kwargs['binWidth'] = int(self.binWidthSliderWidget.value)
        kwargs['symmetricalGLCM'] = self.symmetricalGLCMCheckBox.checked
        # kwargs['label'] = int(self.labelSliderWidget.value)

        imageNode = self.inputVolumeSelector.currentNode()
        labelNode = self.inputMaskSelector.currentNode()
        segmentationNode = self.inputSegmentationSelector.currentNode()

        try:
            featuresDict = logic.run(imageNode, labelNode, segmentationNode,
                                     featureClasses, **kwargs)
            logic.exportToTable(featuresDict,
                                self.outputTableSelector.currentNode())
        except:
            self.logger.error("Feature calculation failed.")

        # Unlock GUI
        self.applyButton.setEnabled(True)
        self.applyButton.text = 'Apply'

        # Show results
        logic.showTable(self.outputTableSelector.currentNode())
示例#8
0
def run_main(subject_dirs, aseg_file, labels, results_csv):
    LUT = lut_parse()
    print(results_csv)
    with open(results_csv, 'w') as out_file:
        writer = csv.writer(out_file, delimiter=',')
        header = None
        for subjects_dir in subject_dirs:
            for subject_name in sorted(os.listdir(subjects_dir)):
                fname = '{}/{}/{}'.format(subjects_dir, subject_name,
                                          aseg_file)
                if not os.path.exists(fname):
                    print('{}: {} not found. Skipping'.format(
                        subject_name, aseg_file))
                    continue

                print(subject_name)
                fields = list()
                values = list()
                img = sitk.ReadImage(fname)
                for label in labels:
                    if ':' in label:
                        label, label_id = label.split(':')
                    else:
                        label_id = LUT[label]
                    radiomics.setVerbosity(50)
                    shape_features = radiomics.shape.RadiomicsShape(
                        img, img, **{'label': int(label_id)})
                    shape_features.enableAllFeatures()
                    results = shape_features.execute()
                    for key in results.keys():
                        fields.append('{}.{}'.format(label, key))
                        values.append(
                            float(results[key]
                                  ) if results['VoxelVolume'] > 0 else 'nan')

                if header is None:
                    header = fields
                    writer.writerow(['Subject'] + header)
                else:
                    assert header == fields

                writer.writerow([subject_name] + values)
def clickProgressbar():
    """
  This function will setup the progress bar exposed by the 'click' package.
  Progress reporting is only used in PyRadiomics for the calculation of GLCM and GLSZM in full python mode, therefore
  enable GLCM and full-python mode to show the progress bar functionality.

  Because the signature used to instantiate a click progress bar is different from what PyRadiomics expects, we need to
  write a simple wrapper class to enable use of a click progress bar. In this case we only need to change the 'desc'
  keyword argument to a 'label' keyword argument.

  N.B. This function will only work if the 'click' package is installed (not included in the PyRadiomics requirements)
  """
    global extractor

    extractor.kwargs['enableCExtensions'] = False
    # Enable the GLCM class to show the progress bar
    extractor.enableFeatureClassByName('glcm')

    radiomics.setVerbosity(
        logging.INFO)  # Verbosity must be at least INFO to enable progress bar

    import click

    class progressWrapper():
        def __init__(self, iterable, desc=''):
            # For a click progressbar, the description must be provided in the 'label' keyword argument.
            self.bar = click.progressbar(iterable, label=desc)

        def __iter__(self):
            return self.bar.__iter__(
            )  # Redirect to the __iter__ function of the click progressbar

        def __enter__(self):
            return self.bar.__enter__(
            )  # Redirect to the __enter__ function of the click progressbar

        def __exit__(self, exc_type, exc_value, tb):
            return self.bar.__exit__(
                exc_type, exc_value, tb
            )  # Redirect to the __exit__ function of the click progressbar

    radiomics.progressReporter = progressWrapper
示例#10
0
def main():
    args = parser.parse_args()

    # Initialize Logging
    logLevel = getattr(logging, args.logging_level)
    rLogger = radiomics.logger

    # Set up optional logging to file
    if args.log_file is not None:
        rLogger.setLevel(logLevel)
        handler = logging.StreamHandler(args.log_file)
        handler.setFormatter(
            logging.Formatter("%(levelname)s:%(name)s: %(message)s"))
        rLogger.addHandler(handler)

    # Set verbosity of output (stderr)
    verboseLevel = (6 - args.verbosity) * 10  # convert to python logging level
    radiomics.setVerbosity(verboseLevel)

    # Initialize logging for script log messages
    logger = rLogger.getChild('batch')

    # Load patient list
    flists = []
    try:
        cr = csv.reader(args.inFile, lineterminator='\n')
        flists = [row for row in cr]
        args.inFile.close()
    except Exception:
        logging.error('CSV READ FAILED:\n%s', traceback.format_exc())
        args.inFile.close()
        args.outFile.close()
        if args.log_file is not None:
            args.log_file.close()
        exit(-1)

    # Initialize extractor
    try:
        logger.debug("Initializing extractor")
        if args.param is not None:
            extractor = featureextractor.RadiomicsFeaturesExtractor(
                args.param[0])
        else:
            extractor = featureextractor.RadiomicsFeaturesExtractor()
    except Exception:
        logger.error('EXTRACTOR INITIALIZATION FAILED:\n%s',
                     traceback.format_exc())
        args.outFile.close()
        args.log_file.close()
        exit(-1)

    # Extract features
    logger.info('Extracting features with kwarg settings: %s',
                str(extractor.kwargs))

    headers = None
    for idx, entry in enumerate(flists, start=1):

        logger.info("(%d/%d) Processing Patient: %s, Study: %s, Reader: %s",
                    idx, len(flists), entry[0], entry[1], entry[2])

        imageFilepath = entry[3]
        maskFilepath = entry[4]

        if (imageFilepath is not None) and (maskFilepath is not None):
            featureVector = collections.OrderedDict()
            featureVector['PatientID'] = entry[0]
            featureVector['Study'] = entry[1]
            featureVector['Reader'] = entry[2]
            featureVector['image'] = os.path.basename(imageFilepath)
            featureVector['mask'] = os.path.basename(maskFilepath)

            try:
                featureVector.update(
                    extractor.execute(imageFilepath, maskFilepath, args.label))

                if args.format == 'csv':
                    writer = csv.writer(args.outFile, lineterminator='\n')
                    if headers is None:
                        headers = list(featureVector.keys())
                        writer.writerow(headers)

                    row = []
                    for h in headers:
                        row.append(featureVector.get(h, "N/A"))
                    writer.writerow(row)
                elif args.format == 'json':
                    json.dump(featureVector, args.out)
                    args.out.write('\n')
            except Exception:
                logger.error('FEATURE EXTRACTION FAILED:\n%s',
                             traceback.format_exc())

    args.outFile.close()
    if args.log_file is not None:
        args.log_file.close()
示例#11
0
CASES = six.moves.range(1, 6)
TYPES = ['', '_Combined']
IBSI_BINNING = False
IBSI_RESAMPLING = False
GRAY_VALUE_ROUNDING = True

#"""
rLogger = radiomics.logger
logHandler = logging.FileHandler(filename='results/IBSIlog.log', mode='w')
logHandler.setLevel(logging.DEBUG)
logHandler.setFormatter(logging.Formatter('%(levelname)-.1s: %(name)s: %(message)s'))

rLogger.setLevel(logging.DEBUG)
rLogger.addHandler(logHandler)

setVerbosity(logging.INFO)
# """

ibsiLogger = logging.getLogger('radiomics.ibsi')


def run_phantom():
  global TYPES
  ibsiLogger.info('################################### Extracting Phantom #############################')
  extractor = featureextractor.RadiomicsFeaturesExtractor()

  image = sitk.ReadImage(os.path.join('data', 'digital_phantom', 'Phantom.nrrd'))
  mask = sitk.ReadImage(os.path.join('data', 'digital_phantom', 'Phantom-label.nrrd'))

  result_series = pd.Series()
  extraction_mode = ('2D', '3D')
def main():
    ###给出基本路径
    params_path = r'E:\Radiomics\huaxi_jiang_yinjie\feature'
    base_outpath = r'E:\Radiomics\huaxi_jiang_yinjie\feature'
    base_dicom_nii_path = r'G:\West China Hospotal-Gastric Cancer SRCC\NRRD'
    series = 'pre' ##给定序列号 AP pre PVP

    outPath = os.path.join(base_outpath, series)
    dicom_nii_path = os.path.join(base_dicom_nii_path, series)###原始图片转换成nrrd文件

    ###给出输入输出文件路径
    inputCSV = os.path.join(outPath, 'presample_nii_path.csv')###文件中是分割文件的路径 'AP PVP pre'
    outputFilepath = os.path.join(outPath, 'radiomics_SRCC_pre_Primary.csv')  ###记得更改不同的特征名称 'AP PVP pre'

    progress_filename = os.path.join(outPath, 'pyrad_log.txt')
    # params = os.path.join(outPath, 'exampleSettings', 'Params.yaml')
    params = os.path.join(params_path, 'exampleCT.yaml')


    # Configure logging
    rLogger = logging.getLogger('radiomics')

    # Set logging level
    # rLogger.setLevel(logging.INFO)  # Not needed, default log level of logger is INFO

    # Create handler for writing to log file
    handler = logging.FileHandler(filename=progress_filename, mode='w')
    handler.setFormatter(logging.Formatter('%(levelname)s:%(name)s: %(message)s'))
    rLogger.addHandler(handler)

    # Initialize logging for batch log messages
    logger = rLogger.getChild('batch')

    # Set verbosity level for output to stderr (default level = WARNING)
    radiomics.setVerbosity(logging.INFO)

    logger.info('pyradiomics version: %s', radiomics.__version__)
    logger.info('Loading CSV')

    flists = []
    try:
      with open(inputCSV, 'r') as inFile:
        cr = csv.DictReader(inFile, lineterminator='\n')
        flists = [row for row in cr]
    except Exception:
      logger.error('CSV READ FAILED', exc_info=True)

    logger.info('Loading Done')
    logger.info('Patients: %d', len(flists))

    if os.path.isfile(params):
      extractor = featureextractor.RadiomicsFeatureExtractor(params)
    else:  # Parameter file not found, use hardcoded settings instead
      settings = {}
      settings['binWidth'] = 25
      settings['resampledPixelSpacing'] = None  # [3,3,3]
      settings['interpolator'] = sitk.sitkBSpline
      settings['enableCExtensions'] = True

      extractor = featureextractor.RadiomicsFeatureExtractor(**settings)
      # extractor.enableInputImages(wavelet= {'level': 2})

    logger.info('Enabled input images types: %s', extractor.enabledImagetypes)
    logger.info('Enabled features: %s', extractor.enabledFeatures)
    logger.info('Current settings: %s', extractor.settings)

    headers = None

    for idx, entry in enumerate(flists, start=1):
      newname = entry['name'] + '.nrrd'#####改名字
      # logger.info("(%d/%d) Processing Patient (Image: %s, Mask: %s)", idx, len(flists), entry['Image'], entry['Mask'])
      logger.info("(%d/%d) Processing Patient (Image: %s, Mask: %s)", idx, len(flists), os.path.join(dicom_nii_path, newname), entry['path'])###更改mask_path和primary名称

      # imageFilepath = entry['Image']
      # maskFilepath = entry['Mask']

      imageFilepath = os.path.join(dicom_nii_path, newname)
      # maskFilepath = entry['primary']###更改原发灶和淋巴结
      maskFilepath = entry['path']  ###更改原发灶和淋巴结
      label = entry.get('Label', None)

      if str(label).isdigit():
        label = int(label)
      else:
        label = None

      if (imageFilepath is not None) and (maskFilepath is not None):
        featureVector = collections.OrderedDict(entry)
        featureVector['Image'] = os.path.basename(imageFilepath)
        featureVector['Mask'] = os.path.basename(maskFilepath)

        try:
          featureVector.update(extractor.execute(imageFilepath, maskFilepath, label))

          with open(outputFilepath, 'a') as outputFile:
            writer = csv.writer(outputFile, lineterminator='\n')
            if headers is None:
              headers = list(featureVector.keys())
              writer.writerow(headers)

            row = []
            for h in headers:
              row.append(featureVector.get(h, "N/A"))
            writer.writerow(row)
        except Exception:
          logger.error('FEATURE EXTRACTION FAILED', exc_info=True)
示例#13
0
def main():
    outPath = r'E:\Git-Repos\PyRadiomicsNKI\pyradiomics-API'

    inputCSV = outPath + os.path.sep + "TestCases.csv"
    outputFilepath = outPath + os.path.sep + "radiomics_features.csv"
    progress_filename = outPath + os.path.sep + "pyrad_log.txt"

    # Configure logging
    rLogger = logging.getLogger('radiomics')

    # Set logging level
    # rLogger.setLevel(logging.INFO)  # Not needed, default log level of logger is INFO

    # Create handler for writing to log file
    handler = logging.FileHandler(filename=progress_filename, mode='w')
    handler.setFormatter(
        logging.Formatter("%(levelname)s:%(name)s: %(message)s"))
    rLogger.addHandler(handler)

    # Initialize logging for batch log messages
    logger = rLogger.getChild('batch')

    # Set verbosity level for output to stderr (default level = WARNING)
    radiomics.setVerbosity(logging.INFO)

    logger.info('Loading CSV')

    flists = []
    try:
        with open(inputCSV, 'r') as inFile:
            cr = csv.DictReader(inFile, lineterminator='\n')
            flists = [row for row in cr]
    except Exception:
        logging.error('CSV READ FAILED', exc_info=True)

    logger.info('Loading Done')
    logger.info('Patients: %d', len(flists))

    kwargs = {}
    kwargs['binWidth'] = 25
    kwargs['resampledPixelSpacing'] = None  # [3,3,3]
    kwargs['interpolator'] = sitk.sitkBSpline
    kwargs['enableCExtensions'] = False

    logger.info('pyradiomics version: %s', radiomics.__version__)
    logger.info('Extracting features with kwarg settings: %s', str(kwargs))

    extractor = featureextractor.RadiomicsFeaturesExtractor(**kwargs)
    extractor.enableInputImages(Original={})
    # extractor.enableInputImages(wavelet= {'level': 2})

    headers = None

    for idx, entry in enumerate(flists, start=1):

        logger.info("(%d/%d) Processing Patient (Image: %s, Mask: %s)", idx,
                    len(flists), entry['Image'], entry['Mask'])

        imageFilepath = entry['Image']
        maskFilepath = entry['Mask']

        if (imageFilepath is not None) and (maskFilepath is not None):
            featureVector = collections.OrderedDict(entry)
            featureVector['Image'] = os.path.basename(imageFilepath)
            featureVector['Mask'] = os.path.basename(maskFilepath)

            try:
                featureVector.update(
                    extractor.execute(imageFilepath, maskFilepath))

                with open(outputFilepath, 'a') as outputFile:
                    writer = csv.writer(outputFile, lineterminator='\n')
                    if headers is None:
                        headers = list(featureVector.keys())
                        writer.writerow(headers)

                    row = []
                    for h in headers:
                        row.append(featureVector.get(h, "N/A"))
                    writer.writerow(row)
            except Exception:
                logger.error('FEATURE EXTRACTION FAILED', exc_info=True)
def execute_extraction_pipeline(patient_name, day_name, organ, voxelbased=False, verbose=False):
	if verbose:
	    rad.setVerbosity(50)
def main():
  outPath = r''

  inputCSV = os.path.join(outPath, 'testCases.csv')
  outputFilepath = os.path.join(outPath, 'radiomics_features.csv')
  progress_filename = os.path.join(outPath, 'pyrad_log.txt')
  params = os.path.join(outPath, 'exampleSettings', 'Params.yaml')

  # Configure logging
  rLogger = logging.getLogger('radiomics')

  # Set logging level
  # rLogger.setLevel(logging.INFO)  # Not needed, default log level of logger is INFO

  # Create handler for writing to log file
  handler = logging.FileHandler(filename=progress_filename, mode='w')
  handler.setFormatter(logging.Formatter('%(levelname)s:%(name)s: %(message)s'))
  rLogger.addHandler(handler)

  # Initialize logging for batch log messages
  logger = rLogger.getChild('batch')

  # Set verbosity level for output to stderr (default level = WARNING)
  radiomics.setVerbosity(logging.INFO)

  logger.info('pyradiomics version: %s', radiomics.__version__)
  logger.info('Loading CSV')

  # ####### Up to this point, this script is equal to the 'regular' batchprocessing script ########

  try:
    # Use pandas to read and transpose ('.T') the input data
    # The transposition is needed so that each column represents one test case. This is easier for iteration over
    # the input cases
    flists = pandas.read_csv(inputCSV).T
  except Exception:
    logger.error('CSV READ FAILED', exc_info=True)
    exit(-1)

  logger.info('Loading Done')
  logger.info('Patients: %d', len(flists.columns))

  if os.path.isfile(params):
    extractor = featureextractor.RadiomicsFeatureExtractor(params)
  else:  # Parameter file not found, use hardcoded settings instead
    settings = {}
    settings['binWidth'] = 25
    settings['resampledPixelSpacing'] = None  # [3,3,3]
    settings['interpolator'] = sitk.sitkBSpline
    settings['enableCExtensions'] = True

    extractor = featureextractor.RadiomicsFeatureExtractor(**settings)
    # extractor.enableInputImages(wavelet= {'level': 2})

  logger.info('Enabled input images types: %s', extractor.enabledImagetypes)
  logger.info('Enabled features: %s', extractor.enabledFeatures)
  logger.info('Current settings: %s', extractor.settings)

  # Instantiate a pandas data frame to hold the results of all patients
  results = pandas.DataFrame()

  for entry in flists:  # Loop over all columns (i.e. the test cases)
    logger.info("(%d/%d) Processing Patient (Image: %s, Mask: %s)",
                entry + 1,
                len(flists),
                flists[entry]['Image'],
                flists[entry]['Mask'])

    imageFilepath = flists[entry]['Image']
    maskFilepath = flists[entry]['Mask']
    label = flists[entry].get('Label', None)

    if str(label).isdigit():
      label = int(label)
    else:
      label = None

    if (imageFilepath is not None) and (maskFilepath is not None):
      featureVector = flists[entry]  # This is a pandas Series
      featureVector['Image'] = os.path.basename(imageFilepath)
      featureVector['Mask'] = os.path.basename(maskFilepath)

      try:
        # PyRadiomics returns the result as an ordered dictionary, which can be easily converted to a pandas Series
        # The keys in the dictionary will be used as the index (labels for the rows), with the values of the features
        # as the values in the rows.
        result = pandas.Series(extractor.execute(imageFilepath, maskFilepath, label))
        featureVector = featureVector.append(result)
      except Exception:
        logger.error('FEATURE EXTRACTION FAILED:', exc_info=True)

      # To add the calculated features for this case to our data frame, the series must have a name (which will be the
      # name of the column.
      featureVector.name = entry
      # By specifying an 'outer' join, all calculated features are added to the data frame, including those not
      # calculated for previous cases. This also ensures we don't end up with an empty frame, as for the first patient
      # it is 'joined' with the empty data frame.
      results = results.join(featureVector, how='outer')  # If feature extraction failed, results will be all NaN

  logger.info('Extraction complete, writing CSV')
  # .T transposes the data frame, so that each line will represent one patient, with the extracted features as columns
  results.T.to_csv(outputFilepath, index=False, na_rep='NaN')
  logger.info('CSV writing complete')
示例#16
0
        features = {}

        for key, value in result.items():
            features[key] = value

        df = pd.DataFrame(result.items())
        df.to_csv(Output_path)


if __name__ == "__main__":
    descr = 'Extraction features from image with a given mask. Image path, mask path and output path must be in a list with 3 columns'
    parser = argparse.ArgumentParser(description=descr)
    parser.add_argument('path_list_path',
                        type=str,
                        help='the path of list of path')
    parser.add_argument(
        'bin_count',
        type=int,
        help='number if the bin of the istogram. Must be between 30 and 130')
    parser.add_argument('-v',
                        '--verbosity',
                        type=int,
                        choices=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
                        default=0,
                        help='increase verbosity of the output')
    args = parser.parse_args()

    radiomics.setVerbosity(args.verbosity)

    EstrattoreFeaturesADC(args.path_list_path, args.bin_count)
示例#17
0
def main():
    args = parser.parse_args()

    # Initialize Logging
    logLevel = getattr(logging, args.logging_level)
    rLogger = radiomics.logger

    # Set up optional logging to file
    if args.log_file is not None:
        rLogger.setLevel(logLevel)
        handler = logging.StreamHandler(args.log_file)
        handler.setFormatter(
            logging.Formatter("%(levelname)s:%(name)s: %(message)s"))
        rLogger.addHandler(handler)

    # Set verbosity of output (stderr)
    verboseLevel = (6 - args.verbosity) * 10  # convert to python logging level
    radiomics.setVerbosity(verboseLevel)

    # Initialize logging for script log messages
    logger = rLogger.getChild('batch')

    logger.warning(
        "This entry point is deprecated. It's enhanced functionality for batch extraction is now available "
        'in the "pyradiomics" entry point. See "http://pyradiomics.readthedocs.io/en/latest/usage.html" '
        'for more details.')

    # Load patient list
    flists = []
    try:
        cr = csv.DictReader(args.inFile, lineterminator='\n')
        flists = [row for row in cr]
        args.inFile.close()

        # Check if required Image and Mask columns are present
        if 'Image' not in cr.fieldnames:
            logger.error(
                'Required column "Image" not present in input, unable to extract features...'
            )
            exit(-1)
        if 'Mask' not in cr.fieldnames:
            logger.error(
                'Required column "Mask" not present in input, unable to extract features...'
            )
            exit(-1)
    except Exception:
        logging.error('CSV READ FAILED', exc_info=True)
        exit(-1)

    # Initialize extractor
    try:
        logger.debug("Initializing extractor")
        if args.param is not None:
            extractor = featureextractor.RadiomicsFeaturesExtractor(args.param)
        else:
            extractor = featureextractor.RadiomicsFeaturesExtractor()
    except Exception:
        logger.error('EXTRACTOR INITIALIZATION FAILED', exc_info=True)
        exit(-1)

    # Extract features
    logger.info('Extracting features with kwarg settings: %s',
                str(extractor.settings))

    headers = None
    for idx, entry in enumerate(flists, start=1):
        # Check if the required columns have a value, if not, skip them.
        if entry['Image'] == '':
            logger.error(
                'Missing value in column "Image", cannot process. Skipping patient (%d/%d)',
                idx, len(flists))
            continue
        if entry['Mask'] == '':
            logger.error(
                'Missing value in column "Mask", cannot process. Skipping patient (%d/%d)',
                idx, len(flists))
            continue

        logger.info("(%d/%d) Processing Patient (Image: %s, Mask: %s)", idx,
                    len(flists), entry['Image'], entry['Mask'])

        imageFilepath = entry['Image']
        maskFilepath = entry['Mask']

        if (imageFilepath is not None) and (maskFilepath is not None):
            if not os.path.isabs(imageFilepath):
                imageFilepath = os.path.abspath(
                    os.path.join(os.path.dirname(args.inFile.name),
                                 imageFilepath))
                logger.debug(
                    'Updated relative image filepath to be relative to input CSV: %s',
                    imageFilepath)
            if not os.path.isabs(maskFilepath):
                maskFilepath = os.path.abspath(
                    os.path.join(os.path.dirname(args.inFile.name),
                                 maskFilepath))
                logger.debug(
                    'Updated relative mask filepath to be relative to input CSV: %s',
                    maskFilepath)

            featureVector = collections.OrderedDict(entry)
            if args.shorten:
                featureVector['Image'] = os.path.basename(imageFilepath)
                featureVector['Mask'] = os.path.basename(maskFilepath)

            try:
                entryLabel = entry.get('Label', None)
                if str(entryLabel).isdigit():
                    label = int(entryLabel)
                else:
                    label = args.label

                featureVector.update(
                    extractor.execute(imageFilepath, maskFilepath, label))

                # if specified, skip NaN values
                if args.skip_nans:
                    for key in list(featureVector.keys()):
                        if isinstance(featureVector[key],
                                      float) and numpy.isnan(
                                          featureVector[key]):
                            logger.debug(
                                'Feature %s computed NaN, removing from results',
                                key)
                            del featureVector[key]

                if args.format == 'csv':
                    writer = csv.writer(args.outFile, lineterminator='\n')
                    if headers is None:
                        headers = list(featureVector.keys())
                        writer.writerow(headers)

                    row = []
                    for h in headers:
                        row.append(featureVector.get(h, ""))
                    writer.writerow(row)
                elif args.format == 'json':
                    json.dump(featureVector, args.out)
                    args.out.write('\n')
            except Exception:
                logger.error('FEATURE EXTRACTION FAILED', exc_info=True)

    args.outFile.close()
    if args.log_file is not None:
        args.log_file.close()
示例#18
0
import numpy as np
import pickle
import nrrd
import radiomics
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

from radiomics import featureextractor

from .globals import (SVM_MODEL_FILES, XGB_MODEL_FILES, IMPORTANT_FEATURES,
                      X_FEATURES, DISEASES)
radiomics.setVerbosity(40)

dataset = './data/datasets/radiomics_features.csv'


def load_models(model='svm'):

    models_arr = []

    model_files = None
    if model == 'svm':
        model_files = SVM_MODEL_FILES
    else:
        model_files = XGB_MODEL_FILES

    for i in range(len(model_files)):
        models_arr.append(pickle.load(open(model_files[i], 'rb')))

    return models_arr
示例#19
0
def main(argv=None):
    logger = logging.getLogger('radiomics.addTest')

    logger.setLevel(logging.INFO)
    radiomics.setVerbosity(logging.INFO)

    handler = logging.FileHandler(filename='testLog.txt', mode='w')
    formatter = logging.Formatter("%(levelname)s:%(name)s: %(message)s")
    handler.setFormatter(formatter)

    radiomics.logger.addHandler(handler)

    parser = argparse.ArgumentParser()
    parser.add_argument(
        'TestName',
        type=str,
        help=
        'Name for the new test, must not be already present in the baseline')
    parser.add_argument('TestCase',
                        type=str,
                        choices=list(radiomics.testCases),
                        help='Test image and segmentation to '
                        'use in the new test')
    parser.add_argument(
        'Configuration',
        metavar='FILE',
        default=None,
        help='Parameter file containing the settings to be used in extraction')
    parser.add_argument('--force',
                        '-f',
                        action='store_true',
                        help='When the test is already known for the class, '
                        'overwrite it in stead of just skipping that class')

    args = parser.parse_args(argv)

    logger.info('Input accepted, starting addTest...')

    try:

        testutils = RadiomicsTestUtils()

        try:
            assert args.TestCase in radiomics.testCases
        except AssertionError:
            logger.error('Input not valid, cancelling addTest!')
            exit(1)

        logger.debug('Initializing extractor')
        extractor = featureextractor.RadiomicsFeaturesExtractor(
            args.Configuration)

        logger.debug('Starting extraction')
        featurevector = extractor.execute(
            *radiomics.getTestCase(args.TestCase))

        configuration = {}
        baselines = {}

        for k, v in six.iteritems(featurevector):
            if 'diagnostics' in k:
                configuration[k] = v
            else:
                image_filter, feature_class, feature_name = k.split('_')
                if feature_class not in baselines:
                    baselines[feature_class] = {}
                baselines[feature_class][k] = v

        configuration['diagnostics_Configuration_TestCase'] = args.TestCase

        testutils.addTest(args.TestName, configuration, baselines)

        logger.info('addTest Done')

    except Exception:
        logger.error('Error running addTest!', exc_info=True)
示例#20
0
def main():
    args = parser.parse_args()

    # Initialize Logging
    logLevel = getattr(logging, args.logging_level)
    rLogger = radiomics.logger

    # Set up optional logging to file
    if args.log_file is not None:
        rLogger.setLevel(logLevel)
        handler = logging.StreamHandler(args.log_file)
        handler.setFormatter(
            logging.Formatter("%(levelname)s:%(name)s: %(message)s"))
        rLogger.addHandler(handler)

    # Set verbosity of output (stderr)
    verboseLevel = (6 - args.verbosity) * 10  # convert to python logging level
    radiomics.setVerbosity(verboseLevel)

    # Initialize logging for script log messages
    logger = rLogger.getChild('script')

    # Initialize extractor
    try:
        if args.param is not None:
            extractor = featureextractor.RadiomicsFeaturesExtractor(args.param)
        else:
            extractor = featureextractor.RadiomicsFeaturesExtractor()
        logger.info(
            'Extracting features with kwarg settings: %s\n\tImage: %s\n\tMask: %s',
            str(extractor.settings), os.path.abspath(args.image),
            os.path.abspath(args.mask))
        featureVector = collections.OrderedDict()
        if args.shorten:
            featureVector['Image'] = os.path.basename(args.image)
            featureVector['Mask'] = os.path.basename(args.mask)

        featureVector.update(
            extractor.execute(args.image, args.mask, args.label))

        # if specified, skip NaN values
        if args.skip_nans:
            for key in list(featureVector.keys()):
                if isinstance(featureVector[key], float) and numpy.isnan(
                        featureVector[key]):
                    logger.debug(
                        'Feature %s computed NaN, removing from results', key)
                    del featureVector[key]

        if args.format == 'csv':
            writer = csv.writer(args.out, lineterminator='\n')
            writer.writerow(list(featureVector.keys()))
            writer.writerow(list(featureVector.values()))
        elif args.format == 'json':
            json.dump(featureVector, args.out)
            args.out.write('\n')
        else:
            for k, v in six.iteritems(featureVector):
                args.out.write('%s: %s\n' % (k, v))
    except Exception:
        logger.error('FEATURE EXTRACTION FAILED', exc_info=True)

    args.out.close()
    if args.log_file is not None:
        args.log_file.close()
示例#21
0
def main(outPath=r'', patch=None, patchsize=30, allfilters=False):
    '''
    Func that runs PyRadiomics analysis. Creates a csv file with results.

    Accepts an input CSV (pyradExcel) which indicates image and mask.

    By default runs features on whole segmentation file (mhd in our case). If want to run PyRadiomics in patches
    (grid-mode):
    (1.pt) call patch='2D' or '3D', depending on the dimensions of your Region of Interest.
    (2) in input CSV, under Slices column, indicate first and last slice in this format - X, Y (otherwise leave empty)
    '''

    inputCSV = os.path.join(outPath, 'pyradExcel.csv')
    outputFilepath = os.path.join(outPath, 'radiomics_features.csv')
    progress_filename = os.path.join(outPath, 'pyrad_log.txt')
    # params = os.path.join(outPath, 'exampleSettings', 'Params.yaml') # default fr PyR. skipped later if not found

    # Configure logging
    rLogger = logging.getLogger('radiomics')

    # Set logging level
    rLogger.setLevel(logging.INFO)  # default log level of logger is INFO

    # Create handler for writing to log file
    handler = logging.FileHandler(filename=progress_filename, mode='w')
    handler.setFormatter(
        logging.Formatter('%(levelname)s:%(name)s: %(message)s'))
    rLogger.addHandler(handler)

    # Initialize logging for batch log messages
    logger = rLogger.getChild('batch')

    # Set verbosity level for output to stderr (default level = WARNING) (amount of messages displayed)
    radiomics.setVerbosity(logging.INFO)

    logger.info('pyradiomics version: %s', radiomics.__version__)
    logger.info('Loading CSV')

    try:
        with open(inputCSV, 'r') as inFile:
            reader = csv.DictReader(inFile, lineterminator='\n')
            index = [row for row in reader]
    except Exception:
        logger.error('CSV READ FAILED', exc_info=True)

    logger.info('Loading Done')
    logger.info('Patients: %d', len(index))

    # Set custom geometryTolerance. This is the only setting that will overun default settings.
    # There can be a tiny delta between image and mask space direction values (ElementSpacing/Size field in mhd/mha).
    # From primary tests they should be equal upto at least 4 decimal places, so I set to 10**-4.
    settings = {}
    settings['geometryTolerance'] = 10**-4

    count = 0

    for idx, entry in enumerate(index, start=1):

        logger.info("(%d/%d) Processing Patient (Image: %s, Mask: %s)", idx,
                    len(index), entry['Image'], entry['Mask'])

        imageFilepath = entry['Image']
        maskFilepath = entry['Mask']
        slices = entry['Slices'].split(', ')

        if (imageFilepath is not None) and (maskFilepath is not None):

            # Extract label from mask.
            # PyRadiomics calls on label 1.pt by default, but mhd has default 255 and Philips TISSUE mask file -1.pt.
            # From my understanding, in TISSUE mask file generated by Philips Portal there is only one label per mask
            sitkMask = sitk.ReadImage(maskFilepath)
            sitkarray = sitk.GetArrayFromImage(sitkMask)
            labels = numpy.unique(sitkarray)
            if 255 in labels:
                totalLabel = int(labels[1])
            elif -1 in labels:
                totalLabel = int(labels[0])

            # By default, only Original input image is enabled (No filter applied).
            extractor = featureextractor.RadiomicsFeatureExtractor(**settings)
            if allfilters:
                extractor.enableAllImageTypes()

            logger.info('Enabled input images types: %s',
                        extractor.enabledImagetypes)
            logger.info('Enabled features: %s', extractor.enabledFeatures)
            logger.info('Current settings: %s', extractor.settings)

            # Checks if want to run in patch mode or whole mask
            if patch is None:

                # If mask is 3D, get full mask for later feature extraction. If 2D, leave sitkMask unchanged
                if slices != ['']:
                    sitkMask = getFullMask(imageFilepath, maskFilepath, slices)

                featureVector = collections.OrderedDict(entry)
                featureVector['Image'] = os.path.basename(imageFilepath)
                featureVector['Mask'] = os.path.basename(maskFilepath)

                try:
                    featureVector.update(
                        extractor.execute(imageFilepath, sitkMask, totalLabel))
                    writeResults(featureVector, outputFilepath, count)
                    count += 1
                except Exception:
                    logger.error('FEATURE EXTRACTION FAILED', exc_info=True)
                    writeResults(featureVector, outputFilepath, count)
            elif patch == '3D' and slices != ['']:
                sitkMask = getFullMask(imageFilepath, maskFilepath, slices)
                sitkarray = sitk.GetArrayFromImage(sitkMask)
                patchedMask, dctLabel, dctABC = patch3Dmask(
                    sitkarray, totalLabel, patchsize=patchsize)
                newMask = sitk.GetImageFromArray(patchedMask)
                newMask.CopyInformation(sitkMask)
                for label in dctLabel:
                    featureVector = collections.OrderedDict(entry)
                    featureVector['Image'] = os.path.basename(imageFilepath)
                    featureVector['Mask'] = os.path.basename(maskFilepath)
                    featureVector['PatchNumber'] = label
                    featureVector['PatchName'] = dctABC[label]
                    featureVector['FractionLabelInPatch'] = dctLabel[label]
                    try:
                        featureVector.update(
                            extractor.execute(imageFilepath, newMask, label))
                        writeResults(featureVector, outputFilepath, count)
                        count += 1
                    except Exception:
                        logger.error('FEATURE EXTRACTION FAILED',
                                     exc_info=True)
                        writeResults(featureVector, outputFilepath, count)
            elif patch == '2D':
                patchedMask, dctLabel = patchMask(sitkarray,
                                                  totalLabel,
                                                  patchsize=patchsize)
                newMask = sitk.GetImageFromArray(patchedMask)
                newMask.CopyInformation(sitkMask)
                for label in dctLabel:
                    featureVector = collections.OrderedDict(entry)
                    featureVector['Image'] = os.path.basename(imageFilepath)
                    featureVector['Mask'] = os.path.basename(
                        maskFilepath) + '_' + str(label)
                    featureVector['PatchNumber'] = label
                    # featureVector['PatchName'] = label # sort out alphabetical name for 2D patching as well
                    featureVector['FractionLabelInPatch'] = dctLabel[label]
                    try:
                        featureVector.update(
                            extractor.execute(imageFilepath, newMask, label))
                        writeResults(featureVector, outputFilepath, count)
                        count += 1
                    except Exception:
                        logger.error('FEATURE EXTRACTION FAILED',
                                     exc_info=True)
                        writeResults(featureVector, outputFilepath, count)
示例#22
0
import six
import matplotlib.pyplot as plt
from radiomics import featureextractor, setVerbosity, getTestCase
resultPath = '/home/zzr/git/pyradiomics1111/result'

dataDir = '/home/zzr/git/pyradiomics1111'
imageName, maskName = getTestCase('brain1', dataDir)
# imageName = os.path.join('/media/zzr/My Passport/430/MRI/Preprocess_MRI/03534455_WANG YONG SHENG_MR', 'T2_img.nii.gz')
# maskName = os.path.join('/media/zzr/My Passport/430/MRI/Preprocess_MRI/03534455_WANG YONG SHENG_MR', 'T2_label.nii.gz')
params = os.path.join(dataDir, 'examples', 'exampleSettings', 'mine.yaml')
extractor = featureextractor.RadiomicsFeaturesExtractor(params)
extractor.addProvenance(provenance_on=False)
extractor.enableAllFeatures()
# extractor.enableFeatureClassByName('shape', False)
extractor.enableAllImageTypes()
setVerbosity(60)
# image, mask = extractor.loadImage(imageName, maskName)
# waveletImage = list(imageoperations.getWaveletImage(image, mask))
# print(len(waveletImage))
# img = sitk.GetArrayFromImage(waveletImage(0))
# for i in xrange(img.shape[0]):
#     plt.imshow(img[i, ...], cmap=plt.cm.gray)
#     plt.show()
# print(waveletImage)
# for x in waveletImage:
#     img = sitk.GetArrayFromImage(x[0])
#     print(img.shape)
#     for i in xrange(img.shape[0]):
#         plt.imshow(img[i, ...], cmap=plt.cm.gray)
#         plt.show()
#     break
# Configure logging
rLogger = logging.getLogger('radiomics')

# Set logging level
# rLogger.setLevel(logging.INFO)  # Not needed, default log level of logger is INFO

# Create handler for writing to log file
handler = logging.FileHandler(filename=progress_filename, mode='w')
handler.setFormatter(logging.Formatter('%(levelname)s:%(name)s: %(message)s'))
rLogger.addHandler(handler)

# Initialize logging for batch log messages
logger = rLogger.getChild('batch')

# Set verbosity level for output to stderr (default level = WARNING)
radiomics.setVerbosity(logging.INFO)

logger.info('pyradiomics version: %s', radiomics.__version__)
logger.info('Loading CSV')

flists = []
try:
    with open(inputCSV, 'r') as inFile:
        cr = csv.DictReader(inFile, lineterminator='\n')
        flists = [row for row in cr]
except Exception:
    logger.error('CSV READ FAILED', exc_info=True)

logger.info('Loading Done')
logger.info('Patients: %d', len(flists))
示例#24
0
import os
import multiprocessing
import threading
import queue
from pathlib import Path
import numpy as np
import pandas as pd
import cv2
import radiomics
radiomics.setVerbosity(60)  #Quiet
import SimpleITK as sitk
from scipy.spatial import distance
from scipy.signal import resample

augm_patLvDiv_train = Path('data/augm_patLvDiv_train/')
augm_patLvDiv_valid = Path('data/augm_patLvDiv_valid')
patLvDiv_test = Path('data/patLvDiv_test')


def readImage(path, color):
    if color == 'rgb':
        return cv2.cvtColor(cv2.imread(str(path)), cv2.COLOR_BGR2RGB)
    elif color == 'gray':
        return cv2.cvtColor(cv2.imread(str(path)), cv2.COLOR_BGR2GRAY)
    elif color == 'hsv':
        return cv2.cvtColor(cv2.imread(str(path)), cv2.COLOR_BGR2HSV)
    return None


def getPyRadImageAndMask(grayScaleImage, jointSeries=False):
    _, pyRadMask = cv2.threshold(grayScaleImage, 1, 1, cv2.THRESH_BINARY)
示例#25
0
    def onApplyButton(self):
        if self.verboseCheckBox.checked:
            # Setup debug logging for the pyradiomics toolbox
            # PyRadiomics logs to stderr by default, which is picked up by slicer and added to the slicer log.
            setVerbosity(logging.DEBUG)
        else:
            setVerbosity(logging.WARNING)

        if not self.outputTableSelector.currentNode():
            tableNode = slicer.vtkMRMLTableNode()
            slicer.mrmlScene.AddNode(tableNode)
            self.outputTableSelector.setCurrentNode(tableNode)

        logic = SlicerRadiomicsLogic()

        # Lock GUI
        self.applyButton.text = 'Working...'
        self.applyButton.setEnabled(False)
        slicer.app.processEvents()

        imageNode = self.inputVolumeSelector.currentNode()
        labelNode = self.inputMaskSelector.currentNode()
        segmentationNode = self.inputSegmentationSelector.currentNode()

        if self.manualCustomizationRadioButton.checked:
            # Set up customization
            featureClasses = self.getCheckedFeatureClasses()
            settings = {}
            settings['binWidth'] = self.binWidthSliderWidget.value
            settings['symmetricalGLCM'] = self.symmetricalGLCMCheckBox.checked

            enabledImageTypes = {'Original': {}}

            logKernelSizesValue = self.logKernelSizes.text
            if logKernelSizesValue:
                try:
                    enabledImageTypes['LoG'] = {
                        'sigma':
                        [float(i) for i in logKernelSizesValue.split(',')]
                    }
                except:
                    self.logger.error(
                        'Failed to parse LoG sigma value from string \"' +
                        logKernelSizesValue + '\"')
                    traceback.print_exc()
                    return

            resampledVoxelSizeValue = self.resampledVoxelSize.text
            if resampledVoxelSizeValue:
                try:
                    settings['resampledPixelSpacing'] = [
                        float(i) for i in resampledVoxelSizeValue.split(',')
                    ]
                except:
                    self.logger.error(
                        'Failed to parse resampled voxel spacing from string \"'
                        + resampledVoxelSizeValue + '\"')
                    settings['resampledPixelSpacing'] = None
                    traceback.print_exc()
                    return

            if self.waveletCheckBox.checked:
                enabledImageTypes['Wavelet'] = {}

            # Compute features
            try:
                featuresDict = logic.run(imageNode, labelNode,
                                         segmentationNode, featureClasses,
                                         settings, enabledImageTypes)
                logic.exportToTable(featuresDict,
                                    self.outputTableSelector.currentNode())
            except:
                self.logger.error("Feature calculation failed.")
                traceback.print_exc()

        else:
            # Compute Features
            try:
                parameterFile = self.parameterFilePathLineEdit.currentPath
                featuresDict = logic.runWithParameterFile(
                    imageNode, labelNode, segmentationNode, parameterFile)
                logic.exportToTable(featuresDict,
                                    self.outputTableSelector.currentNode())
            except:
                self.logger.error("Feature calculation failed.")
                traceback.print_exc()

        # Unlock GUI
        self.applyButton.setEnabled(True)
        self.applyButton.text = 'Apply'

        # Show results
        logic.showTable(self.outputTableSelector.currentNode())
示例#26
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Jun  5 17:07:02 2019

@author: leonardo
"""
import radiomics
import SimpleITK as sitk
import os

radiomics.setVerbosity(10)

dataDir = '/home/leonardo/pyradiomics/data'

Image_path = '/home/leonardo/Scrivania/paziente_prova/CSI+Boost/RTDOSE_2011-09-29_075800_TomoTherapy.Patient.Disease_TomoTherapy.Planned.Dose_n1__00000/1.2.826.0.1.3680043.2.200.426397767.89.47755.958.dcm'

Mask_path = '/home/leonardo/Scrivania/paziente_prova/RTst_nii'

#PER USARE PYRADIOMICS SERVONO IMMAGINI IN FORMATO COMPATIBILE CON SIMPLEITK. USARE sitk.ReadImage. IL PROBLEMA È CHE L'IMMAGINE CT È SPACCHETTATA IN TANTE IMMAGINI SI SINGOLE SLICE.
#CI SONO DELLE FUNZIONI DI SITK PER APRIRE I DICOM

#Carico immagine Mask

Maskstk = sitk.ReadImage(Mask_path + '/mask_Body.nii')

#Carico immagine DOSE

#Imagestk=sitk.ImageSeriesReader.GetGDCMSeriesFileNames(Image_path)
Imagestk = sitk.ReadImage(Image_path)
示例#27
0
def main():
  outPath = r''

  inputCSV = os.path.join(outPath, 'testCases.csv')
  outputFilepath = os.path.join(outPath, 'radiomics_features.csv')
  progress_filename = os.path.join(outPath, 'pyrad_log.txt')
  params = os.path.join(outPath, 'exampleSettings', 'Params.yaml')

  # Configure logging
  rLogger = logging.getLogger('radiomics')

  # Set logging level
  # rLogger.setLevel(logging.INFO)  # Not needed, default log level of logger is INFO

  # Create handler for writing to log file
  handler = logging.FileHandler(filename=progress_filename, mode='w')
  handler.setFormatter(logging.Formatter('%(levelname)s:%(name)s: %(message)s'))
  rLogger.addHandler(handler)

  # Initialize logging for batch log messages
  logger = rLogger.getChild('batch')

  # Set verbosity level for output to stderr (default level = WARNING)
  radiomics.setVerbosity(logging.INFO)

  logger.info('pyradiomics version: %s', radiomics.__version__)
  logger.info('Loading CSV')

  flists = []
  try:
    with open(inputCSV, 'r') as inFile:
      cr = csv.DictReader(inFile, lineterminator='\n')
      flists = [row for row in cr]
  except Exception:
    logger.error('CSV READ FAILED', exc_info=True)

  logger.info('Loading Done')
  logger.info('Patients: %d', len(flists))

  if os.path.isfile(params):
    extractor = featureextractor.RadiomicsFeatureExtractor(params)
  else:  # Parameter file not found, use hardcoded settings instead
    settings = {}
    settings['binWidth'] = 25
    settings['resampledPixelSpacing'] = None  # [3,3,3]
    settings['interpolator'] = sitk.sitkBSpline
    settings['enableCExtensions'] = True

    extractor = featureextractor.RadiomicsFeatureExtractor(**settings)
    # extractor.enableInputImages(wavelet= {'level': 2})

  logger.info('Enabled input images types: %s', extractor.enabledImagetypes)
  logger.info('Enabled features: %s', extractor.enabledFeatures)
  logger.info('Current settings: %s', extractor.settings)

  headers = None

  for idx, entry in enumerate(flists, start=1):

    logger.info("(%d/%d) Processing Patient (Image: %s, Mask: %s)", idx, len(flists), entry['Image'], entry['Mask'])

    imageFilepath = entry['Image']
    maskFilepath = entry['Mask']
    label = entry.get('Label', None)

    if str(label).isdigit():
      label = int(label)
    else:
      label = None

    if (imageFilepath is not None) and (maskFilepath is not None):
      featureVector = collections.OrderedDict(entry)
      featureVector['Image'] = os.path.basename(imageFilepath)
      featureVector['Mask'] = os.path.basename(maskFilepath)

      try:
        featureVector.update(extractor.execute(imageFilepath, maskFilepath, label))

        with open(outputFilepath, 'a') as outputFile:
          writer = csv.writer(outputFile, lineterminator='\n')
          if headers is None:
            headers = list(featureVector.keys())
            writer.writerow(headers)

          row = []
          for h in headers:
            row.append(featureVector.get(h, "N/A"))
          writer.writerow(row)
      except Exception:
        logger.error('FEATURE EXTRACTION FAILED', exc_info=True)
示例#28
0
def pyradiomics_batch(input_file_name, output_file_name):
    '''
    Extract features from a batch of images using radiomics.
    
    :param str input_file_name: Name of the excel-document that contains patient ID, path
                                the image and path to the mask of the image
    :param str output_file_name: Name of the excel-document that is going to 
                                 containing the extracted features
    '''

    #Finding the directory and setting up a logging file
    outPath = os.getcwd()
    inputXLSX = os.path.join(outPath, input_file_name)
    outputFilepath = os.path.join(outPath, output_file_name)
    progress_filename = os.path.join(outPath, 'pyrad_log.txt')
    rLogger = logging.getLogger('radiomics')
    handler = logging.FileHandler(filename=progress_filename, mode='w')
    handler.setFormatter(
        logging.Formatter('%(levelname)s:%(name)s: %(message)s'))
    rLogger.addHandler(handler)
    logger = rLogger.getChild('batch')
    radiomics.setVerbosity(logging.INFO)

    try:
        # Use pandas to read and transpose ('.T') the input data
        # The transposition is needed so that each column represents one test case. This is easier for iteration over the input cases
        flists = pandas.read_excel(inputXLSX).T
    except Exception:
        logger.error('Excel READ FAILED', exc_info=True)
        exit(-1)

    logger.info('Loading Done')
    logger.info('Patients: %d', len(flists.columns))

    #Change the settings
    settings = {}
    settings['binWidth'] = 2  #To get the right amount of bins
    settings['sigma'] = [1]
    extractor = featureextractor.RadiomicsFeaturesExtractor(**settings)
    extractor.enableAllImageTypes()

    logger.info('Enabled input images types: %s', extractor._enabledImagetypes)
    logger.info('Enabled features: %s', extractor._enabledFeatures)
    logger.info('Current settings: %s', extractor.settings)

    results = pandas.DataFrame()

    for entry in flists:  # Loop over all columns (i.e. the test cases)
        logger.info("(%d/%d) Processing Patient: %s", entry + 1,
                    len(flists.columns), flists[entry]['pasientID'])

        imageFilepath = flists[entry]['Image']
        maskFilepath = flists[entry]['Mask']
        label = flists[entry].get('Label', None)

        if str(label).isdigit():
            label = int(label)
        else:
            label = None

        if (imageFilepath is not None) and (maskFilepath is not None):
            featureVector = flists[entry]  # This is a pandas Series
            featureVector['Image'] = os.path.basename(imageFilepath)
            featureVector['Mask'] = os.path.basename(maskFilepath)

            try:
                # PyRadiomics returns the result as an ordered dictionary, which can be easily converted to a pandas Series
                # The keys in the dictionary will be used as the index (labels for the rows), with the values of the features
                # as the values in the rows.
                result = pandas.Series(
                    extractor.execute(imageFilepath, maskFilepath, label))
                featureVector = featureVector.append(result)
            except Exception:
                logger.error('FEATURE EXTRACTION FAILED:', exc_info=True)

        featureVector.name = entry
        # By specifying an 'outer' join, all calculated features are added to the data frame, including those not
        # calculated for previous cases. This also ensures we don't end up with an empty frame, as for the first patient
        # it is 'joined' with the empty data frame.
        results = results.join(featureVector, how='outer')

    logger.info('Extraction complete, writing Excel')
    # .T transposes the data frame, so that each line will represent one patient, with the extracted features as columns

    results.T.to_excel(outputFilepath, index=False, na_rep='NaN')
    logger.info('Excel writing complete')
示例#29
0
#FINALLY: give the value of the calculated h_final to the parameter file
_createParameterFile(h_final)

#Perform pyRadiomics feature extraction with such parameter
for (i, j) in zip(list_images, list_masks):

    case = i[0:4]
    imagePath = os.path.join(src, i)
    labelPath = os.path.join(src, j)

    image = sitk.ReadImage(imagePath)
    label = sitk.ReadImage(labelPath)

    #print(len(out_bin)) #number of bins
    radiomics.setVerbosity(level=10)

    extractor = radiomics.featureextractor.RadiomicsFeatureExtractor(paramPath)

    print("Enabled filters:\n\t", extractor.enabledImagetypes, "")
    print("Extraction parameters:\n\t", extractor.settings)
    print("Enabled features:\n\t", extractor.enabledFeatures)

    # Extract features
    print("Calculating features")
    featureVector = extractor.execute(image, label)

    d1 = featureVector
    d1.update({'Case': case})
    d1.move_to_end('Case', last=False)