PyRadiomics

repository·master·Indexed 22 days ago

https://github.com/aim-harvard/pyradiomics

An open-source Python package for the reproducible extraction of radiomic features from 2D and 3D medical imaging. It supports segment-based and voxel-based extraction, providing various feature classes (such as GLCM, GLRLM, and Shape-based) and filter classes (including Wavelet and LoG). The library can be used via a Python API, a command-line interface, or a 3D Slicer extension, and is available as Docker images for CLI and Jupyter notebook environments.

Tokens
20.5K
Snippets
34
Records
101
Agent score
81%

What's inside pyradiomics

  1. Overview of PyRadiomics feature classes

    master

    PyRadiomics extracts various radiomic features categorized into several classes. Most feature classes (except for Shape features) can be calculated on either the original image or a derived image obtained via filters.

    Feature Classes:

    • First Order Statistics (radiomics.firstorder): 19 features.
    • Shape-based (3D) (radiomics.shape): 16 features. These are extracted from the label mask and are independent of gray value.
    • Shape-based (2D) (radiomics.shape2D): 10 features.
    • Gray Level Co-occurrence Matrix (GLCM) (radiomics.glcm): 24 features.
    • Gray Level Run Length Matrix (GLRLM) (radiomics.glrlm): 16 features.
    • Gray Level Size Zone Matrix (GLSZM) (radiomics.glszm): 16 features.
    • Neighbouring Gray Tone Difference Matrix (NGTDM) (radiomics.ngtdm): 5 features.
    • Gray Level Dependence Matrix (GLDM) (radiomics.gldm): 14 features.

    Most features comply with the Imaging Biomarker Standardization Initiative (IBSI) definitions.

  2. Overview of PyRadiomics usage modes

    master

    PyRadiomics can be used in three primary ways:

    1. Python API: Use the featureextractor module directly within your Python scripts.
    2. Command Line Interface (CLI): Use the pyradiomics command for single image extraction or batch processing.
    3. 3D Slicer Extension: Use the 'Radiomics' extension within the 3D Slicer software for a GUI-based interface.
  3. Configure gray value discretization (Fixed Bin Width vs. Fixed Bin Count)

    master

    PyRadiomics supports two methods for gray value discretization:

    1. binWidth (Default): Sets a fixed bin width. This is the recommended default, especially for PET imaging, as it provides better reproducibility across different intensity ranges.
    2. binCount: Sets a fixed number of bins.

    Using a fixed bin width is generally preferred for images with absolute gray values (like HU in CT or SUV in PET) to ensure that the 'meaning' of a discretized gray value remains consistent across different images.

  4. Perform Voxel-based Radiomics Extraction

    master

    Voxel-based extraction calculates feature maps for every voxel rather than a single float value per feature. This process is more computationally intensive.

    Command Line

    Add the --mode voxel argument. The resulting feature maps are stored as NRRD images in the current working directory (or a directory specified by --out-dir) using the naming convention Case-<idx>_<FeatureName>.nrrd. The console/output file will contain diagnostic information, and the feature value will point to the location of the stored map.

    pyradiomics <path/to/image> <path/to/segmentation> --mode voxel --out-dir ./maps

    Interactive Use (Python API)

    Pass voxelBased=True to the execute() method. The returned dictionary will contain SimpleITK.Image objects for the feature maps.

  5. How PyRadiomics compares to IBSI definitions

    master

    PyRadiomics generally adheres to IBSI (Image Biomarker Standardization Initiative) definitions, but there are notable differences in specific implementations that may cause variations in results:

    • Binning (Fixed Bin Width): IBSI computes bin edges based on the resegmentation range or minimum intensities. PyRadiomics always uses bin edges equally spaced from 0, ensuring the lowest gray level is in the first bin.
    • Resampling Alignment: IBSI aligns the resampling grid by the image center; PyRadiomics aligns it by the corner of the origin voxel. This can lead to differences in interpolated results and image/ROI sizes.
    • Gray Value Rounding: PyRadiomics does not implement the IBSI practice of rounding resampled values to the nearest integer (to match original precision), as it considers the complexity-to-benefit ratio low.
    • Mask Resampling: PyRadiomics forces mask resampling to use nearest neighbor interpolation to prevent incorrect re-assignment of label values.
    • Kurtosis: IBSI calculates Excess Kurtosis (Kurtosis - 3). PyRadiomics calculates standard Kurtosis (which is +3 compared to IBSI).
  6. Understand excluded GLCM features in PyRadiomics

    master

    Some Gray Level Co-occurrence Matrix (GLCM) features have been removed from PyRadiomics because they are mathematically identical to other supported features. If your workflow requires these specific metrics, use the equivalent supported feature instead:

    • Sum Variance: Use radiomics.glcm.RadiomicsGLCM.getClusterTendencyFeatureValue() (Cluster Tendency).
    • Dissimilarity: Use radiomics.glcm.RadiomicsGLCM.getDifferenceAverageFeatureValue() (Difference Average).
  7. Understand excluded GLDM features in PyRadiomics

    master

    Certain Gray Level Dependence Matrix (GLDM) features are excluded because they either always result in a constant value or are mathematically equivalent to First Order features:

    • Dependence percentage: Removed because PyRadiomics allows for incomplete dependence zones, meaning all voxels have a dependence zone ($N_z = N_p$), resulting in a constant value of 1.
    • Gray Level Non-Uniformity Normalized (GLNN): Removed because it is mathematically identical to First Order Uniformity. Use radiomics.firstorder.RadiomicsFirstOrder.getUniformityFeatureValue() instead.
  8. Understand the 4 types of PyRadiomics customization

    master

    PyRadiomics allows customization at four distinct levels:

    1. Image Types: Choosing which image types (e.g., Original, Wavelet, LoG) to extract features from.
    2. Feature Classes: Selecting which specific feature classes (e.g., shape, glcm) to extract.
    3. Settings: Controlling preprocessing (resampling, normalization) and the behavior of filters and feature classes.
    4. Voxel-based settings: Specific settings used only when generating feature maps (e.g., kernelRadius).

    Important Initialization Rule: When initializing a RadiomicsFeaturesExtractor or an individual feature class using **kwargs, you can only provide Type 3 (Settings) parameters. Type 1 (Image Types) and Type 2 (Feature Classes) parameters must be provided via a parameter file during initialization, or changed later using specific class methods.

  9. Implement a custom Progress Reporter

    master

    In full-python mode, PyRadiomics allows reporting progress for GLCM and GLSZM matrix calculations. To enable this, set radiomics.progressReporter to a class object (not an instance) that satisfies these requirements:

    1. Accepts an iterable and a keyword argument desc (string label).
    2. Supports the context manager protocol (__enter__ and __exit__).
    3. Is itself iterable (implements __iter__).

    To intercept iteration for custom reporting, implement __iter__ to return self and define a __next__ method that calls the underlying iterable's __next__ method.

    class MyProgressReporter(object):
        def __init__(self, iterable, desc=''):
            self.desc = desc
            self.iterable = iterable
    
        def __iter__(self):
            return self
    
        def __next__(self):
            nextElement = self.iterable.__next__()
            # Insert custom progress reporting code here
            return nextElement
    
        def __enter__(self):
            print (self.desc)
            return self
    
        def __exit__(self, exc_type, exc_value, tb):
            pass
  10. Reproducible feature extraction in pyradiomics

    master
    To support reproducible research, pyradiomics includes metadata in its output. This output contains information regarding the used image and mask, as well as the specific settings and filters applied during the extraction process.
  11. Submit a parameter file for feature extraction

    master

    PyRadiomics encourages users to share their parameter files to help the community use optimal settings for specific use cases. Parameter files are stored in the examples/exampleSettings directory of the repository.

    To submit a parameter file via a Pull Request, follow these requirements:

    1. Naming Convention: The filename must contain the modality (e.g., MR, CT) and should optionally include the body part (e.g., prostate).
    2. File Extension: Use either .yml or .yaml.
    3. Documentation: Use comments within the parameter file to briefly explain your specific use case.

    Once submitted via a Pull Request, the file is automatically detected in the exampleSettings folder. You can manually validate your file using the provided test script.

    bin/testParams.py
  12. Implement a new Radiomics feature class

    master

    To add a new feature class, create a separate module where the module name serves as the feature class name (e.g., tex.py becomes the tex feature class). The class must inherit from radiomics.base.RadiomicsFeaturesBase.

    Key requirements:

    • Initialization: Call super().__init__(inputImage, inputMask, **kwargs) in your __init__ method.
    • Feature Methods: Define individual features using the signature get[Name]FeatureValue(self), which must return a scalar value.
    • C Extensions: If using C extensions for matrix calculations, implement a _calculateMatrix function that returns a numpy array and assign it to a class variable named P_[Name] (where [Name] is the module name).
    • Logging: Use self.logger (a child logger of the radiomics namespace) for all log messages.
    • Documentation: Docstrings are required at both the class and individual feature levels.
    from radiomics import base
    
    class Radiomics[Name](base.RadiomicsFeaturesBase):
        """
        Feature class docstring
        """
    
        def __init__(self, inputImage, inputMask, **kwargs):
            super(Radiomics[Name], self).__init__(inputImage, inputMask, **kwargs)
            # Feature class specific init
    
        def get[Feature]FeatureValue(self):
            """
            Feature docstring
            """
            # value = feature calculation using member variables of RadiomicsFeatureBase and this class.
            return [value]