def generate_scenarios(): global logger, testCases, baselineFile assert os.path.isfile(baselineFile) baseline = numpy.load(baselineFile) wavelets = ('HHH', 'HHL', 'HLH', 'HLL', 'LHH', 'LHL', 'LLH', 'LLL') baselineDict = {wavelets[idx]: b for idx, b in enumerate(baseline)} for testCase in testCases: im_path, ma_path = getTestCase(testCase) assert im_path is not None assert ma_path is not None logger.debug('Loading image and mask for testCase %s', testCase) image = sitk.ReadImage(im_path) mask = sitk.ReadImage(ma_path) logger.debug('Checking image and mask for testCase %s', testCase) bb, correctedMask = imageoperations.checkMask(image, mask) assert bb is not None # Check mask should pass normally waveletGenerator = imageoperations.getWaveletImage(image, mask) for wavelet_image, wavelet_name, args in waveletGenerator: level = wavelet_name.split('-')[1] yield '_'.join((testCase, wavelet_name)), image, mask, baselineDict[level] logger.debug('Applying preCropping with padDistance 6 to testCase %s', testCase) image, mask = imageoperations.cropToTumorMask(image, mask, bb, padDistance=6) waveletGenerator = imageoperations.getWaveletImage(image, mask) for wavelet_image, wavelet_name, args in waveletGenerator: level = wavelet_name.split('-')[1] yield '_'.join((testCase, 'preCropped', wavelet_name)), image, mask, baselineDict[level]
def demo(): imageName, maskName = getTestCase('brain1') image = sitk.ReadImage(imageName) mask = sitk.ReadImage(maskName) settings = { 'binWidth': 25, 'interpolator': sitk.sitkBSpline, 'resampledPixelSpacing': None } # # If enabled, resample image (resampled image is automatically cropped. # interpolator = settings.get('interpolator') resampledPixelSpacing = settings.get('resampledPixelSpacing') if interpolator is not None and resampledPixelSpacing is not None: image, mask = imageoperations.resampleImage(image, mask, **settings) bb, correctedMask = imageoperations.checkMask(image, mask) if correctedMask is not None: mask = correctedMask image, mask = imageoperations.cropToTumorMask(image, mask, bb) ### firstOrderFeatures = firstorder.RadiomicsFirstOrder( image, mask, **settings) results = firstOrderFeatures.execute() print(results) ### shapeFeatures = shape.RadiomicsShape(image, mask, **settings) shapeFeatures.enableAllFeatures() results = shapeFeatures.execute() ### glcmFeatures = glcm.RadiomicsGLCM(image, mask, **settings) glcmFeatures.enableAllFeatures() results = glcmFeatures.execute() ### glrlmFeatures = glrlm.RadiomicsGLRLM(image, mask, **settings) glrlmFeatures.enableAllFeatures() results = glrlmFeatures.execute() ### glszmFeatures = glszm.RadiomicsGLSZM(image, mask, **settings) glszmFeatures.enableAllFeatures() results = glszmFeatures.execute()
def usage() -> NoReturn: imageName, maskName = getTestCase('brain1') image = sitk.ReadImage(imageName) mask = sitk.ReadImage(maskName) img_np = sitk.GetArrayFromImage(image) mask_np = sitk.GetArrayFromImage(mask) image1 = img_np[13, :, :][:, :, np.newaxis] image2 = img_np[14, :, :][:, :, np.newaxis] mask1 = mask_np[13, :, :][:, :, np.newaxis] mask2 = mask_np[14, :, :][:, :, np.newaxis] fea1 = calc_radio_fea(image1, mask1) fea2 = calc_radio_fea(image2, mask1) loss_list, var1_list, var2_list = compare_radio_feas(fea1, fea2) print("---------------------------------------") print(loss_list) print("---------------------------------------") print(var1_list) print("---------------------------------------") print(var2_list)
def generateWaveletBaseline(): logger = logging.getLogger('radiomics.addBaseline') baselineFile = '../data/baseline/wavelet.npy' testCase = 'test_wavelet_64x64x64' if os.path.isfile( baselineFile): # Check if the baseline does not yet exist logger.info('Baseline already exists, cancelling generation') return baselineDict = {} wavelets = ('HHH', 'HHL', 'HLH', 'HLL', 'LHH', 'LHL', 'LLH', 'LLL') im_path, ma_path = getTestCase(testCase) assert im_path is not None assert ma_path is not None logger.debug('Loading image and mask for testCase %s', testCase) image = sitk.ReadImage(im_path) mask = sitk.ReadImage(ma_path) logger.debug('Checking image and mask for testCase %s', testCase) bb, correctedMask = imageoperations.checkMask(image, mask) assert bb is not None # Check mask should pass normally waveletGenerator = imageoperations.getWaveletImage(image, mask) for wavelet_image, wavelet_name, args in waveletGenerator: level = wavelet_name.split('-')[1] im_arr = sitk.GetArrayFromImage(image) ma_arr = sitk.GetArrayFromImage( mask) == 1 # Convert to boolean array, label = 1 voxelArray = im_arr[ma_arr] # 1D array of all voxels inside mask baselineDict[level] = voxelArray baseline = [baselineDict[wl] for wl in wavelets] baseline = numpy.array(baseline) numpy.save(baselineFile, baseline)
from __future__ import print_function import logging import SimpleITK as sitk import radiomics from radiomics import featureextractor import os import collections from radiomics import generalinfo, getFeatureClasses, getImageTypes, getParameterValidationFiles, imageoperations if __name__ == "__main__": # Get some test data # Download the test case to temporary files and return it's location. If already downloaded, it is not downloaded again, # but it's location is still returned. print("Hello") imageName, maskName = radiomics.getTestCase('brain1') print(imageName, maskName) if imageName is None or maskName is None: # Something went wrong, in this case PyRadiomics will also log an error print('Error getting testcase!') exit() # # Regulate verbosity with radiomics.verbosity (default verbosity level = WARNING) # radiomics.setVerbosity(logging.INFO) # Get the PyRadiomics logger (default log-level = INFO) logger = radiomics.logger logger.setLevel( logging.DEBUG ) # set level to DEBUG to include debug log messages in log file # # # Set up the handler to write out all log entries to a file
# coding=utf-8 from __future__ import print_function import os import SimpleITK as sitk 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)
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 # Get some test data # repositoryRoot points to the root of the repository. The following line gets that location if this script is run # from it's default location in \pyradiomics\bin. Otherwise, it will point to some (invalid) folder, causing the # getTestCase function to fail to find the test case in the repository. In that case, a test case will be downloaded to # temporary files and it's location is returned. repositoryRoot = os.path.abspath(os.path.join(os.getcwd(), "..")) imageName, maskName = radiomics.getTestCase('brain1', repositoryRoot) # Get the location of the example settings file paramsFile = os.path.abspath(r'exampleSettings\Params.yaml') if imageName is None or maskName is None: # Something went wrong, in this case PyRadiomics will also log an error print('Error getting testcase!') exit() # Regulate verbosity with radiomics.verbosity # radiomics.setVerbosity(logging.INFO) # Get the PyRadiomics logger (default log-level = INFO logger = radiomics.logger logger.setLevel(logging.DEBUG) # set level to DEBUG to include debug log messages in log file
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 # Get some test data testCase = 'lung2' # repositoryRoot points to the root of the repository. The following line gets that location if this script is run # from it's default location in \pyradiomics\bin. Otherwise, it will point to some (invalid) folder, causing the # getTestCase function to fail to find the test case in the repository. In that case, a test case will be downloaded to # temporary files and it's location is returned. repositoryRoot = os.path.abspath(os.path.join(os.getcwd(), "..")) imageName, maskName = radiomics.getTestCase(testCase, repositoryRoot) # Get the location of the example settings file paramsFile = os.path.abspath(r'exampleSettings\exampleVoxel.yaml') if imageName is None or maskName is None: # Something went wrong, in this case PyRadiomics will also log an error print('Error getting testcase!') exit() # Regulate verbosity with radiomics.verbosity # radiomics.setVerbosity(logging.INFO) # Get the PyRadiomics logger (default log-level = INFO logger = radiomics.logger logger.setLevel( logging.DEBUG
def setFeatureClassAndTestCase(self, className, test): """ Set testing suite to specified testCase and feature class. Throws an assertion error if either class or test case are not recognized. These have to be set here together, as the settings with which the test case has to be loaded are defined per feature class in the baseline (extracted from provenance information). Only (re)loads an image/mask if the test case has changed, or the change of feature class causes a change in test settings. If feature class and test case are unchanged, nothing is reloaded and function returns False. If either feature class or test case is changed, function returns True. """ global TEST_CASES if self._featureClassName == className and self._test == test: return False self._test = test self._testedSet.add(self._test) # First set featureClass if necessary, because if settings have changed, testCase needs te be reloaded if self._featureClassName != className: self._logger.debug('Setting feature class name to %s', className) assert className in self._baseline.keys( ) # Check if a baseline has been read for this class self._featureClassName = className # Check if test settings have changed if self._current_config != self._baseline[className].getTestConfig( test): self._current_config = self._baseline[className].getTestConfig( test) self._testCase = None # forces image to be reloaded (as settings have changed) # Next, set testCase if necessary if self._testCase != self._current_config['TestCase']: self._testCase = self._current_config['TestCase'] self._logger.info("Reading the image and mask for test case %s", self._testCase) assert self._current_config['TestCase'] in TEST_CASES imageName, maskName = getTestCase(self._testCase) assert imageName is not None assert maskName is not None self._image = sitk.ReadImage(imageName) self._mask = sitk.ReadImage(maskName) if 'ImageHash' in self._current_config: assert sitk.Hash( self._image) == self._current_config['ImageHash'] if 'MaskHash' in self._current_config: assert sitk.Hash( self._mask) == self._current_config['MaskHash'] settings = self._current_config.get('Settings', {}) interpolator = settings.get('interpolator', sitk.sitkBSpline) resampledPixelSpacing = settings.get('resampledPixelSpacing', None) if interpolator is not None and resampledPixelSpacing is not None: self._image, self._mask = imageoperations.resampleImage( self._image, self._mask, resampledPixelSpacing, interpolator, settings.get('label', 1), settings.get('padDistance', 5)) self._bb, correctedMask = imageoperations.checkMask( self._image, self._mask, **settings) if correctedMask is not None: self._mask = correctedMask self._imageType = None return True
def main(): global TEST_CASES dataDir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "data") baselineDir = os.path.join(dataDir, "baseline") kwargs = { 'binWidth': 25, 'interpolator': None, 'resampledPixelSpacing': None, 'padDistance': 5, 'voxelArrayShift': 2000, 'weightingNorm': None, 'gldm_a': 0 } extractor = featureextractor.RadiomicsFeaturesExtractor(**kwargs) newClasses = [ cls for cls in extractor.getFeatureClassNames() if not os.path.exists(os.path.join(baselineDir, 'baseline_%s.csv' % (cls))) ] if len(newClasses) == 0: print("No new classes to add, exiting...") exit(0) print("Adding new classes: ", newClasses) newBaseline = {} extractor.disableAllFeatures() extractor.disableAllImageTypes() # Calculate new baseline on original image for all new classes extractor.enableImageTypeByName('Original') for cls in newClasses: newBaseline[cls] = {} print("Computing new baseline") for testCase in TEST_CASES: print("\tCalculating test case", testCase) imagePath, maskPath = getTestCase(testCase) image, mask = extractor.loadImage(imagePath, maskPath) if image is None or mask is None: print("Error during loading of image/mask, testcase:", testCase) continue # testImage or mask not found / error during loading for cls in newClasses: print("\t\tCalculating class", cls) extractor.disableAllFeatures() extractor.enableFeatureClassByName(cls) newBaseline[cls][testCase] = collections.OrderedDict() newBaseline[cls][testCase]['general_info_TestCase'] = testCase newBaseline[cls][testCase].update(extractor.execute(image, mask)) print("Writing new baseline") for cls in newClasses: baselineFile = os.path.join(baselineDir, 'baseline_%s.csv' % (cls)) with open(baselineFile, 'wb') as baseline: csvWriter = csv.writer(baseline) header = ['featureName'] + list(TEST_CASES) csvWriter.writerow(header) features = newBaseline[cls][TEST_CASES[0]].keys() for f in features: row = [f] for testCase in TEST_CASES: row.append(newBaseline[cls][testCase].get(f, '')) csvWriter.writerow(row) baseline.close()
import SimpleITK as sitk import six from radiomics import firstorder, getTestCase, glcm, glrlm, glszm, imageoperations, shape # testBinWidth = 25 this is the default bin size # testResampledPixelSpacing = [3,3,3] no resampling for now. # Get some test data # repositoryRoot points to the root of the repository. The following line gets that location if this script is run # from it's default location in \pyradiomics\bin. Otherwise, it will point to some (invalid) folder, causing the # getTestCase function to fail to find the test case in the repository. In that case, a test case will be downloaded to # temporary files and it's location is returned. repositoryRoot = os.path.abspath(os.path.join(os.getcwd(), "..")) imageName, maskName = getTestCase('brain1', repositoryRoot) if imageName is None or maskName is None: # Something went wrong, in this case PyRadiomics will also log an error print('Error getting testcase!') exit() image = sitk.ReadImage(imageName) mask = sitk.ReadImage(maskName) applyLog = False applyWavelet = False # Setting for the feature calculation. # Currently, resampling is disabled. # Can be enabled by setting 'resampledPixelSpacing' to a list of 3 floats (new voxel size in mm for x, y and z) kwargs = {'binWidth': 25,
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)
from __future__ import print_function import numpy import SimpleITK as sitk import six from radiomics import firstorder, getTestCase, glcm, glrlm, glszm, imageoperations, shape # testBinWidth = 25 this is the default bin size # testResampledPixelSpacing = [3,3,3] no resampling for now. # Get some test data # Download the test case to temporary files and return it's location. If already downloaded, it is not downloaded again, # but it's location is still returned. imageName, maskName = getTestCase('brain1') if imageName is None or maskName is None: # Something went wrong, in this case PyRadiomics will also log an error print('Error getting testcase!') exit() image = sitk.ReadImage(imageName) mask = sitk.ReadImage(maskName) applyLog = False applyWavelet = False # Setting for the feature calculation. # Currently, resampling is disabled. # Can be enabled by setting 'resampledPixelSpacing' to a list of 3 floats (new voxel size in mm for x, y and z) settings = {