Welcome to pyradiomics documentation!¶
This is an opensource python package for the extraction of Radiomics features from medical imaging. With this package we aim to establish a reference standard for Radiomic Analysis, and provide a tested and maintained opensource platform for easy and reproducible Radiomic Feature extraction. By doing so, we hope to increase awareness of radiomic capabilities and expand the community. The platform supports both the feature extraction in 2D and 3D.
If you publish any work which uses this package, please cite the following publication: Joost JM van Griethuysen, Andriy Fedorov, Chintan Parmar, Ahmed Hosny, Nicole Aucoin, Vivek Narayan, Regina GH BeetsTan, JeanChristophe FillionRobin, Steve Pieper, Hugo JWL Aerts, “Computational Radiomics System to Decode the Radiographic Phenotype”; Accepted Cancer Research 2017
Note
This work was supported in part by the US National Cancer Institute grant 5U24CA194354, QUANTITATIVE RADIOMICS SYSTEM DECODING THE TUMOR PHENOTYPE.
Warning
Not intended for clinical use.
Table of Contents¶
Installation¶
Get the code¶
 Ensure you have the version control system
git
installed on your machine.  Ensure that you have
python
installed on your machine, at least version 2.7 or 3.4.  Clone the repository:
git clone git://github.com/Radiomics/pyradiomics
Installation on your system¶
For unix like systems (MacOSX, linux):
cd pyradiomics
python m pip install r requirements.txt
python setup.py install
To use your build for interactive use and development: *
python setup.py develop
If you don’t have sudo/admin rights on your machine, you need to locally install numpy, nose, tqdm, PyWavelets, SimpleITK (specified in requirements.txt). In a bash shell:
pip install user upgrade pip export PATH=$HOME/.local/bin:$PATH pip install user r requirements.txt export PYTHONPATH=$HOME/.local/lib64/python2.7/sitepackages
For Windows:
cd pyradiomics
python m pip install r requirements.txt
python setup.py install
Usage¶
Instruction Video¶
Example¶
 PyRadiomics example code and data is available in the Github repository
 The sample sample data is provided in
pyradiomics/data
 Use jupyter to run the helloRadiomics example, located in
pyradiomics/examples/Notebooks
 Jupyter can also be used to run the example notebook as shown in the instruction video
 The example notebook can be found in
pyradiomics/examples/Notebooks
 The parameter file used in the instruction video is available in
pyradiomics/examples/exampleSettings
 The example notebook can be found in
 If jupyter is not installed, run the python script alternative (
pyradiomics/examples/helloRadiomics.py
):python helloRadiomics.py
Command Line Use¶
PyRadiomics has 2 commandline scripts,
pyradiomics
is for single image feature extraction andpyradiomicsbatch
is for feature extraction from a batch of images and segmentations.Both scripts can be run directly from a command line window, anywhere in your system.
To extract features from a single image and segmentation run:
pyradiomics <path/to/image> <path/to/segmentation>
To extract features from a batch run:
pyradiomicsbatch <path/to/input> <path/to/output>
The input file for batch processing is a CSV file where the first row is contains headers and each subsequent row represents one combination of an image and a segmentation and contains at least 2 elements: 1) path/to/image, 2) path/to/mask. The headers specify the column names and must be “Image” and “Mask” for image and mask location, respectively (capital sensitive). Additional columns may also be specified, all columns are copied to the output in the same order (with calculated features appended after last column). To specify custom label values for each combination, a column “Label” can optionally be added, which specifies the desired extraction label for each combination. Values specified in this column take precedence over label values specified in the parameter file or on the commandline. If a row contains no value, the default (or globally customized) value is used instead.
Note
All headers should be unique and different from headers provided by PyRadiomics (
<filter>_<class>_<feature>
).For more information on the possible command line arguments, run:
pyradiomics h pyradiomicsbatch h
Interactive Use¶
(LINUX) Add pyradiomics to the environment variable PYTHONPATH:
setenv PYTHONPATH /path/to/pyradiomics/radiomics
Start the python interactive session:
python
Import the necessary classes:
from radiomics import featureextractor, getTestCase import six import sys, os
Set up a pyradiomics directory variable:
dataDir = '/path/to/pyradiomics'
You will find sample data files brain1_image.nrrd and brain1_label.nrrd in that directory.
Store the path of your image and mask in two variables:
imageName, maskName = getTestCase('brain1', dataDir)
Also store the path to the file containing the extraction settings:
params = os.path.join(dataDir, "examples", "exampleSettings", "Params.yaml")
Instantiate the feature extractor class with the parameter file:
extractor = featureextractor.RadiomicsFeaturesExtractor(params)
Calculate the features:
result = extractor.execute(imageName, maskName) for key, val in six.iteritems(result): print("\t%s: %s" %(key, val))
See the feature extractor class for more information on using this core class.
PyRadiomics in 3D Slicer¶
A convenient frontend interface is provided as the ‘Radiomics’ extension for 3D Slicer. It is available here.
Using feature classes directly¶
This represents an example where feature classes are used directly, circumventing checks and preprocessing done by the radiomics feature extractor class, and is not intended as standard use example.
(LINUX) Add pyradiomics to the environment variable PYTHONPATH:
setenv PYTHONPATH /path/to/pyradiomics/radiomics
Start the python interactive session:
python
Import the necessary classes:
from radiomics import firstorder, glcm, imageoperations, shape, glrlm, glszm, getTestCase import SimpleITK as sitk import six import sys, os
Set up a data directory variable:
dataDir = '/path/to/pyradiomics/data'
You will find sample data files brain1_image.nrrd and brain1_label.nrrd in that directory.
Use SimpleITK to read a the brain image and mask:
imageName, maskName = getTestCase('brain1', dataDir) image = sitk.ReadImage(imageName) mask = sitk.ReadImage(maskName)
Calculate the first order features:
firstOrderFeatures = firstorder.RadiomicsFirstOrder(image,mask) firstOrderFeatures.calculateFeatures() for (key,val) in six.iteritems(firstOrderFeatures.featureValues): print("\t%s: %s" % (key, val))
See the Radiomic Features section for more features that you can calculate.
Setting Up Logging¶
PyRadiomics features extensive logging to help track down any issues with the extraction of features. By default PyRadiomics logging reports messages of level INFO and up (giving some information on progress during extraction and any warnings or errors that occur), and prints this to the output (stderr). By default, PyRadiomics does not create a log file.
To change the amount of information that is printed to the output, use setVerbosity()
in interactive
use and the optional verbosity
argument in commandline use.
When using PyRadiomics in interactive mode, enable storing the PyRadiomics logging in a file by adding an appropriate handler to the pyradiomics logger:
import radiomics
log_file = 'path/to/log_file.txt'
handler = logging.FileHandler(filename=log_file, mode='w') # overwrites log_files from previous runs. Change mode to 'a' to append.
formatter = logging.Formatter("%(levelname)s:%(name)s: %(message)s") # format string for log messages
handler.setFormatter(formatter)
radiomics.logger.addHandler(handler)
# Control the amount of logging stored by setting the level of the logger. N.B. if the level is higher than the
# Verbositiy level, the logger level will also determine the amount of information printed to the output
radiomics.logger.setLevel(logging.DEBUG)
To store a log file when running pyradiomics from the commandline, specify a file location in the optional
logfile
argument. The amount of logging that is stored is controlled by the loglevel
argument.
Customizing the Extraction¶
Types of Customization¶
There are 3 ways in which the feature extraction can be customized in PyRadiomics: 1) Specifying which image types (original/derived) to use to extract features from, 2) Specifying which feature(class) to extract, 3) Specifying settings, which control the pre processing and customize the behaviour of filters and feature classes.
Image Types¶
These are the input image types (either the original image or derived images) that can be used to extract features from.
The image types that are available are determined dynamically (all functions in imageoperations.py
that fit the
signature of a filter.
The enabled types are stored in the inputImages
dictionary in the feature extractor class instance and can be
changed using the functions enableAllInputImages()
,
disableAllInputImages()
,
enableInputImageByName()
and
enableInputImages()
. Moreover, custom settings can be
provided for each enabled input type, which will then only be applied for that input image type. Please note that this
will only work for settings that are applied at or after any filter is applied (i.e. not at the feature extractor
level).
By default, only the original input type is enabled.
Enabled Features¶
These are the features that are extracted from each (original and/or derived) input image. The available features are determined dynamically, and are ordered in feature classes. For more information on the signature used to identify features and feature classes, see the Developers <radiomicsdevelopers> section.
The enable features are stored in the enabledFeatures
dictionary in the feature extractor class instance and can be
changed using the functions enableAllFeatures()
,
disableAllFeatures()
,
enableFeatureClassByName()
and
enableFeaturesByName()
. Each keyvalue pair in the
dictionary represents one enabled feature class with the feature class name as the key and a list of enabled feature
names as value. If the value is None
or an empty list, all features in that class are enabled. Otherwise only the
features specified.
By default, all feature classes and all features are enabled.
Settings¶
Besides customizing what to extract (image types, features), PyRadiomics exposes various settings customizing how the
features are extracted. These settings operate at different levels. E.g. resampling is done just after the images are
loaded (in the feature extractor), so settings controlling the resampling operate only on the feature extractor level.
Settings are stored in the setttings
dictionary in the feature extractor class instance, where the key is the case
sensitive setting name. Custom settings are provided as keyword arguments at initialization of the feature extractor
(with the setting name as keyword and value as the argument value, e.g. binWidth=25
), or by interacting directly
with the settings
dictionary.
Note
When using the feature classes directly, feature class level settings can be customized by providing them as keyword arguments at initialization of the feature class.
Below are the settings that control the behaviour of the extraction, ordered per level and category. Each setting is listed as it’s unique, case sensitive name, followed by it’s default value in brackets. After the default value is the documentation on the type of the value and what the setting controls.
Feature Extractor Level¶
Image Normalization
 normalize [False]: Boolean, set to True to enable normalizing of the image before any resampling. See also
normalizeImage()
.  normalizeScale [1]: Float, > 0, determines the scale after normalizing the image. If normalizing is disabled, this has no effect.
 removeOutliers [None]: Float, > 0, defines the outliers to remove from the image. An outlier is defined as values
that differ more than \(n\sigma_x\) from the mean, where \(n>0\) and equal to the value of this setting. If
this parameter is omitted (providing it without a value (i.e. None) in the parameter file will throw an error), no
outliers are removed. If normalizing is disabled, this has no effect. See also
normalizeImage()
.
Resampling the image
resampledPixelSpacing [None]: List of 3 floats (> 0), sets the size of the voxel in (x, y, z) plane when resampling.
interpolator [sitkBSpline]: Simple ITK constant or string name thereof, sets interpolator to use for resampling. Enumerated value, possible values:
 sitkNearestNeighbor (= 1)
 sitkLinear (= 2)
 sitkBSpline (= 3)
 sitkGaussian (= 4)
 sitkLabelGaussian (= 5)
 sitkHammingWindowedSinc (= 6)
 sitkCosineWindowedSinc (= 7)
 sitkWelchWindowedSinc (= 8)
 sitkLanczosWindowedSinc (= 9)
 sitkBlackmanWindowedSinc (= 10)
padDistance [5]: Integer, \(\geq 0\), set the number of voxels pad cropped tumor volume with during resampling. Padding occurs in new feature space and is done on all faces, i.e. size increases in x, y and z direction by 2*padDistance. Padding is needed for some filters (e.g. LoG). Value of padded voxels are set to original gray level intensity, padding does not exceed original image boundaries. N.B. After application of filters image is cropped again without padding.
Note
Resampling is disabled when either resampledPixelSpacing or interpolator is set to None
Mask validation
 minimumROIDimensions [1]: Integer, range 13, specifies the minimum dimensions (1D, 2D or 3D, respectively). Singlevoxel segmentations are always excluded.
 minimumROISize [None]: Integer, > 0, specifies the minimum number of voxels required. Test is skipped if this parameter is omitted (specifying it as None in the parameter file will throw an error).
 geometryTolerance [None]: Float, determines the tolarance used by SimpleITK to compare origin, direction and spacing
between image and mask. Affects the fist step in
checkMask()
. If set toNone
, PyRadiomics will use SimpleITK default (1e16).  correctMask [False]: Boolean, if set to true, PyRadiomics will attempt to resample the mask to the image geometry when
the first step in
checkMask()
fails. This uses a nearest neighbor interpolator. Mask check will still fail if the ROI defined in the mask includes areas outside of the image physical space.
Miscellaneous
 enableCExtensions [True]: Boolean, set to False to force calculation to fullpython mode. See also
enableCExtensions()
.  additionalInfo [True]: boolean, set to False to disable inclusion of additional information on the extraction in the
output. See also
addProvenance()
.
Filter Level¶
Laplacian of Gaussian settings
 sigma: List of floats or integers, must be greater than 0. Sigma values to use for the filter (determines coarseness).
Warning
Setting for sigma must be provided if LoG filter is enabled. If omitted, no LoG image features are calculated and the function will return an empty dictionary.
Wavelet settings
start_level [0]: integer, 0 based level of wavelet which should be used as first set of decompositions from which a signature is calculated
level [1]: integer, number of levels of wavelet decompositions from which a signature is calculated.
wavelet [“coif1”]: string, type of wavelet decomposition. Enumerated value, validated against possible values present in the
pyWavelet.wavelist()
. Current possible values (pywavelet version 0.4.0) (where an aditional number is needed, range of values is indicated in []): haar
 dmey
 sym[220]
 db[120]
 coif[15]
 bior[1.1, 1.3, 1.5, 2.2, 2.4, 2.6, 2.8, 3.1, 3.3, 3.5, 3.7, 3.9, 4.4, 5.5, 6.8]
 rbio[1.1, 1.3, 1.5, 2.2, 2.4, 2.6, 2.8, 3.1, 3.3, 3.5, 3.7, 3.9, 4.4, 5.5, 6.8]
Feature Class Level¶
Image discretization
 binWidth [25]: Float, > 0, size of the bins when making a histogram and for discretization of the image gray level.
Forced 2D extraction
 force2D [False]: Boolean, set to true to force a by slice texture calculation. Dimension that identifies
the ‘slice’ can be defined in
force2Ddimension
. If input ROI is already a 2D ROI, features are automatically extracted in 2D. See alsogenerateAngles()
 force2Ddimension [0]: int, range 02. Specifies the ‘slice’ dimension for a byslice feature extraction. Value 0
identifies the ‘z’ dimension (axial plane feature extraction), and features will be extracted from the xy plane.
Similarly, 1 identifies the y dimension (coronal plane) and 2 the x dimension (saggital plane). if
force2Dextraction
is set to False, this parameter has no effect. See alsogenerateAngles()
Texture matrix weighting
weightingNorm [None]: string, indicates which norm should be used when applying distance weighting. Enumerated setting, possible values:
 ‘manhattan’: first order norm
 ‘euclidean’: second order norm
 ‘infinity’: infinity norm.
 ‘no_weighting’: GLCMs are weighted by factor 1 and summed
 None: Applies no weighting, mean of values calculated on separate matrices is returned.
In case of other values, an warning is logged and option ‘no_weighting’ is used.
Feature Class Specific Settings¶
First Order
 voxelArrayShift [0]: Integer, This amount is added to the gray level intensity in features Energy, Total Energy and RMS, this is to prevent negative values. If using CT data, or data normalized with mean 0, consider setting this parameter to a fixed value (e.g. 2000) that ensures nonnegative numbers in the image. Bear in mind however, that the larger the value, the larger the volume confounding effect will be.
GLCM
 distances [[1]]: List of integers. This specifies the distances between the center voxel and the neighbor, for which
angles should be generated. See also
generateAngles()
Parameter File¶
All 3 types of customization can be provided in a single yamlstructured text file, which can be provided in an optional
argument (param
) when running pyradiomics from the command line. In interactive mode, it can be provided during
initialization of the feature extractor, or using
loadParams()
after initialization. This removes the need
to hard code a customized extraction in a python script through use of functions described above. Additionally, this
also makes it more easy to share settings for customized extractions.
Note
Examples of the parameter file are provided in the pyradiomics/examples/exampleSettings
folder.
The paramsFile is written according to the YAMLconvention (www.yaml.org) and is checked by the code for consistency. Only one yaml document per file is allowed. Settings must be grouped by customization type as mentioned above. This is reflected in the structure of the document as follows:
<Customization Type>:
<Setting Name>: <value>
...
<Customization Type>:
...
Blank lines may be inserted to increase readability, these are ignored by the parser. Additional comments are also possible, these are preceded by an ‘#’ and can be inserted on a blank line, or on a line containing settings:
# This is a line containing only comments
setting: # This is a comment placed after the declaration of the 'setting' group.
Any keyword, such as a customization type or setting name may only be mentioned once. Multiple instances do not raise an error, but only the last one encountered is used.
The three setting types are named as follows:
 inputImage: input image to calculate features on. <value> is custom kwarg settings (dictionary). if <value> is an empty dictionary (‘{}’), no custom settings are added for this input image.
 featureClass: Feature class to enable, <value> is list of strings representing enabled features. If no <value> is specified or <value> is an empty list (‘[]’), all features for this class are enabled.
 setting: Setting to use for pre processing and class specific settings. if no <value> is specified, the value for this setting is set to None.
Note
 settings not specified in parameters are set to their default value.
 enabledFeatures are replaced by those in parameters (i.e. only specified features/classes are enabled. If the ‘featureClass’ customization type is omitted, all featureClasses and features are enabled.
 inputImages are replaced by those in parameters (i.e. only specified types are used to extract features from. If the ‘inputImage’ customization type is ommited, only original image is used for feature extraction, with no additional custom settings.
Pipeline Modules¶
This section contains the documentation on the various modules used to define the PyRadiomics pipeline and preprocess the input data. Feature class modules, which contain the feature definitions are documented in the Radiomic Features section.
Additionally, this section contains the documentation for the radiomics.generalinfo module, which provides the additional information about the extraction in the output. This additional information is added to enhance reproducibility of the results.
Finally, this section contains documentation for the global functions, which are used throughout the toolbox (such as logging and the C extensions) and the radiomics.base module, which defines the common interface for the feature classes.
Feature Extractor¶

class
radiomics.featureextractor.
RadiomicsFeaturesExtractor
(*args, **kwargs)[source]¶ Wrapper class for calculation of a radiomics signature. At and after initialisation various settings can be used to customize the resultant signature. This includes which classes and features to use, as well as what should be done in terms of preprocessing the image and what images (original and/or filtered) should be used as input.
Then a call to
execute()
generates the radiomics signature specified by these settings for the passed image and labelmap combination. This function can be called repeatedly in a batch process to calculate the radiomics signature for all image and labelmap combinations.At initialization, a parameters file can be provided containing all necessary settings. This is done by passing the location of the file as the single argument in the initialization call, without specifying it as a keyword argument. If such a file location is provided, any additional kwargs are ignored. Alternatively, at initialisation, custom settings can be provided as keyword arguments, with the setting name as key and its value as the argument value (e.g.
binWidth=25
). For mor information on possible settings and customization, see Customizing the Extraction.By default, all features in all feature classes are enabled. By default, only Original input image is enabled (No filter applied).

addProvenance
(provenance_on=True)[source]¶ Enable or disable reporting of additional information on the extraction. This information includes toolbox version, enabled input images and applied settings. Furthermore, additional information on the image and region of interest (ROI) is also provided, including original image spacing, total number of voxels in the ROI and total number of fully connected volumes in the ROI.
To disable this, call
addProvenance(False)
.

loadParams
(paramsFile)[source]¶ Parse specified parameters file and use it to update settings, enabled feature(Classes) and input images. For more information on the structure of the parameter file, see Customizing the extraction.
If supplied file does not match the requirements (i.e. unrecognized names or invalid values for a setting), a pykwalify error is raised.

enableInputImageByName
(inputImage, enabled=True, customArgs=None)[source]¶ Enable or disable specified input image. If enabling input image, optional custom settings can be specified in customArgs.
Current possible input images are:
 Original: No filter applied
 Wavelet: Wavelet filtering, yields 8 decompositions per level (all possible combinations of applying either
a High or a Low pass filter in each of the three dimensions.
See also
getWaveletImage()
 LoG: Laplacian of Gaussian filter, edge enhancement filter. Emphasizes areas of gray level change, where sigma
defines how coarse the emphasised texture should be. A low sigma emphasis on fine textures (change over a
short distance), where a high sigma value emphasises coarse textures (gray level change over a large distance).
See also
getLoGImage()
 Square: Takes the square of the image intensities and linearly scales them back to the original range. Negative values in the original image will be made negative again after application of filter.
 SquareRoot: Takes the square root of the absolute image intensities and scales them back to original range. Negative values in the original image will be made negative again after application of filter.
 Logarithm: Takes the logarithm of the absolute intensity + 1. Values are scaled to original range and negative original values are made negative again after application of filter.
 Exponential: Takes the the exponential, where filtered intensity is e^(absolute intensity). Values are scaled to original range and negative original values are made negative again after application of filter.
For the mathmetical formulas of square, squareroot, logarithm and exponential, see their respective functions in imageoperations (
getSquareImage()
,getSquareRootImage()
,getLogarithmImage()
andgetExponentialImage()
, respectively).

enableInputImages
(**inputImages)[source]¶ Enable input images, with optionally custom settings, which are applied to the respective input image. Settings specified here override those in kwargs. The following settings are not customizable:
 interpolator
 resampledPixelSpacing
 padDistance
Updates current settings: If necessary, enables input image. Always overrides custom settings specified for input images passed in inputImages. To disable input images, use
enableInputImageByName()
ordisableAllInputImages()
instead.Parameters: inputImages – dictionary, key is imagetype (original, wavelet or log) and value is custom settings (dictionary)

enableFeatureClassByName
(featureClass, enabled=True)[source]¶ Enable or disable all features in given class.

enableFeaturesByName
(**enabledFeatures)[source]¶ Specify which features to enable. Key is feature class name, value is a list of enabled feature names.
To enable all features for a class, provide the class name with an empty list or None as value. Settings for feature classes specified in enabledFeatures.keys are updated, settings for feature classes not yet present in enabledFeatures.keys are added. To disable the entire class, use
disableAllFeatures()
orenableFeatureClassByName()
instead.

execute
(imageFilepath, maskFilepath, label=None)[source]¶ Compute radiomics signature for provide image and mask combination. It comprises of the following steps:
 Image and mask are loaded and normalized/resampled if necessary.
 Validity of ROI is checked using
checkMask()
, which also computes and returns the bounding box.  If enabled, provenance information is calculated and stored as part of the result.
 Shape features are calculated on a cropped (no padding) version of the original image.
 Other enabled featureclasses are calculated using all specified input image types in
inputImages
. Images are cropped to tumor mask (no padding) after application of any filter and before being passed to the feature class.  The calculated features is returned as
collections.OrderedDict
.
Parameters:  imageFilepath – SimpleITK Image, or string pointing to image file location
 maskFilepath – SimpleITK Image, or string pointing to labelmap file location
 label – Integer, value of the label for which to extract features. If not specified, last specified label is used. Default label is 1.
Returns: dictionary containing calculated signature (“<filter>_<featureClass>_<featureName>”:value).

loadImage
(ImageFilePath, MaskFilePath)[source]¶ Preprocess the image and labelmap. If ImageFilePath is a string, it is loaded as SimpleITK Image and assigned to image, if it already is a SimpleITK Image, it is just assigned to image. All other cases are ignored (nothing calculated). Equal approach is used for assignment of mask using MaskFilePath.
If normalizing is enabled image is first normalized before any resampling is applied.
If resampling is enabled, both image and mask are resampled and cropped to the tumor mask (with additional padding as specified in padDistance) after assignment of image and mask.

getProvenance
(imageFilepath, maskFilepath, mask)[source]¶ Generates provenance information for reproducibility. Takes the original image & mask filepath, as well as the resampled mask which is passed to the feature classes. Returns a dictionary with keynames coded as “general_info_<item>”. For more information on generated items, see generalinfo

computeFeatures
(image, mask, inputImageName, **kwargs)[source]¶ Compute signature using image, mask, **kwargs settings.
This function computes the signature for just the passed image (original or derived), it does not preprocess or apply a filter to the passed image. Features / Classes to use for calculation of signature are defined in self.enabledFeatures. See also
enableFeaturesByName()
.Note
shape descriptors are independent of gray level and therefore calculated separately (handeled in execute). In this function, no shape functions are calculated.

Image Processing and Filters¶

radiomics.imageoperations.
getBinEdges
(binwidth, parameterValues)[source]¶ Calculate and return the histogram using parameterValues (1D array of all segmented voxels in the image). Parameter
binWidth
determines the fixed width of each bin. This ensures comparable voxels after binning, a fixed bin count would be dependent on the intensity range in the segmentation.Returns the bin edges, a list of the edges of the calculated bins, length is N(bins) + 1. Bins are defined such, that the bin edges are equally spaced from zero, and that the leftmost edge \(\leq \min(X_{gl})\).
Example: for a ROI with values ranging from 54 to 166, and a bin width of 25, the bin edges will be [50, 75, 100, 125, 150, 175].
This value can be directly passed to
numpy.histogram
to generate a histogram ornumpy.digitize
to discretize the ROI gray values. See alsobinImage()
.References
 Leijenaar RTH, Nalbantov G, Carvalho S, et al. The effect of SUV discretization in quantitative FDGPET Radiomics: the need for standardized methodology in tumor texture analysis. Sci Rep. 2015;5(August):11075.

radiomics.imageoperations.
binImage
(binwidth, parameterMatrix, parameterMatrixCoordinates)[source]¶ Discretizes the parameterMatrix (matrix representation of the gray levels in the ROI) using the binEdges calculated using
getBinEdges()
. Only voxels defined by parameterMatrixCoordinates (defining the segmentation) are used for calculation of histogram and subsequently discretized. Voxels outside segmentation are left unchanged.\(X_{b, i} = \lfloor \frac{X_{gl, i}}{W} \rfloor  \lfloor \frac {\min(X_{gl})}{W} \rfloor + 1\)
Here, \(X_{gl, i}\) and \(X_{b, i}\) are gray level intensities before and after discretization, respectively. \({W}\) is the bin width value (specfied in
binWidth
parameter). The first part of the formula ensures that the bins are equally spaced from 0, whereas the second part ensures that the minimum gray level intensity inside the ROI after binning is always 1.If the range of gray level intensities is equally dividable by the binWidth, i.e. \((\max(X_{gl}) \min(X_{gl})) \mod W = 0\), the maximum intensity will be encoded as numBins + 1, therefore the maximum number of gray level intensities in the ROI after binning is number of bins + 1.
Warning
This is different from the assignment of voxels to the bins by
numpy.histogram
, which has halfopen bins, with the exception of the rightmost bin, which means this maximum values are assigned to the topmost bin.numpy.digitize
uses halfopen bins, including the rightmost bin.

radiomics.imageoperations.
generateAngles
(size, **kwargs)[source]¶ Generate all possible angles for specified distances in
distances
in 3D. E.g. for d = 1, 13 angles are generated and for d = 2, 49 angles are generated (representing the 26 connected region for distance 1, and the 98 connected region for distance 2). Angles are generated with the following steps: All angles for distance = 1 to the maximum distance specified in
distances
are generated.  Only angles are retained, for which the maximum step size in any dimension (i.e. the infinity norm distance from
the center voxel) is present in
distances
.  “Impossible” angles (where ‘neighbouring’ voxels will always be outside delineation) are deleted.
 If
force2Dextraction
is enabled, all angles defining a step in theforce2Ddimension
are removed (e.g. if this dimension is 0, all angles that have a nonzero step size at index 0 (z dimension) are removed, resulting in angles that only move in the x and/or y dimension).
Parameters:  size – dimensions (z, x, y) of the bounding box of the tumor mask.
 kwargs –
The following additional parameters can be specified here (default values in brackets):
 distances [[1]]: List of integers. This specifies the distances between the center voxel and the neighbor, for which angles should be generated.
 force2D [False]: Boolean, set to true to force a by slice texture calculation. Dimension that identifies
the ‘slice’ can be defined in
force2Ddimension
. If input ROI is already a 2D ROI, features are automatically extracted in 2D.  force2Ddimension [0]: int, range 02. Specifies the ‘slice’ dimension for a byslice feature extraction. Value 0
identifies the ‘z’ dimension (axial plane feature extraction), and features will be extracted from the xy plane.
Similarly, 1 identifies the y dimension (coronal plane) and 2 the x dimension (saggital plane). if
force2Dextraction
is set to False, this parameter has no effect.
Returns: numpy array with shape (N, 3), where N is the number of unique angles
 All angles for distance = 1 to the maximum distance specified in

radiomics.imageoperations.
checkMask
(imageNode, maskNode, **kwargs)[source]¶ Checks whether the Region of Interest (ROI) defined in the mask size and dimensions match constraints, specified in settings. The following checks are performed.
 Check whether the mask corresponds to the image (i.e. has a similar size, spacing, direction and origin). N.B.
This check is performed by SimpleITK, if it fails, an error is logged, with additional error information from
SimpleITK logged with level DEBUG (i.e. logginglevel has to be set to debug to store this information in the log
file). The tolerance can be increased using the
geometryTolerance
parameter. Alternatively, if thecorrectMask
parameter isTrue
, PyRadiomics will check if the mask contains a valid ROI (inside image physical area) and if so, resample the mask to image geometry. See Settings for more info.  Check if the label is present in the mask
 Count the number of dimensions in which the size of the ROI > 1 (i.e. does the ROI represent a single voxel (0), a
line (1), a surface (2) or a volume (3)) and compare this to the minimum number of dimension required (specified in
minimumROIDimensions
).  Optional. Check if there are at least N voxels in the ROI. N is defined in
minimumROISize
, this test is skipped ifminimumROISize = None
.
This function returns a tuple of two items. The first item (if not None) is the bounding box of the mask. The second item is the mask that has been corrected by resampling to the input image geometry (if that resampling was successful).
If a check fails, an error is logged and a (None,None) tuple is returned. No features will be extracted for this mask. If the mask passes all tests, this function returns the bounding box, which is used in the
cropToTumorMask()
function.The bounding box is calculated during (1.) and used for the subsequent checks. The bounding box is calculated by SimpleITK.LabelStatisticsImageFilter() and returned as a tuple of indices: (L_x, U_x, L_y, U_y, L_z, U_z), where ‘L’ and ‘U’ are lower and upper bound, respectively, and ‘x’, ‘y’ and ‘z’ the three image dimensions.
By reusing the bounding box calculated here, calls to SimpleITK.LabelStatisticsImageFilter() are reduced, improving performance.
Uses the following settings:
 minimumROIDimensions [1]: Integer, range 13, specifies the minimum dimensions (1D, 2D or 3D, respectively). Singlevoxel segmentations are always excluded.
 minimumROISize [None]: Integer, > 0, specifies the minimum number of voxels required. Test is skipped if this parameter is set to None.
Note
If the first check fails there are generally 2 possible causes:
 The image and mask are matched, but there is a slight difference in origin, direction or spacing. The exact
cause, difference and used tolerance are stored with level DEBUG in a log (if enabled). For more information on
setting up logging, see “setting up logging” and the helloRadiomics examples
(located in the
pyradiomics/examples
folder). This problem can be fixed by changing the global tolerance (geometryTolerance
parameter) or enabling mask correction (correctMask
parameter).  The image and mask do not match, but the ROI contained within the mask does represent a physical volume
contained within the image. If this is the case, resampling is needed to ensure matching geometry between image
and mask before features can be extracted. This can be achieved by enabling mask correction using the
correctMask
parameter.
 Check whether the mask corresponds to the image (i.e. has a similar size, spacing, direction and origin). N.B.
This check is performed by SimpleITK, if it fails, an error is logged, with additional error information from
SimpleITK logged with level DEBUG (i.e. logginglevel has to be set to debug to store this information in the log
file). The tolerance can be increased using the

radiomics.imageoperations.
cropToTumorMask
(imageNode, maskNode, boundingBox)[source]¶ Create a sitkImage of the segmented region of the image based on the input label.
Create a sitkImage of the labelled region of the image, cropped to have a cuboid shape equal to the ijk boundaries of the label.
Parameters:  boundingBox – The bounding box used to crop the image. This is the bounding box as returned by
checkMask()
.  label – [1], value of the label, onto which the image and mask must be cropped.
Returns: Cropped image and mask (SimpleITK image instances).
 boundingBox – The bounding box used to crop the image. This is the bounding box as returned by

radiomics.imageoperations.
resampleImage
(imageNode, maskNode, resampledPixelSpacing, interpolator=3, label=1, padDistance=5)[source]¶ Resamples image and mask to the specified pixel spacing (The default interpolator is Bspline).
Resampling can be enabled using the settings ‘interpolator’ and ‘resampledPixelSpacing’ in the parameter file or as part of the settings passed to the feature extractor. See also feature extractor.
‘imageNode’ and ‘maskNode’ are SimpleITK Objects, and ‘resampledPixelSpacing’ is the output pixel spacing (sequence of 3 elements).
Only part of the image and labelmap are resampled. The resampling grid is aligned to the input origin, but only voxels covering the area of the image ROI (defined by the bounding box) and the padDistance are resampled. This results in a resampled and partially cropped image and mask. Additional padding is required as some filters also sample voxels outside of segmentation boundaries. For feature calculation, image and mask are cropped to the bounding box without any additional padding, as the feature classes do not need the gray level values outside the segmentation.
The resampling grid is calculated using only the input mask. Even when image and mask have different directions, both the cropped image and mask will have the same direction (equal to direction of the mask). Spacing and size are determined by settings and bounding box of the ROI.
Note
Before resampling the bounds of the nonpadded ROI are compared to the bounds. If the ROI bounding box includes areas outside of the physical space of the image, an error is logged and (None, None) is returned. No features will be extracted. This enables the input image and mask to have different geometry, so long as the ROI defines an area within the image.
Note
The additional padding is adjusted, so that only the physical space within the mask is resampled. This is done to prevent resampling outside of the image. Please note that this assumes the image and mask to image the same physical space. If this is not the case, it is possible that voxels outside the image are included in the resampling grid, these will be assigned a value of 0. It is therefore recommended, but not enforced, to use an input mask which has the same or a smaller physical space than the image.

radiomics.imageoperations.
normalizeImage
(image, scale=1, outliers=None)[source]¶ Normalizes the image by centering it at the mean with standard deviation. Normalization is based on all gray values in the image, not just those inside the segementation.
\(f(x) = \frac{s(x  \mu_x)}{\sigma_x}\)
Where:
 \(x\) and \(f(x)\) are the original and normalized intensity, respectively.
 \(\mu_x\) and \(\sigma_x\) are the mean and standard deviation of the image instensity values.
 \(s\) is an optional scaling defined by
scale
. By default, it is set to 1.
Optionally, outliers can be removed, in which case values for which \(x > \mu_x + n\sigma_x\) or \(x < \mu_x  n\sigma_x\) are set to \(\mu_x + n\sigma_x\) and \(\mu_x  n\sigma_x\), respectively. Here, \(n>0\) and defined by
outliers
. This, in turn, is controlled by theremoveOutliers
parameter. Removal of outliers is done after the values of the image are normalized, but beforescale
is applied.

radiomics.imageoperations.
applyThreshold
(inputImage, lowerThreshold, upperThreshold, insideValue=None, outsideValue=0)[source]¶

radiomics.imageoperations.
getOriginalImage
(inputImage, **kwargs)[source]¶ This function does not apply any filter, but returns the original image. This function is needed to dyanmically expose the original image as a valid input image.
Returns: Yields original image, ‘original’ and kwargs

radiomics.imageoperations.
getLoGImage
(inputImage, **kwargs)[source]¶ Apply Laplacian of Gaussian filter to input image and compute signature for each filtered image.
Following settings are possible:
 sigma: List of floats or integers, must be greater than 0. Sigma values to use for the filter (determines coarseness).
N.B. Setting for sigma must be provided. If omitted, no LoG image features are calculated and the function will return an empty dictionary.
Returned filter name reflects LoG settings: logsigma<sigmaValue>3D.
Returns: Yields log filtered image for each specified sigma, corresponding filter name and kwargs

radiomics.imageoperations.
getWaveletImage
(inputImage, **kwargs)[source]¶ Apply wavelet filter to image and compute signature for each filtered image.
Following settings are possible:
 start_level [0]: integer, 0 based level of wavelet which should be used as first set of decompositions from which a signature is calculated
 level [1]: integer, number of levels of wavelet decompositions from which a signature is calculated.
 wavelet [“coif1”]: string, type of wavelet decomposition. Enumerated value, validated against possible values
present in the
pyWavelet.wavelist()
. Current possible values (pywavelet version 0.4.0) (where an aditional number is needed, range of values is indicated in []): haar
 dmey
 sym[220]
 db[120]
 coif[15]
 bior[1.1, 1.3, 1.5, 2.2, 2.4, 2.6, 2.8, 3.1, 3.3, 3.5, 3.7, 3.9, 4.4, 5.5, 6.8]
 rbio[1.1, 1.3, 1.5, 2.2, 2.4, 2.6, 2.8, 3.1, 3.3, 3.5, 3.7, 3.9, 4.4, 5.5, 6.8]
Returned filter name reflects wavelet type: wavelet[level]<decompositionName>
N.B. only levels greater than the first level are entered into the name.
Returns: Yields each wavelet decomposition and final approximation, corresponding filter name and kwargs

radiomics.imageoperations.
getSquareImage
(inputImage, **kwargs)[source]¶ Computes the square of the image intensities.
Resulting values are rescaled on the range of the initial original image and negative intensities are made negative in resultant filtered image.
\(f(x) = (cx)^2,\text{ where } c=\displaystyle\frac{1}{\sqrt{\max(x)}}\)
Where \(x\) and \(f(x)\) are the original and filtered intensity, respectively.
Returns: Yields square filtered image, ‘square’ and kwargs

radiomics.imageoperations.
getSquareRootImage
(inputImage, **kwargs)[source]¶ Computes the square root of the absolute value of image intensities.
Resulting values are rescaled on the range of the initial original image and negative intensities are made negative in resultant filtered image.
\(f(x) = \left\{ {\begin{array}{lcl} \sqrt{cx} & \mbox{for} & x \ge 0 \\ \sqrt{cx} & \mbox{for} & x < 0\end{array}} \right.,\text{ where } c=\max(x)\)
Where \(x\) and \(f(x)\) are the original and filtered intensity, respectively.
Returns: Yields square root filtered image, ‘squareroot’ and kwargs

radiomics.imageoperations.
getLogarithmImage
(inputImage, **kwargs)[source]¶ Computes the logarithm of the absolute value of the original image + 1.
Resulting values are rescaled on the range of the initial original image and negative intensities are made negative in resultant filtered image.
\(f(x) = \left\{ {\begin{array}{lcl} c\log{(x + 1)} & \mbox{for} & x \ge 0 \\ c\log{(x + 1)} & \mbox{for} & x < 0\end{array}} \right. \text{, where } c=\left\{ {\begin{array}{lcl} \frac{\max(x)}{\log(\max(x) + 1)} & if & \max(x) \geq 0 \\ \frac{\max(x)}{\log(\max(x)  1)} & if & \max(x) < 0 \end{array}} \right.\)
Where \(x\) and \(f(x)\) are the original and filtered intensity, respectively.
Returns: Yields logarithm filtered image, ‘logarithm’ and kwargs

radiomics.imageoperations.
getExponentialImage
(inputImage, **kwargs)[source]¶ Computes the exponential of the original image.
Resulting values are rescaled on the range of the initial original image.
\(f(x) = e^{cx},\text{ where } c=\displaystyle\frac{\log(\max(x))}{\max(x)}\)
Where \(x\) and \(f(x)\) are the original and filtered intensity, respectively.
Returns: Yields exponential filtered image, ‘exponential’ and kwargs
General Info Module¶

class
radiomics.generalinfo.
GeneralInfo
(imagePath, maskPath, resampledMask, kwargs, inputImages)[source]¶ 
execute
()[source]¶ Return a dictionary containing all general info items. Format is <info_item>:<value>, where the type of the value is preserved. For CSV format, this will result in conversion to string and quotes where necessary, for JSON, the values will be interpreted and stored as JSON strings.

getBoundingBoxValue
()[source]¶ Calculate and return the boundingbox extracted using the specified label. Elements 0, 1 and 2 are the x, y and z coordinates of the lower bound, respectively. Elements 3, 4 and 5 are the size of the bounding box in x, y and z direction, respectively.
Values are based on the resampledMask.

getGeneralSettingsValue
()[source]¶ Return a string representation of the settings contained in kwargs. Format is {<settings_name>:<value>, ...}.

getImageHashValue
()[source]¶ Returns the sha1 hash of the image. This enables checking whether two images are the same, regardless of the file location.
If the reading of the image fails, an empty string is returned.

getImageSpacingValue
()[source]¶ Returns the original spacing of the image.
If the reading of the image fails, an empty string is returned.

getInputImagesValue
()[source]¶ Return a string representation of the enabled filters and any custom settings for the filter. Format is {<filter_name>:{<setting_name>:<value>, ...}, ...}.

getMaskHashValue
()[source]¶ Returns the sha1 hash of the mask. This enables checking whether two masks are the same, regardless of the file location.
If the reading of the mask fails, an empty string is returned. Uses the original mask, specified in maskPath.

getVolumeNumValue
()[source]¶ Calculate and return the number of zones within the mask for the specified label. A zone is defined as a group of connected neighbours that are segmented with the specified label, and a voxel is considered a neighbour using 26connectedness for 3D and 8connectedness for 2D.
Values are based on the resampledMask.

Feature Class Base¶

class
radiomics.base.
RadiomicsFeaturesBase
(inputImage, inputMask, **kwargs)[source]¶ Bases:
object
This is the abstract class, which defines the common interface for the feature classes. All feature classes inherit (directly of indirectly) from this class.
At initialization, image and labelmap are passed as SimpleITK image objects (
inputImage
andinputMask
, respectively.) The motivation for using SimpleITK images as input is to keep the possibility of reusing the optimized feature calculators implemented in SimpleITK in the future. If either the image or the mask is None, initialization fails and a warning is logged (does not raise an error).Logging is set up using a child logger from the parent ‘radiomics’ logger. This retains the toolbox structure in the generated log.
The following variables are instantiated at initialization:
 binWidth: bin width, as specified in
**kwargs
. If key is not present, a default value of 25 is used.  label: label value of Region of Interest (ROI) in labelmap. If key is not present, a default value of 1 is used.
 verbose: boolean indication whether or not to provide progress reporting to the output.
 featureNames: list containing the names of features defined in the feature class. See
getFeatureNames()
 inputImage: Simple ITK image object of the input image
 inputMask: Simple ITK image object of the input labelmap
 imageArray: numpy array of the gray values in the input image
 maskArray: numpy array with elements set to 1 where labelmap = label, 0 otherwise
 matrix: numpy array of the gray values in the input image (with gray values inside ROI discretized when necessary in the texture feature classes).
 matrixCoordinates: tuple of 3 numpy arrays containing the z, x and y coordinates of the voxels included in the ROI, respectively. Length of each array is equal to total number of voxels inside ROI.
 targetVoxelArray: flattened numpy array of gray values inside ROI.

enableFeatureByName
(featureName, enable=True)[source]¶ Enables or disables feature specified by
featureName
. If feature is not present in this class, a lookup error is raised.enable
specifies whether to enable or disable the feature.

classmethod
getFeatureNames
()[source]¶ Dynamically enumerates features defined in the feature class. Features are identified by the
get<Feature>FeatureValue
signature, where <Feature> is the name of the feature (unique on the class level).Found features are returned as a list of the feature names (
[<Feature1>, <Feature2>, ...]
).This function is called at initialization, found features are stored in the
featureNames
variable.

calculateFeatures
()[source]¶ Calculates all features enabled in
enabledFeatures
. A feature is enabled if it’s key is present in this dictionary and it’s value is True.Calculated values are stored in the
featureValues
dictionary, with feature name as key and the calculated feature value as value. If an exception is thrown during calculation, the error is logged, and the value is set to NaN.
 binWidth: bin width, as specified in
Global Toolbox Functions¶

radiomics.
cMatsEnabled
()[source]¶ Returns a boolean indicating whether or not the C extensions are enabled. This function is called by the feature classes to switch between Cenhanced calculation and full python mode.

radiomics.
enableCExtensions
(enabled=True)[source]¶ By default, calculation of GLCM, GLRLM and GLSZM is done in C, using extension
_cmatrices.py
If an error occurs during loading of this extension, a warning is logged and the extension is disabled, matrices are then calculated in python. The C extension can be disabled by calling this function as
enableCExtensions(False)
, which forces the calculation of the matrices to fullpython mode.Reenabling use of C implementation is also done by this function, but if the extension is not loaded correctly, a warning is logged and matrix calculation is forced to fullpython mode.

radiomics.
getFeatureClasses
()[source]¶ Iterates over all modules of the radiomics package using pkgutil and subsequently imports those modules.
Return a dictionary of all modules containing featureClasses, with modulename as key, abstract class object of the featureClass as value. Assumes only one featureClass per module
This is achieved by inspect.getmembers. Modules are added if it contains a member that is a class, with name starting with ‘Radiomics’ and is inherited from
radiomics.base.RadiomicsFeaturesBase
.This iteration only runs once (at initialization of toolbox), subsequent calls return the dictionary created by the first call.

radiomics.
getInputImageTypes
()[source]¶ Returns a list of possible input image types. This function finds the image types dynamically by matching the signature (“get<inputImage>Image”) against functions defined in imageoperations. Returns a list containing available input image names (<inputImage> part of the corresponding function name).
This iteration only occurs once, at initialization of the toolbox. Found results are stored and returned on subsequent calls.

radiomics.
getTestCase
(testCase, repoDirectory=None)[source]¶ This function provides an image and mask for testing PyRadiomics. One of five test cases can be selected:
 brain1
 brain2
 breast1
 lung1
 lung2
If the repository is available locally (including all five test cases, the path to the root folder of the repository can be specified in
repoDirectory
, preventing unnecessary downloads. If the repository is not found, or the repository does not contain the requested test case, PyRadiomics checks if it is run in development mode (directly from the source code in the repository), and if so, if it can find the test case relative to it’s own location.If the requested test case could not be found in the repository, PyRadiomics downloads the test case from the GitHub repository and stores it in temporary files. If the test case was already downloaded, this is returned instead.
Returns a tuple of two strings:
(path/to/image.nrrd, path/to/mask.nrrd)

radiomics.
setVerbosity
(level)[source]¶ Change the amount of information PyRadiomics should print out during extraction. The lower the level, the more information is printed to the output (stderr).
Using the
level
(Python defined logging levels) argument, the following levels are possible: 60: Quiet mode, no messages are printed to the stderr
 50: Only log messages of level “CRITICAL” are printed
 40: Log messages of level “ERROR” and up are printed
 30: Log messages of level “WARNING” and up are printed
 20: Log messages of level “INFO” and up are printed
 10: Log messages of level “DEBUG” and up are printed (i.e. all log messages)
By default, the radiomics logger is set to level “INFO” and the stderr handler to level “WARNING”. Therefore a log storing the extraction log messages from level “INFO” and up can be easily set up by adding an appropriate handler to the radiomics logger, while the output to stderr will still only contain warnings and errors.
Note
This function assumes the handler added to the radiomics logger at initialization of the toolbox is not removed from the logger handlers and therefore remains the first handler.
Note
This does not affect the level of the logger itself (e.g. if verbosity level = 3, log messages with DEBUG level can still be stored in a log file if an appropriate handler is added to the logger and the logging level of the logger has been set to the correct level. Exception: In case the verbosity is set to DEBUG, the level of the logger is also lowered to DEBUG. If the verbosity level is then raised again, the logger level will remain DEBUG.
Radiomic Features¶
This section contains the definitions of the various features that can be extracted using PyRadiomics. They are subdivided into the following classes:
 First Order Features (19 features)
 Shape Features (16 features)
 Gray Level Cooccurrence Matrix (GLCM) Features (27 features)
 Gray Level Size Zone Matrix (GLSZM) Features (16 features)
 Gray Level Run Length Matrix (GLRLM) Features (16 features)
All feature classes, with the exception of shape can be calculated on either the original image and/or a derived image, obtained by applying one of several filters. The shape descriptors are independent of gray value, and are extracted from the label mask. If enabled, they are calculated separately of enabled input image types, and listed in the result as if calculated on the original image.
First Order Features¶

class
radiomics.firstorder.
RadiomicsFirstOrder
(inputImage, inputMask, **kwargs)[source]¶ Bases:
radiomics.base.RadiomicsFeaturesBase
Firstorder statistics describe the distribution of voxel intensities within the image region defined by the mask through commonly used and basic metrics.
Let:
 \(\textbf{X}\) be a set of \(N\) voxels included in the ROI
 \(\textbf{P}(i)\) be the first order histogram with \(N_l\) discrete intensity levels,
where \(N_l\) is the number of nonzero bins, equally spaced from 0 with a width defined in the
binWidth
parameter.  \(p(i)\) be the normalized first order histogram and equal to \(\frac{\textbf{P}(i)}{\sum{\textbf{P}(i)}}\)
Following additional settings are possible:
 voxelArrayShift [0]: Integer, This amount is added to the gray level intensity in features Energy, Total Energy and RMS, this is to prevent negative values. If using CT data, or data normalized with mean 0, consider setting this parameter to a fixed value (e.g. 2000) that ensures nonnegative numbers in the image. Bear in mind however, that the larger the value, the larger the volume confounding effect will be.

getEnergyFeatureValue
()[source]¶ 1. Energy
\[\textit{energy} = \displaystyle\sum^{N}_{i=1}{(\textbf{X}(i) + c)^2}\]Here, \(c\) is optional value, defined by
voxelArrayShift
, which shifts the intensities to prevent negative values in \(\textbf{X}\). This ensures that voxels with the lowest gray values contribute the least to Energy, instead of voxels with gray level intensity closest to 0.Energy is a measure of the magnitude of voxel values in an image. A larger values implies a greater sum of the squares of these values.
Note
This feature is volumeconfounded, a larger value of \(c\) increases the effect of volumeconfounding.

getTotalEnergyFeatureValue
()[source]¶ 2. Total Energy
\[\textit{total energy} = V_{voxel}\displaystyle\sum^{N}_{i=1}{(\textbf{X}(i) + c)^2}\]Here, \(c\) is optional value, defined by
voxelArrayShift
, which shifts the intensities to prevent negative values in \(\textbf{X}\). This ensures that voxels with the lowest gray values contribute the least to Energy, instead of voxels with gray level intensity closest to 0.Total Energy is the value of Energy feature scaled by the volume of the voxel in cubic mm.
Note
This feature is volumeconfounded, a larger value of \(c\) increases the effect of volumeconfounding.

getEntropyFeatureValue
()[source]¶ 3. Entropy
\[\textit{entropy} = \displaystyle\sum^{N_l}_{i=1}{p(i)\log_2\big(p(i)+\epsilon\big)}\]Here, \(\epsilon\) is an arbitrarily small positive number (\(\approx 2.2\times10^{16}\)).
Entropy specifies the uncertainty/randomness in the image values. It measures the average amount of information required to encode the image values.

getMaximumFeatureValue
()[source]¶ 7. Maximum
\[\textit{maximum} = \max(\textbf{X})\]The maximum gray level intensity within the ROI.

getMeanFeatureValue
()[source]¶ 8. Mean
\[\textit{mean} = \frac{1}{N}\displaystyle\sum^{N}_{i=1}{\textbf{X}(i)}\]The average gray level intensity within the ROI.

getInterquartileRangeFeatureValue
()[source]¶ 10. Interquartile Range
\[\textit{interquartile range} = \textbf{P}_{75}  \textbf{P}_{25}\]Here \(\textbf{P}_{25}\) and \(\textbf{P}_{75}\) are the 25^{th} and 75^{th} percentile of the image array, respectively.

getRangeFeatureValue
()[source]¶ 11. Range
\[\textit{range} = \max(\textbf{X})  \min(\textbf{X})\]The range of gray values in the ROI.

getMeanAbsoluteDeviationFeatureValue
()[source]¶ 12. Mean Absolute Deviation (MAD)
\[\textit{MAD} = \frac{1}{N}\displaystyle\sum^{N}_{i=1}{\textbf{X}(i)\bar{X}}\]Mean Absolute Deviation is the mean distance of all intensity values from the Mean Value of the image array.

getRobustMeanAbsoluteDeviationFeatureValue
()[source]¶ 13. Robust Mean Absolute Deviation (rMAD)
\[\textit{rMAD} = \frac{1}{N_{1090}}\displaystyle\sum^{N_{1090}}_{i=1} {\textbf{X}_{1090}(i)\bar{X}_{1090}}\]Robust Mean Absolute Deviation is the mean distance of all intensity values from the Mean Value calculated on the subset of image array with gray levels in between, or equal to the 10^{th} and 90^{th} percentile.

getRootMeanSquaredFeatureValue
()[source]¶ 14. Root Mean Squared (RMS)
\[\textit{RMS} = \sqrt{\frac{1}{N}\sum^{N}_{i=1}{(\textbf{X}(i) + c)^2}}\]Here, \(c\) is optional value, defined by
voxelArrayShift
, which shifts the intensities to prevent negative values in \(\textbf{X}\). This ensures that voxels with the lowest gray values contribute the least to RMS, instead of voxels with gray level intensity closest to 0.RMS is the squareroot of the mean of all the squared intensity values. It is another measure of the magnitude of the image values. This feature is volumeconfounded, a larger value of \(c\) increases the effect of volumeconfounding.

getStandardDeviationFeatureValue
()[source]¶ 15. Standard Deviation
\[\textit{standard deviation} = \sqrt{\frac{1}{N}\sum^{N}_{i=1}{(\textbf{X}(i)\bar{X})^2}}\]Standard Deviation measures the amount of variation or dispersion from the Mean Value. By definition, :math:textit{standard deviation} = sqrt{textit{variance}}

getSkewnessFeatureValue
(axis=0)[source]¶ 16. Skewness
\[\textit{skewness} = \displaystyle\frac{\mu_3}{\sigma^3} = \frac{\frac{1}{N}\sum^{N}_{i=1}{(\textbf{X}(i)\bar{X})^3}} {\left(\sqrt{\frac{1}{N}\sum^{N}_{i=1}{(\textbf{X}(i)\bar{X})^2}}\right)^3}\]Where \(\mu_3\) is the 3^{rd} central moment.
Skewness measures the asymmetry of the distribution of values about the Mean value. Depending on where the tail is elongated and the mass of the distribution is concentrated, this value can be positive or negative.
Related links:
https://en.wikipedia.org/wiki/Skewness
Note
In case of a flat region, the standard deviation and 4^{rd} central moment will be both 0. In this case, a value of 0 is returned.

getKurtosisFeatureValue
(axis=0)[source]¶ 17. Kurtosis
\[\textit{kurtosis} = \displaystyle\frac{\mu_4}{\sigma^4} = \frac{\frac{1}{N}\sum^{N}_{i=1}{(\textbf{X}(i)\bar{X})^4}} {\left(\frac{1}{N}\sum^{N}_{i=1}{(\textbf{X}(i)\bar{X}})^2\right)^2}\]Where \(\mu_4\) is the 4^{th} central moment.
Kurtosis is a measure of the ‘peakedness’ of the distribution of values in the image ROI. A higher kurtosis implies that the mass of the distribution is concentrated towards the tail(s) rather than towards the mean. A lower kurtosis implies the reverse: that the mass of the distribution is concentrated towards a spike near the Mean value.
Related links:
https://en.wikipedia.org/wiki/Kurtosis
Note
In case of a flat region, the standard deviation and 4^{rd} central moment will be both 0. In this case, a value of 0 is returned.

getVarianceFeatureValue
()[source]¶ 18. Variance
\[\textit{variance} = \frac{1}{N}\displaystyle\sum^{N}_{i=1}{(\textbf{X}(i)\bar{X})^2}\]Variance is the the mean of the squared distances of each intensity value from the Mean value. This is a measure of the spread of the distribution about the mean. By definition, \(\textit{variance} = \sigma^2\)

getUniformityFeatureValue
()[source]¶ 19. Uniformity
\[\textit{uniformity} = \displaystyle\sum^{N_l}_{i=1}{p(i)^2}\]Uniformity is a measure of the sum of the squares of each intensity value. This is a measure of the heterogeneity of the image array, where a greater uniformity implies a greater heterogeneity or a greater range of discrete intensity values.
Shape Features¶

class
radiomics.shape.
RadiomicsShape
(inputImage, inputMask, **kwargs)[source]¶ Bases:
radiomics.base.RadiomicsFeaturesBase
In this group of features we included descriptors of the threedimensional size and shape of the ROI. These features are independent from the gray level intensity distribution in the ROI and are therefore only calculated on the nonderived image and mask.
Let:
 \(V\) the volume of the ROI in mm^{3}
 \(A\) the surface area of the ROI in mm^{2}

getVolumeFeatureValue
()[source]¶ 1. Volume
The volume of the ROI is approximated by multiplying the number of voxels in the ROI by the volume of a single voxel.

getSurfaceAreaFeatureValue
()[source]¶ 2. Surface Area
\[A = \displaystyle\sum^{N}_{i=1}{\frac{1}{2}\text{a}_i\text{b}_i \times \text{a}_i\text{c}_i}\]Where:
\(N\) is the number of triangles forming the surface mesh of the volume (ROI)
\(\text{a}_i\text{b}_i\) and \(\text{a}_i\text{c}_i\) are the edges of the \(i^{\text{th}}\) triangle formed by points \(\text{a}_i\), \(\text{b}_i\) and \(\text{c}_i\)
Surface Area is an approximation of the surface of the ROI in mm2, calculated using a marching cubes algorithm.
References:
 Lorensen WE, Cline HE. Marching cubes: A high resolution 3D surface construction algorithm. ACM SIGGRAPH Comput Graph Internet. 1987;21:1639.

getSurfaceVolumeRatioFeatureValue
()[source]¶ 3. Surface Area to Volum ratio
\[\textit{surface to volume ratio} = \frac{A}{V}\]Here, a lower value indicates a more compact (spherelike) shape. This feature is not dimensionless, and is therefore (partly) dependent on the volume of the ROI.

getSphericityFeatureValue
()[source]¶ 4. Sphericity
\[\textit{sphericity} = \frac{\sqrt[3]{36 \pi V^2}}{A}\]Sphericity is a measure of the roundness of the shape of the tumor region relative to a sphere. It is a dimensionless measure, independent of scale and orientation. The value range is \(0 < sphericity \leq 1\), where a value of 1 indicates a perfect sphere (a sphere has the smallest possible surface area for a given volume, compared to other solids).
Note
This feature is correlated to Compactness 1, Compactness 2 and Spherical Disproportion. In the default parameter file provided in the
pyradiomics/examples/exampleSettings
folder, Compactness 1 and Compactness 2 are therefore disabled.

getCompactness1FeatureValue
()[source]¶ 5. Compactness 1
\[\textit{compactness 1} = \frac{V}{\sqrt{\pi A^3}}\]Similar to Sphericity, Compactness 1 is a measure of how compact the shape of the tumor is relative to a sphere (most compact). It is therefore correlated to Sphericity and redundant. It is provided here for completeness. The value range is \(0 < compactness\ 1 \leq \frac{1}{6 \pi}\), where a value of \(\frac{1}{6 \pi}\) indicates a perfect sphere.
By definition, \(compactness\ 1 = \frac{1}{6 \pi}\sqrt{compactness\ 2} = \frac{1}{6 \pi}\sqrt{sphericity^3}\).
Note
This feature is correlated to Compactness 2, Sphericity and Spherical Disproportion. In the default parameter file provided in the
pyradiomics/examples/exampleSettings
folder, Compactness 1 and Compactness 2 are therefore disabled.

getCompactness2FeatureValue
()[source]¶ 6. Compactness 2
\[\textit{compactness 2} = 36 \pi \frac{V^2}{A^3}\]Similar to Sphericity and Compactness 1, Compactness 2 is a measure of how compact the shape of the tumor is relative to a sphere (most compact). It is a dimensionless measure, independent of scale and orientation. The value range is \(0 < compactness\ 2 \leq 1\), where a value of 1 indicates a perfect sphere.
By definition, \(compactness\ 2 = (sphericity)^3\)
Note
This feature is correlated to Compactness 1, Sphericity and Spherical Disproportion. In the default parameter file provided in the
pyradiomics/examples/exampleSettings
folder, Compactness 1 and Compactness 2 are therefore disabled.

getSphericalDisproportionFeatureValue
()[source]¶ 7. Spherical Disproportion
\[\textit{spherical disproportion} = \frac{A}{4\pi R^2} = \frac{A}{\sqrt[3]{36 \pi V^2}}\]Where \(R\) is the radius of a sphere with the same volume as the tumor, and equal to \(\sqrt[3]{\frac{3V}{4\pi}}\).
Spherical Disproportion is the ratio of the surface area of the tumor region to the surface area of a sphere with the same volume as the tumor region, and by definition, the inverse of Sphericity. Therefore, the value range is \(spherical\ disproportion \geq 1\), with a value of 1 indicating a perfect sphere.
Note
This feature is correlated to Compactness 1, Compactness 2 and Sphericity. In the default parameter file provided in the
pyradiomics/examples/exampleSettings
folder, Compactness 1 and Compactness 2 are therefore disabled.

getMaximum3DDiameterFeatureValue
()[source]¶ 8. Maximum 3D diameter
Maximum 3D diameter is defined as the largest pairwise Euclidean distance between surface voxels in the ROI.
Also known as Feret Diameter.
Warning
This feature is only available when C Extensions are enabled

getMaximum2DDiameterSliceFeatureValue
()[source]¶ 9. Maximum 2D diameter (Slice)
Maximum 2D diameter (Slice) is defined as the largest pairwise Euclidean distance between tumor surface voxels in the rowcolumn (generally the axial) plane.
Warning
This feature is only available when C Extensions are enabled

getMaximum2DDiameterColumnFeatureValue
()[source]¶ 10. Maximum 2D diameter (Column)
Maximum 2D diameter (Column) is defined as the largest pairwise Euclidean distance between tumor surface voxels in the rowslice (usually the coronal) plane.
Warning
This feature is only available when C Extensions are enabled

getMaximum2DDiameterRowFeatureValue
()[source]¶ 11. Maximum 2D diameter (Row)
Maximum 2D diameter (Row) is defined as the largest pairwise Euclidean distance between tumor surface voxels in the columnslice (usually the sagittal) plane.
Warning
This feature is only available when C Extensions are enabled

getMajorAxisFeatureValue
()[source]¶ 12. Major Axis
\[\textit{major axis} = 4 \sqrt{\lambda_{\text{major}}}\]

getMinorAxisFeatureValue
()[source]¶ 13. Minor Axis
\[\textit{minor axis} = 4 \sqrt{\lambda_{\text{minor}}}\]

getLeastAxisFeatureValue
()[source]¶ 14. Least Axis
\[\textit{least axis} = 4 \sqrt{\lambda_{\text{least}}}\]

getElongationFeatureValue
()[source]¶ 15. Elongation
Elongation is calculated using its implementation in SimpleITK, and is defined as:
\[\textit{elongation} = \sqrt{\frac{\lambda_{\text{minor}}}{\lambda_{\text{major}}}}\]Here, \(\lambda_{\text{major}}\) and \(\lambda_{\text{minor}}\) are the lengths of the largest and second largest principal component axes. The values range between 1 (where the cross section through the first and second largest principal moments is circlelike (nonelongated)) and 0 (where the object is a single point or 1 dimensional line).

getFlatnessFeatureValue
()[source]¶ 16. Flatness
Flatness is calculated using its implementation in SimpleITK, and is defined as:
\[\textit{flatness} = \sqrt{\frac{\lambda_{\text{least}}}{\lambda_{\text{major}}}}\]Here, \(\lambda_{\text{major}}\) and \(\lambda_{\text{least}}\) are the lengths of the largest and smallest principal component axes. The values range between 1 (nonflat, spherelike) and 0 (a flat object).
Gray Level Cooccurrence Matrix (GLCM) Features¶

class
radiomics.glcm.
RadiomicsGLCM
(inputImage, inputMask, **kwargs)[source]¶ Bases:
radiomics.base.RadiomicsFeaturesBase
A Gray Level Cooccurrence Matrix (GLCM) of size \(N_g \times N_g\) describes the secondorder joint probability function of an image region constrained by the mask and is defined as \(\textbf{P}(i,j\delta,\alpha)\). The \((i,j)^{\text{th}}\) element of this matrix represents the number of times the combination of levels \(i\) and \(j\) occur in two pixels in the image, that are separated by a distance of \(\delta\) pixels along angle \(\alpha\). The distance \(\delta\) from the center voxel is defined as the distance according to the infinity norm. For \(\delta=1\), this results in 2 neighbors for each of 13 angles in 3D (26connectivity) and for \(\delta=2\) a 98connectivity (49 unique angles).
Note that pyradiomics by default computes symmetrical GLCM!
As a two dimensional example, let the following matrix \(\textbf{I}\) represent a 5x5 image, having 5 discrete grey levels:
\[\begin{split}\textbf{I} = \begin{bmatrix} 1 & 2 & 5 & 2 & 3\\ 3 & 2 & 1 & 3 & 1\\ 1 & 3 & 5 & 5 & 2\\ 1 & 1 & 1 & 1 & 2\\ 1 & 2 & 4 & 3 & 5 \end{bmatrix}\end{split}\]For distance \(\delta = 1\) (considering pixels with a distance of 1 pixel from each other) and angle \(\alpha=0^\circ\) (horizontal plane, i.e. voxels to the left and right of the center voxel), the following symmetrical GLCM is obtained:
\[\begin{split}\textbf{P} = \begin{bmatrix} 6 & 4 & 3 & 0 & 0\\ 4 & 0 & 2 & 1 & 3\\ 3 & 2 & 0 & 1 & 2\\ 0 & 1 & 1 & 0 & 0\\ 0 & 3 & 2 & 0 & 2 \end{bmatrix}\end{split}\]Let:
 \(\epsilon\) be an arbitrarily small positive number (\(\approx 2.2\times10^{16}\))
 \(\textbf{P}(i,j)\) be the cooccurence matrix for an arbitrary \(\delta\) and \(\alpha\)
 \(p(i,j)\) be the normalized cooccurence matrix and equal to \(\frac{\textbf{P}(i,j)}{\sum{\textbf{P}(i,j)}}\)
 \(N_g\) be the number of discrete intensity levels in the image
 \(p_x(i) = \sum^{N_g}_{j=1}{P(i,j)}\) be the marginal row probabilities
 \(p_y(j) = \sum^{N_g}_{i=1}{P(i,j)}\) be the marginal column probabilities
 \(\mu_x\) be the mean gray level intensity of \(p_x\) and defined as \(\mu_x = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1}{p(i,j)i}\)
 \(\mu_y\) be the mean gray level intensity of \(p_y\) and defined as \(\mu_y = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1}{p(i,j)j}\)
 \(\sigma_x\) be the standard deviation of \(p_x\)
 \(\sigma_y\) be the standard deviation of \(p_y\)
 \(p_{x+y}(k) = \sum^{N_g}_{i=1}\sum^{N_g}_{j=1}{p(i,j)},\text{ where }i+j=k,\text{ and }k=2,3,\dots,2N_g\)
 \(p_{xy}(k) = \sum^{N_g}_{i=1}\sum^{N_g}_{j=1}{p(i,j)},\text{ where }ij=k,\text{ and }k=0,1,\dots,N_g1\)
 \(HX = \sum^{N_g}_{i=1}{p_x(i)\log_2\big(p_x(i)+\epsilon\big)}\) be the entropy of \(p_x\)
 \(HY = \sum^{N_g}_{j=1}{p_y(j)\log_2\big(p_y(j)+\epsilon\big)}\) be the entropy of \(p_y\)
 \(HXY = \sum^{N_g}_{i=1}\sum^{N_g}_{j=1}{p(i,j)\log_2\big(p(i,j)+\epsilon\big)}\) be the entropy of \(p(i,j)\)
 \(HXY1 = \sum^{N_g}_{i=1}\sum^{N_g}_{j=1}{p(i,j)\log_2\big(p_x(i)p_y(j)+\epsilon\big)}\)
 \(HXY2 = \sum^{N_g}_{i=1}\sum^{N_g}_{j=1}{p_x(i)p_y(j)\log_2\big(p_x(i)p_y(j)+\epsilon\big)}\)
By default, the value of a feature is calculated on the GLCM for each angle separately, after which the mean of these values is returned. If distance weighting is enabled, GLCM matrices are weighted by weighting factor W and then summed and normalised. Features are then calculated on the resultant matrix. Weighting factor W is calculated for the distance between neighbouring voxels by:
\(W = e^{\d\^2}\), where d is the distance for the associated angle according to the norm specified in setting ‘weightingNorm’.
The following class specific settings are possible:
symmetricalGLCM [True]: boolean, indicates whether cooccurrences should be assessed in two directions per angle, which results in a symmetrical matrix, with equal distributions for \(i\) and \(j\). A symmetrical matrix corresponds to the GLCM as defined by Haralick et al.
weightingNorm [None]: string, indicates which norm should be used when applying distance weighting. Enumerated setting, possible values:
 ‘manhattan’: first order norm
 ‘euclidean’: second order norm
 ‘infinity’: infinity norm.
 ‘no_weighting’: GLCMs are weighted by factor 1 and summed
 None: Applies no weighting, mean of values calculated on separate matrices is returned.
In case of other values, an warning is logged and option ‘no_weighting’ is used.
References
 Haralick, R., Shanmugan, K., Dinstein, I; Textural features for image classification; IEEE Transactions on Systems, Man and Cybernetics; 1973(3), p610621
 https://en.wikipedia.org/wiki/Cooccurrence_matrix
 http://www.fp.ucalgary.ca/mhallbey/the_glcm.htm

getAutocorrelationFeatureValue
()[source]¶ 1. Autocorrelation
\[\textit{autocorrelation} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1}{p(i,j)ij}\]Autocorrelation is a measure of the magnitude of the fineness and coarseness of texture.

getAverageIntensityFeatureValue
()[source]¶ 2. Joint Average
\[\mu_x = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1}{p(i,j)i}\]Returns the mean gray level intensity of the \(i\) distribution.
Warning
As this formula represents the average of the distribution of \(i\), it is independent from the distribution of \(j\). Therefore, only use this formula if the GLCM is symmetrical, where \(p_x(i) = p_y(j) \text{, where } i = j\).

getClusterProminenceFeatureValue
()[source]¶ 3. Cluster Prominence
\[\textit{cluster prominence} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1} {\big( i+j\mu_x(i)\mu_y(j)\big)^4p(i,j)}\]Cluster Prominence is a measure of the skewness and asymmetry of the GLCM. A higher values implies more asymmetry about the mean while a lower value indicates a peak near the mean value and less variation about the mean.

getClusterShadeFeatureValue
()[source]¶ 4. Cluster Shade
\[\textit{cluster shade} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1} {\big(i+j\mu_x(i)\mu_y(j)\big)^3p(i,j)}\]Cluster Shade is a measure of the skewness and uniformity of the GLCM. A higher cluster shade implies greater asymmetry about the mean.

getClusterTendencyFeatureValue
()[source]¶ 5. Cluster Tendency
\[\textit{cluster tendency} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1} {\big(i+j\mu_x(i)\mu_y(j)\big)^2p(i,j)}\]Cluster Tendency is a measure of groupings of voxels with similar graylevel values.

getContrastFeatureValue
()[source]¶ 6. Contrast
\[\textit{contrast} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1}{(ij)^2p(i,j)}\]Contrast is a measure of the local intensity variation, favoring values away from the diagonal \((i = j)\). A larger value correlates with a greater disparity in intensity values among neighboring voxels.

getCorrelationFeatureValue
()[source]¶ 7. Correlation
\[\textit{correlation} = \frac{\sum^{N_g}_{i=1}\sum^{N_g}_{j=1}{p(i,j)ij\mu_x(i)\mu_y(j)}}{\sigma_x(i)\sigma_y(j)}\]Correlation is a value between 0 (uncorrelated) and 1 (perfectly correlated) showing the linear dependency of gray level values to their respective voxels in the GLCM.
Note
When there is only 1 discreet gray value in the ROI (flat region), \(\sigma_x\) and \(\sigma_y\) will be 0. In this case, an arbitrary value of 1 is returned instead. This is assessed on a perangle basis.

getDifferenceAverageFeatureValue
()[source]¶ 8. Difference Average
\[\textit{difference average} = \displaystyle\sum^{N_g1}_{k=0}{kp_{xy}(k)}\]Difference Average measures the relationship between occurrences of pairs with similar intensity values and occurrences of pairs with differing intensity values.

getDifferenceEntropyFeatureValue
()[source]¶ 9. Difference Entropy
\[\textit{difference entropy} = \displaystyle\sum^{N_g1}_{k=0}{p_{xy}(k)\log_2\big(p_{xy}(k)+\epsilon\big)}\]Difference Entropy is a measure of the randomness/variability in neighborhood intensity value differences.

getDifferenceVarianceFeatureValue
()[source]¶ 10. Difference Variance
\[\textit{difference variance} = \displaystyle\sum^{N_g1}_{k=0}{(1DA)^2p_{xy}(k)}\]Difference Variance is a measure of heterogeneity that places higher weights on differing intensity level pairs that deviate more from the mean.

getDissimilarityFeatureValue
()[source]¶ 11. Dissimilarity
\[\textit{dissimilarity} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1}{ijp(i,j)}\]Dissimilarity is a measure of local intensity variation defined as the mean absolute difference between the neighbouring pairs. A larger value correlates with a greater disparity in intensity values among neighboring voxels.

getEnergyFeatureValue
()[source]¶ 12. Joint Energy
\[\textit{energy} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1}{\big(p(i,j)\big)^2}\]Energy (or Angular Second Moment)is a measure of homogeneous patterns in the image. A greater Energy implies that there are more instances of intensity value pairs in the image that neighbor each other at higher frequencies.

getEntropyFeatureValue
()[source]¶ 13. Joint Entropy
\[\textit{entropy} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1} {p(i,j)\log_2\big(p(i,j)+\epsilon\big)}\]Entropy is a measure of the randomness/variability in neighborhood intensity values.

getHomogeneity1FeatureValue
()[source]¶ 14. Homogeneity 1
\[\textit{homogeneity 1} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1}{\frac{p(i,j)}{1+ij}}\]Homogeneity 1 is a measure of the similarity in intensity values for neighboring voxels. It is a measure of local homogeneity that increases with less contrast in the window.

getHomogeneity2FeatureValue
()[source]¶ 15. Homogeneity 2
\[\textit{homogeneity 2} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1}{\frac{p(i,j)}{1+ij^2}}\]Homogeneity 2 is a measure of the similarity in intensity values for neighboring voxels.

getImc1FeatureValue
()[source]¶ 16. Informal Measure of Correlation (IMC) 1
\[\textit{IMC 1} = \frac{HXYHXY1}{\max\{HX,HY\}}\]Note
In the case where both HX and HY are 0 (as is the case in a flat region), an arbitrary value of 0 is returned to prevent a division by 0. This is done on a perangle basis

getImc2FeatureValue
()[source]¶ 17. Informal Measure of Correlation (IMC) 2
\[\textit{IMC 2} = \sqrt{1e^{2(HXY2HXY)}}\]Note
In the case where HXY = HXY2, an arbitrary value of 0 is returned to prevent returning complex numbers. This is done on a perangle basis.

getIdmFeatureValue
()[source]¶ 18. Inverse Difference Moment (IDM)
\[\textit{IDM} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1}{ \frac{p(i,j)}{1+ij^2} }\]IDM (inverse difference moment) is a measure of the local homogeneity of an image. IDM weights are the inverse of the Contrast weights (decreasing exponentially from the diagonal i=j in the GLCM).

getIdmnFeatureValue
()[source]¶ 19. Inverse Difference Moment Normalized (IDMN)
\[\textit{IDMN} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1} { \frac{p(i,j)}{1+\left(\frac{ij^2}{N_g^2}\right)} }\]IDMN (inverse difference moment normalized) is a measure of the local homogeneity of an image. IDMN weights are the inverse of the Contrast weights (decreasing exponentially from the diagonal \(i=j\) in the GLCM). Unlike Homogeneity2, IDMN normalizes the square of the difference between neighboring intensity values by dividing over the square of the total number of discrete intensity values.

getIdFeatureValue
()[source]¶ 20. Inverse Difference (ID)
\[\textit{ID} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1}{ \frac{p(i,j)}{1+ij} }\]ID (inverse difference) is another measure of the local homogeneity of an image. With more uniform gray levels, the denominator will remain low, resulting in a higher overall value.

getIdnFeatureValue
()[source]¶ 21. Inverse Difference Normalized (IDN)
\[\textit{IDN} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1} { \frac{p(i,j)}{1+\left(\frac{ij}{N_g}\right)} }\]IDN (inverse difference normalized) is another measure of the local homogeneity of an image. Unlike Homogeneity1, IDN normalizes the difference between the neighboring intensity values by dividing over the total number of discrete intensity values.

getInverseVarianceFeatureValue
()[source]¶ 22. Inverse Variance
\[\textit{inverse variance} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1}{\frac{p(i,j)}{ij^2}}, i \neq j\]

getMaximumProbabilityFeatureValue
()[source]¶ 23. Maximum Probability
\[\textit{maximum probability} = \max\big(p(i,j)\big)\]Maximum Probability is occurrences of the most predominant pair of neighboring intensity values.

getSumAverageFeatureValue
()[source]¶ 24. Sum Average
\[\textit{sum average} = \displaystyle\sum^{2N_g}_{k=2}{p_{x+y}(k)k}\]Sum Average measures the relationship between occurrences of pairs with lower intensity values and occurrences of pairs with higher intensity values.

getSumEntropyFeatureValue
()[source]¶ 25. Sum Entropy
\[\textit{sum entropy} = \displaystyle\sum^{2N_g}_{k=2}{p_{x+y}(k)\log_2\big(p_{x+y}(k)+\epsilon\big)}\]Sum Entropy is a sum of neighborhood intensity value differences.

getSumVarianceFeatureValue
()[source]¶ 26. Sum Variance
\[\textit{sum variance} = \displaystyle\sum^{2N_g}_{k=2}{(kSA)^2p_{x+y}(k)}\]Sum Variance is a measure of heterogeneity that places higher weights on neighboring intensity level pairs that deviate more from the mean.

getSumSquaresFeatureValue
()[source]¶ 27. Sum of Squares
\[\textit{sum squares} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_g}_{j=1}{(i\mu_x)^2p(i,j)}\]Sum of Squares or Variance is a measure in the distribution of neigboring intensity level pairs about the mean intensity level in the GLCM.
Warning
This formula represents the variance of the distribution of \(i\) and is independent from the distribution of \(j\). Therefore, only use this formula if the GLCM is symmetrical, where \(p_x(i) = p_y(j) \text{, where } i = j\)
Gray Level Size Zone Matrix (GLSZM) Features¶

class
radiomics.glszm.
RadiomicsGLSZM
(inputImage, inputMask, **kwargs)[source]¶ Bases:
radiomics.base.RadiomicsFeaturesBase
A Gray Level Size Zone (GLSZM) quantifies gray level zones in an image. A gray level zone is defined as a the number of connected voxels that share the same gray level intensity. A voxel is considered connected if the distance is 1 according to the infinity norm (26connected region in a 3D, 8connected region in 2D). In a gray level size zone matrix \(P(i,j)\) the \((i,j)^{\text{th}}\) element equals the number of zones with gray level \(i\) and size \(j\) appear in image. Contrary to GLCM and GLRLM, the GLSZM is rotation independent, with only one matrix calculated for all directions in the ROI.
As a two dimensional example, consider the following 5x5 image, with 5 discrete gray levels:
\[\begin{split}\textbf{I} = \begin{bmatrix} 5 & 2 & 5 & 4 & 4\\ 3 & 3 & 3 & 1 & 3\\ 2 & 1 & 1 & 1 & 3\\ 4 & 2 & 2 & 2 & 3\\ 3 & 5 & 3 & 3 & 2 \end{bmatrix}\end{split}\]The GLSZM then becomes:
\[\begin{split}\textbf{P} = \begin{bmatrix} 0 & 0 & 0 & 1 & 0\\ 1 & 0 & 0 & 0 & 1\\ 1 & 0 & 1 & 0 & 1\\ 1 & 1 & 0 & 0 & 0\\ 3 & 0 & 0 & 0 & 0 \end{bmatrix}\end{split}\]Let:
 \(\textbf{P}(i,j)\) be the size zone matrix
 \(p(i,j)\) be the normalized size zone matrix, defined as \(p(i,j) = \frac{\textbf{P}(i,j)}{\sum{\textbf{P}(i,j)}}\)
 \(N_g\) be the number of discreet intensity values in the image
 \(N_s\) be the number of discreet zone sizes in the image
 \(N_p\) be the number of voxels in the image
Note
The mathematical formulas that define the GLSZM features correspond to the definitions of features extracted from the GLRLM.
References
 Guillaume Thibault; Bernard Fertil; Claire Navarro; Sandrine Pereira; Pierre Cau; Nicolas Levy; Jean Sequeira; JeanLuc Mari (2009). “Texture Indexes and Gray Level Size Zone Matrix. Application to Cell Nuclei Classification”. Pattern Recognition and Information Processing (PRIP): 140145.
 https://en.wikipedia.org/wiki/Gray_level_size_zone_matrix

getSmallAreaEmphasisFeatureValue
()[source]¶ 1. Small Area Emphasis (SAE)
\[\textit{SAE} = \frac{\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\frac{\textbf{P}(i,j)}{j^2}}} {\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\textbf{P}(i,j)}}\]SAE is a measure of the distribution of small size zones, with a greater value indicative of more smaller size zones and more fine textures.

getLargeAreaEmphasisFeatureValue
()[source]¶ 2. Large Area Emphasis (LAE)
\[\textit{LAE} = \frac{\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\textbf{P}(i,j)j^2}} {\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\textbf{P}(i,j)}}\]LAE is a measure of the distribution of large area size zones, with a greater value indicative of more larger size zones and more coarse textures.

getGrayLevelNonUniformityFeatureValue
()[source]¶ 3. Gray Level NonUniformity (GLN)
\[\textit{GLN} = \frac{\sum^{N_g}_{i=1}\left(\sum^{N_s}_{j=1}{\textbf{P}(i,j)}\right)^2} {\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\textbf{P}(i,j)}}\]GLN measures the variability of graylevel intensity values in the image, with a lower value indicating more homogeneity in intensity values.

getGrayLevelNonUniformityNormalizedFeatureValue
()[source]¶ 4. Gray Level NonUniformity Normalized (GLNN)
\[\textit{GLNN} = \frac{\sum^{N_g}_{i=1}\left(\sum^{N_s}_{j=1}{\textbf{P}(i,j)}\right)^2} {\sum^{N_g}_{i=1}\sum^{N_d}_{j=1}{\textbf{P}(i,j)}^2}\]GLNN measures the variability of graylevel intensity values in the image, with a lower value indicating a greater similarity in intensity values. This is the normalized version of the GLN formula.

getSizeZoneNonUniformityFeatureValue
()[source]¶ 5. SizeZone NonUniformity (SZN)
\[\textit{SZN} = \frac{\sum^{N_s}_{j=1}\left(\sum^{N_g}_{i=1}{\textbf{P}(i,j)}\right)^2} {\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\textbf{P}(i,j)}}\]SZN measures the variability of size zone volumes in the image, with a lower value indicating more homogeneity in size zone volumes.

getSizeZoneNonUniformityNormalizedFeatureValue
()[source]¶ 6. SizeZone NonUniformity Normalized (SZNN)
\[\textit{SZNN} = \frac{\sum^{N_s}_{j=1}\left(\sum^{N_g}_{i=1}{\textbf{P}(i,j)}\right)^2} {\sum^{N_g}_{i=1}\sum^{N_d}_{j=1}{\textbf{P}(i,j)}^2}\]SZNN measures the variability of size zone volumes throughout the image, with a lower value indicating more homogeneity among zone size volumes in the image. This is the normalized version of the SZN formula.

getZonePercentageFeatureValue
()[source]¶ 7. Zone Percentage (ZP)
\[\textit{ZP} = \sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\frac{\textbf{P}(i,j)}{N_p}}\]ZP measures the coarseness of the texture by taking the ratio of number of zones and number of voxels in the ROI.
Values are in range \(\frac{1}{N_p} \leq ZP \leq 1\), with higher values indicating a larger portion of the ROI consists of small zones (indicates a more fine texture).

getGrayLevelVarianceFeatureValue
()[source]¶ 8. Gray Level Variance (GLV)
\[\textit{GLV} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_s}_{j=1}{p(i,j)(i  \mu)^2}\]Here, \(\mu = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_s}_{j=1}{p(i,j)i}\)
GLV measures the variance in gray level intensities for the zones.

getZoneVarianceFeatureValue
()[source]¶ 9. Zone Variance (ZV)
\[\textit{ZV} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_s}_{j=1}{p(i,j)(j  \mu)^2}\]Here, \(\mu = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_s}_{j=1}{p(i,j)j}\)
ZV measures the variance in zone size volumes for the zones.

getZoneEntropyFeatureValue
()[source]¶ 10. Zone Entropy (ZE)
\[\textit{ZE} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_s}_{j=1}{p(i,j)\log_{2}(p(i,j)+\epsilon)}\]Here, \(\epsilon\) is an arbitrarily small positive number (\(\approx 2.2\times10^{16}\)).
ZE measures the uncertainty/randomness in the distribution of zone sizes and gray levels. A higher value indicates more heterogeneneity in the texture patterns.

getLowGrayLevelZoneEmphasisFeatureValue
()[source]¶ 11. Low Gray Level Zone Emphasis (LGLZE)
\[\textit{LGLZE} = \frac{\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\frac{\textbf{P}(i,j)}{i^2}}} {\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\textbf{P}(i,j)}}\]LGLZE measures the distribution of lower graylevel size zones, with a higher value indicating a greater proportion of lower graylevel values and size zones in the image.

getHighGrayLevelZoneEmphasisFeatureValue
()[source]¶ 12. High Gray Level Zone Emphasis (HGLZE)
\[\textit{HGLZE} = \frac{\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\textbf{P}(i,j)i^2}} {\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\textbf{P}(i,j)}}\]HGLZE measures the distribution of the higher graylevel values, with a higher value indicating a greater proportion of higher graylevel values and size zones in the image.

getSmallAreaLowGrayLevelEmphasisFeatureValue
()[source]¶ 13. Small Area Low Gray Level Emphasis (SALGLE)
\[\textit{SALGLE} = \frac{\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\frac{\textbf{P}(i,j)}{i^2j^2}}} {\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\textbf{P}(i,j)}}\]SALGLE measures the proportion in the image of the joint distribution of smaller size zones with lower graylevel values.

getSmallAreaHighGrayLevelEmphasisFeatureValue
()[source]¶ 14. Small Area High Gray Level Emphasis (SAHGLE)
\[\textit{SAHGLE} = \frac{\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\frac{\textbf{P}(i,j)i^2}{j^2}}} {\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\textbf{P}(i,j)}}\]SAHGLE measures the proportion in the image of the joint distribution of smaller size zones with higher graylevel values.

getLargeAreaLowGrayLevelEmphasisFeatureValue
()[source]¶ 15. Large Area Low Gray Level Emphasis (LALGLE)
\[\textit{LALGLE} = \frac{\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\frac{\textbf{P}(i,j)j^2}{i^2}}} {\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\textbf{P}(i,j)}}\]LALGLE measures the proportion in the image of the joint distribution of larger size zones with lower graylevel values.

getLargeAreaHighGrayLevelEmphasisFeatureValue
()[source]¶ 16. Large Area High Gray Level Emphasis (LAHGLE)
\[\textit{LAHGLE} = \frac{\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\textbf{P}(i,j)i^2j^2}} {\sum^{N_g}_{i=1}\sum^{N_s}_{j=1}{\textbf{P}(i,j)}}\]LAHGLE measures the proportion in the image of the joint distribution of larger size zones with higher graylevel values.
Gray Level Run Length Matrix (GLRLM) Features¶

class
radiomics.glrlm.
RadiomicsGLRLM
(inputImage, inputMask, **kwargs)[source]¶ Bases:
radiomics.base.RadiomicsFeaturesBase
A Gray Level Run Length Matrix (GLRLM) quantifies gray level runs, which are defined as the length in number of pixels, of consecutive pixels that have the same gray level value. In a gray level run length matrix \(\textbf{P}(i,j\theta)\), the \((i,j)^{\text{th}}\) element describes the number of runs with gray level \(i\) and length \(j\) occur in the image (ROI) along angle \(\theta\).
As a two dimensional example, consider the following 5x5 image, with 5 discrete gray levels:
\[\begin{split}\textbf{I} = \begin{bmatrix} 5 & 2 & 5 & 4 & 4\\ 3 & 3 & 3 & 1 & 3\\ 2 & 1 & 1 & 1 & 3\\ 4 & 2 & 2 & 2 & 3\\ 3 & 5 & 3 & 3 & 2 \end{bmatrix}\end{split}\]The GLRLM for \(\theta = 0\), where 0 degrees is the horizontal direction, then becomes:
\[\begin{split}\textbf{P} = \begin{bmatrix} 1 & 0 & 1 & 0 & 0\\ 3 & 0 & 1 & 0 & 0\\ 4 & 1 & 1 & 0 & 0\\ 1 & 1 & 0 & 0 & 0\\ 3 & 0 & 0 & 0 & 0 \end{bmatrix}\end{split}\]Let:
 \(\textbf{P}(i,j\theta)\) be the run length matrix for an arbitrary direction \(\theta\)
 \(p(i,j\theta)\) be the normalized run length matrix, defined as \(p(i,j\theta) = \frac{\textbf{P}(i,j\theta)}{\sum{\textbf{P}(i,j\theta)}}\)
 \(N_g\) be the number of discreet intensity values in the image
 \(N_r\) be the number of discreet run lengths in the image
 \(N_p\) be the number of voxels in the image
By default, the value of a feature is calculated on the GLRLM for each angle separately, after which the mean of these values is returned. If distance weighting is enabled, GLRLMs are weighted by the distance between neighbouring voxels and then summed and normalised. Features are then calculated on the resultant matrix. The distance between neighbouring voxels is calculated for each angle using the norm specified in ‘weightingNorm’.
The following class specific settings are possible:
weightingNorm [None]: string, indicates which norm should be used when applying distance weighting. Enumerated setting, possible values:
 ‘manhattan’: first order norm
 ‘euclidean’: second order norm
 ‘infinity’: infinity norm.
 ‘no_weighting’: GLCMs are weighted by factor 1 and summed
 None: Applies no weighting, mean of values calculated on separate matrices is returned.
In case of other values, an warning is logged and option ‘no_weighting’ is used.
References
 Galloway MM. 1975. Texture analysis using gray level run lengths. Computer Graphics and Image Processing, 4(2):172179.
 Chu A., Sehgal C.M., Greenleaf J. F. 1990. Use of gray value distribution of run length for texture analysis. Pattern Recognition Letters, 11(6):415419
 Xu D., Kurani A., Furst J., Raicu D. 2004. RunLength Encoding For Volumetric Texture. International Conference on Visualization, Imaging and Image Processing (VIIP), p. 452458
 Tang X. 1998. Texture information in runlength matrices. IEEE Transactions on Image Processing 7(11):16021609.
 Tustison N., Gee J. RunLength Matrices For Texture Analysis. Insight Journal 2008 January  June.

getShortRunEmphasisFeatureValue
()[source]¶ 1. Short Run Emphasis (SRE)
\[\textit{SRE} = \frac{\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\frac{\textbf{P}(i,j\theta)}{j^2}}} {\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)}}\]SRE is a measure of the distribution of short run lengths, with a greater value indicative of shorter run lengths and more fine textural textures.

getLongRunEmphasisFeatureValue
()[source]¶ 2. Long Run Emphasis (LRE)
\[\textit{LRE} = \frac{\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)j^2}} {\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)}}\]LRE is a measure of the distribution of long run lengths, with a greater value indicative of longer run lengths and more coarse structural textures.

getGrayLevelNonUniformityFeatureValue
()[source]¶ 3. Gray Level NonUniformity (GLN)
\[\textit{GLN} = \frac{\sum^{N_g}_{i=1}\left(\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)}\right)^2} {\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)}}\]GLN measures the similarity of graylevel intensity values in the image, where a lower GLN value correlates with a greater similarity in intensity values.

getGrayLevelNonUniformityNormalizedFeatureValue
()[source]¶ 4. Gray Level NonUniformity Normalized (GLNN)
\[\textit{GLNN} = \frac{\sum^{N_g}_{i=1}\left(\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)}\right)^2} {\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)}^2}\]GLNN measures the similarity of graylevel intensity values in the image, where a lower GLNN value correlates with a greater similarity in intensity values. This is the normalized version of the GLN formula.

getRunLengthNonUniformityFeatureValue
()[source]¶ 5. Run Length NonUniformity (RLN)
\[\textit{RLN} = \frac{\sum^{N_r}_{j=1}\left(\sum^{N_g}_{i=1}{\textbf{P}(i,j\theta)}\right)^2} {\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)}}\]RLN measures the similarity of run lengths throughout the image, with a lower value indicating more homogeneity among run lengths in the image.

getRunLengthNonUniformityNormalizedFeatureValue
()[source]¶ 6. Run Length NonUniformity Normalized (RLNN)
\[\textit{RLNN} = \frac{\sum^{N_r}_{j=1}\left(\sum^{N_g}_{i=1}{\textbf{P}(i,j\theta)}\right)^2} {\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)}}\]RLNN measures the similarity of run lengths throughout the image, with a lower value indicating more homogeneity among run lengths in the image. This is the normalized version of the RLN formula.

getRunPercentageFeatureValue
()[source]¶ 7. Run Percentage (RP)
\[\textit{RP} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_r}_{j=1}{\frac{\textbf{P}(i,j\theta)}{N_p}}\]RP measures the coarseness of the texture by taking the ratio of number of runs and number of voxels in the ROI.
Values are in range \(\frac{1}{N_p} \leq RP \leq 1\), with higher values indicating a larger portion of the ROI consists of short runs (indicates a more fine texture).

getGrayLevelVarianceFeatureValue
()[source]¶ 8. Gray Level Variance (GLV)
\[\textit{GLV} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_r}_{j=1}{p(i,j\theta)(i  \mu)^2}\]Here, \(\mu = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_r}_{j=1}{p(i,j\theta)i}\)
GLV measures the variance in gray level intensity for the runs.

getRunVarianceFeatureValue
()[source]¶ 9. Run Variance (RV)
\[\textit{RV} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_r}_{j=1}{p(i,j\theta)(j  \mu)^2}\]Here, \(\mu = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_r}_{j=1}{p(i,j\theta)j}\)
RV is a measure of the variance in runs for the run lengths.

getRunEntropyFeatureValue
()[source]¶ 10. Run Entropy (RE)
\[\textit{RE} = \displaystyle\sum^{N_g}_{i=1}\displaystyle\sum^{N_r}_{j=1} {p(i,j\theta)\log_{2}(p(i,j\theta)+\epsilon)}\]Here, \(\epsilon\) is an arbitrarily small positive number (\(\approx 2.2\times10^{16}\)).
RE measures the uncertainty/randomness in the distribution of run lengths and gray levels. A higher value indicates more heterogeneity in the texture patterns.

getLowGrayLevelRunEmphasisFeatureValue
()[source]¶ 11. Low Gray Level Run Emphasis (LGLRE)
\[\textit{LGLRE} = \frac{\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\frac{\textbf{P}(i,j\theta)}{i^2}}} {\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)}}\]LGLRE measures the distribution of low graylevel values, with a higher value indicating a greater concentration of low graylevel values in the image.

getHighGrayLevelRunEmphasisFeatureValue
()[source]¶ 12. High Gray Level Run Emphasis (HGLRE)
\[\textit{HGLRE} = \frac{\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)i^2}} {\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)}}\]HGLRE measures the distribution of the higher graylevel values, with a higher value indicating a greater concentration of high graylevel values in the image.

getShortRunLowGrayLevelEmphasisFeatureValue
()[source]¶ 13. Short Run Low Gray Level Emphasis (SRLGLE)
\[\textit{SRLGLE} = \frac{\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\frac{\textbf{P}(i,j\theta)}{i^2j^2}}} {\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)}}\]SRLGLE measures the joint distribution of shorter run lengths with lower graylevel values.

getShortRunHighGrayLevelEmphasisFeatureValue
()[source]¶ 14. Short Run High Gray Level Emphasis (SRHGLE)
\[\textit{SRHGLE} = \frac{\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\frac{\textbf{P}(i,j\theta)i^2}{j^2}}} {\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)}}\]SRHGLE measures the joint distribution of shorter run lengths with higher graylevel values.

getLongRunLowGrayLevelEmphasisFeatureValue
()[source]¶ 15. Long Run Low Gray Level Emphasis (LRLGLE)
\[\textit{LRLGLRE} = \frac{\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\frac{\textbf{P}(i,j\theta)j^2}{i^2}}} {\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)}}\]LRLGLRE measures the joint distribution of long run lengths with lower graylevel values.

getLongRunHighGrayLevelEmphasisFeatureValue
()[source]¶ 16. Long Run High Gray Level Emphasis (LRHGLE)
\[\textit{LRHGLRE} = \frac{\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)i^2j^2}} {\sum^{N_g}_{i=1}\sum^{N_r}_{j=1}{\textbf{P}(i,j\theta)}}\]LRHGLRE measures the joint distribution of long run lengths with higher graylevel values.
Developers¶
This section contains information on how to add or customize the feature classes and filters available in PyRadiomics.
PyRadiomics enumerates the available feature classes and input image types at initialization of the toolbox. These are
available from the global radiomics
namespace by use of the functions getFeatureClasses()
and
getInputImageTypes()
, respectively. Individual features in a feature class are enumerated at
initialization of the class. See also the
contributing guidelines
Signature of a feature class¶
Each feature class is defined in a separate module, the module name is used as the feature class name (e.g. if module tex.py matches the feature class signature, it is available in the PyRadiomics toolbox as the ‘tex’ feature class). In the module a class should be defined that fits the following signature:
[required imports]
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]
 At the top should be the import statements for packages required by the feature class. Unused import statements should be removed (flake8 will fail if unused import statements are encountered, or import statements are not structured as defined by appnexus).
 The class name should be ‘Radiomics’ followed by the name of the class (usually similar to the module name. However, this name is not used elsewhere and may be named arbitrarily).
 The class should inherit (directly or indirectly) from
base.RadiomicsFeaturesBase
, which is an abstract class defining the common interface for the feature classes  Additional initialization steps should be called in the
__init__
function. For default variables initialized, see Feature Class Base.  Documentation is required! Both at the class level (Feature class docstring) and at the level of the individual features (Feature docstring).
 If the feature class uses C extensions for matrix calculation enhancement, which should be tested using
test_cmatrices
, matrix calculation should be implemented as follows: The function calculating the matrix in python should be defined in a function called
_calculateMatrix
.  The function calculating the matrix using the C extension should be defined in a function called
_calculateCMatrix
.  The functions to calculate the matrix accept no additional input arguments other than the
self
argument, and return the fully processed matrix as a numpy array.  The fully processed matrix should be assigned to a variable in the feature class named
P_[Name]
, where[Name]
is identical to the feature class name (module name) (e.g. in feature classglcm
, matrix is stored in variableP_glcm
 The function calculating the matrix in python should be defined in a function called
 A feature class specific logger is created by the base class, which will be a child logger (i.e. the ‘radiomics.tex’
logger in case of the feature class ‘tex’). It is exposed in the feature class as
self.logger
. Any log messages generated by the feature class should make use of this logger to ensure that the hierarchy of classes is correctly reflected in generated logs (i.e.self.logger.debug('message')
to generate a debug log message).
Signature of individual features¶
Each individual feature is defined as a function in the feature class with the get[Name]FeatureValue(self)
signature, where [Name]
is the feature name (unique on the feature class level). It accepts no input arguments, and
should return a scalar value. The self
argument represents the instantiated feature class that defines the function,
and identifies the feature function as nonstatic.
Signature of a filter¶
All filters are defined in the imageoperations module, and identified by the
signature get[Name]Image(inputImage, **kwargs)
. Here, [Name]
represents the unique name for the image type,
which is also used to identify the filter during extraction. The input of a filter is fixed and consists of the
inputImage
, a SimpleITK Image object of the original image and **kwargs
, which are the customized setting that
should be used for the extraction of features from the derived image.
One or more derived images are returned using the ‘yield’ statement: yield derivedImage, inputImageName, kwargs
.
Here, derivedImage
is one SimpleITK image object representing the filtered imag
e, inputImageName
is a unique
string identifying features calculated using this filter in the output and kwargs
are the customized settings for
the extraction (**kwargs
passed as input, without the double asterisk). Multiple derived images can be
returned by multiple yield statements, or yield statements inside a loop. Please note that only one derived image should
be returned on each call to yield and that inputImageName
is a unique name for each returned derived image. Derived
images must have the same dimensions and occupy the same physical space to ensure compatibility with the mask.
Progress Reporting¶
When operating in fullpython mode, the calculation of the texture matrices can take some time. Therefor PyRadiomics
provides the possibility to report the progress for calculation of GLCM and GLSZM.
This is only enabled in fullpython mode when the verbosity (setVerbosity()
) is set to INFO or
DEBUG. By default, none is provided and no progress of matrix calculation will be reported.
To enable progress reporting, the radiomics.progressReporter
variable should be set to a class object (NOT an
instance), which fits the following signature:
 Accepts an iterable as the first positional argument and a keyword argument (‘desc’) specifying a label to display
 Can be used in a ‘with’ statement (i.e. exposes a
__enter__
and__exit__
function)  Is iterable (i.e. at least specifies an
__iter__
function, which iterates over the iterable passed at initialization)
It is also possible to create your own progress reporter. To achieve this, additionally specify a function __next__
,
and have the __iter__
function return self
. The __next__
function takes no arguments and returns a call to
the __next__
function of the iterable (i.e. return self.iterable.__next__()
). Any prints/progress reporting
calls can then be inserted in this function prior to the return statement.
In radiomics\__init__.py
a dummy progress reporter (_DummyProgressReporter
) is defined, which is used when
calculating in fullpython mode, but progress reporting is not enabled (verbosity > INFO) or the progressReporter
variable is not set.
To design a custom progress reporter, the following code can be adapted and used as progressReporter:
class MyProgressReporter(object):
def __init__(self, iterable, desc=''):
self.desc = desc # A description is which describes the progress that is reported
self.iterable = iterable # Iterable is required
# This function identifies the class as iterable and should return an object which exposes
# the __next__ function that should be used to iterate over the object
def __iter__(self):
return self # return self to 'intercept' the calls to __next__ to insert reporting code.
def __next__(self):
nextElement = self.iterable.__next__()
# Insert custom progress reporting code here. This is called for every iteration in the loop
# (once for each unique gray level in the ROI for GLCM and GLSZM)
# By inserting after the call `self.iterable.__next__()` the function will exit before the
# custom code is run when the stopIteration error is raised.
return nextElement
# This function is called when the 'with' statement is entered
def __enter__(self):
print (self.desc) # Print out the description upon start of the loop
return self # The __enter__ function should return itself
# This function is called when the 'with' statement is exited
def __exit__(self, exc_type, exc_value, tb):
pass # If nothing needs to be closed or handled, so just specify 'pass'
Addtional points for attention¶
Code style¶
To keep the PyRadiomics code consistent and as readable as possible, some style rules are enforced. These are part of
the continuous testing and implemented using flake8. See also the .flake8
configuration file in the root of the
repository. To aid in keeping a consistent code style, a .editorconfig
file is provided in the root of the folder.
Module names should be lowercase, without underscores or spaces. Class names, function names and variables should be declared using camelcase, with uppercase first letter for class names and lowercase first letter otherwise. Private helper functions (which should not be included in the documentation) should be declared using a ‘_’ prefix. This is consistent with the python style for marking them as ‘private’, and will automatically exclude them from the generated documentation.
Documentation¶
The documentation of PyRadiomics is autogenerated from static files contained in the docs
folder and the docstrings
of the Python code files. When a new feature class is added, this has to be added to the static file (features.rst
)
describing the feature classes as well. If done so, sphinx will take care of the rest. A featureclass can be added as
follows:
<Class Name> Features

.. automodule:: radiomics.<module name>
:members:
:undocmembers:
:showinheritance:
:memberorder: bysource
Documentation providing information of the feature class as a whole (e.g. how the feature matrix is calculated) should be provided in the docstring of the class. Definition of individual features, including the mathematical formulas should be provided in the docstrings of the feature functions. A docstring of the module is not required.
The presence of a docstring at the class level and at the level of each individual feature is required and checked during testing. Missing docstrings will cause the test to fail.
Testing¶
To ensure consistency in the extraction provided by PyRadiomics, continuous testing is used to test the PyRadiomics source code after each commit. These tests are defined in the test folder and used to run tests for the following environments:
 Python 2.7 32 and 64 bits (Windows, Linux and Mac)
 Python 3.4 32 and 64 bits (Windows and Linux)
 Python 3.5 32 and 64 bits (Windows and Linux)
Note
Python 3 testing for mac is currently disabled for Mac due to some issues with the SimpleITK package for python 3.
There are 3 testing scripts run for PyRadiomics. The first test is test_cmatrices
, which asserts if the matrices
calculated by the C extensions match those calculated by Python. A threshold of 1e3 is used to allow for machine
precision errors. The second test is test_docstrings
, which asserts if there is missing documentation as described
above. The final and most important test is test_features
, which compares the features calculated by PyRadiomics
against a known baseline using 5 test cases. These test cases and the baseline are stored in the data
folder of the
repository. This ensures that changes to the code do not silently change the calculated values of the features.
To add a new feature class to the baseline, run the addClassToBaseline.py
script, contained in the bin
folder.
This script detects if there are feature classes in PyRadiomics, for which there is no baseline available. If any are
found, a new baseline if calculated for these classes in the fullpython mode and added to the baseline files. These new
baseline files then needed to be included in the repository and committed.
Frequently Asked Questions¶
Installation¶
During setup, python is unable to compile the C extensions.¶
This can occur when no compiler is available for python. If you’re installing on Windows, you can find free compilers for python here.
Error loading C extensions.¶
I installed PyRadiomics successfully from the repository, but when I run the notebook, I get Error loading C extensions, switching to python calculation
When PyRadiomics is installed, the C extensions are compiled and copied to the installation folder, by default the
sitepackages
folder. However, when the notebook is run form the repository, it is possible that PyRadiomics uses
the source code directly (i.e. runs in development mode). You can check this by checking the radiomics.__path__
field, which will be something like ['radiomics']
when it is running in development mode and
['path/to/python/Lib/sitepackages']
when running from the installed folder. If running in development mode, the C
extensions are not available by default. To make them available in development mode, run python setup.py develop
from the commandline, which is similar to the install
command, but installs pyradiomics to the source folder
instead (i.e. does nothing to the python files, but compiles the C extensions and copies them to the source folder).
Which python versions is PyRadiomics compatible with?¶
PyRadiomics is compatible with both python 2 and python 3. The automated testing uses python versions 2.7, 3.4 and 3.5 (both 32 and 64 bits). Python < 2.6 is not supported. Other python versions may be compatible with PyRadiomics, but this is not actively tested and therefore not guaranteed to work.
Input / Customization¶
I want to customize my extraction. How do I do that?¶
See also Customizing the Extraction. PyRadiomics can be customized in various ways, but it’s most easy to do this by providing a parameter file. In this yaml structured text file you can define your custom settings and which features and input image types to enable.
Error loading parameter file¶
When I try to load my own parameter file, I get error:”CoreError: Unable to load any data from source yaml file”
This error is thrown by PyKwalify when it is unable to read the parameter file. The most common cause is when the file is indented using tabs, which throws a “token (‘t’) not recognized error”. Instead, ensure that all indentations are made using 2 or 4 spaces.
What file types are supported by PyRadiomics for input image and mask?¶
PyRadiomics uses SimpleITK for image loading and handling. Therefore, all image types supported by SimpleITK can be used as input for PyRadiomics. Please note that only one file location can be provided for image/mask. If you want to provide the image in DICOM format, load the DICOM images using SimpleITK functionality and pass the resultant image object instead.
Geometry mismatch between image and mask¶
My mask was generated using a another image than my input image, can I still extract features?
For various reasons, both image and mask must have the same geometry (i.e. same spacing, size, direction and origin)
when passed the feature classes. To this end PyRadiomics includes checks in the pipeline to ensure this is the case.
For more information on the mask checks, see checkMask()
. If the geometry error is small
difference in origin, spacing or direction, you can increase the tolerance by setting geometryTolerance
.
If the error is large, or the dimensions do not match, you could also resample the mask to image space. An example of
this is provided in bin\resampleMask.py
and can be enabled in PyRadiomics by setting correctMask
to True
,
which will only perform this correction in case of a geometery mismatch where the mask contains a valid ROI (i.e. the
mask contains the label value which does not include areas outside image physical bounds).
What modalities does PyRadiomics support?¶
PyRadiomics is not developed for one specific modality. Multiple modalities can be processed by PyRadiomics, although the optimal settings may differ between modalities. There are some constraints on the input however:
 Gray scale volume: PyRadiomics currently does not provide extraction from color images or images with complex values
 3D or slice: Although PyRadiomics supports single slice (2D) feature extraction, the input is still required to have 3 dimensions (where in case of 2D, a dimension may be of size 1).
Can I use DICOMRT struct for the input mask?¶
PyRadiomics does not support DICOMRT struct as input directly. We recommend to convert these using for example SlicerRT. We are working on providing support for DICOMRT in the Slicer extension, but this is not thoroughly tested yet.
Usage¶
How should the input file for pyradiomicsbatch
be structured?¶
Currently, the input file for pyradiomicsbatch
is a csv file specifying the combinations of images and masks for
which to extract features. It must contain a header line, where at least header “Image” and “Mask” should be specified
(capital sensitive). These identify the columns that contain the file location of the image and the mask, respectively.
Each subsequent line represents one combination of an image and a mask. Additional columns are also allowed, these are
copied to the output in the same order as the input, with the additional columns of the calculated features appended
at the end. N.B. All header names should be unique and not match any of the produced header names by pyradiomics.
Radiomics module not found in jupyter notebook¶
I installed PyRadiomics, but when I run the jupyter notebook, I get ImportError: No module named radiomics
This can have two possible causes: 1) When installing PyRadiomics from the repository, your python path variable will be updated to enable python to find the package. However, this value is only updated in commandline windows when they are restarted. If your jupyter notebook was running during installation, you first need to restart it. 2) Multiple versions of python can be installed on your machine simultaneously. Ensure PyRadiomics is installed on the same version you are using in your Jupyter notebook.
I’m missing features from my output. How can I see what went wrong?¶
If calculation of features or application of filters fails, a warning is logged. If you want to know exactly what
happens inside the toolbox, PyRadiomics provides extensive debug logging. You can enable this to be printed to the
out, or stored in a separate log file. The output is regulated by radiomics.setVerbosity()
and the PyRadiomics
logger can be accessed via radiomics.logger
. See also here and the examples
included in the repository on how to set up logging.
I’m able to extract features, but many are NaN, 0 or 1. What happend?¶
It is possible that the segmentation was too small to extract a valid texture. Check the value of VoxelNum
, which is
part of the additional information in the output. This is the number of voxels in the ROI after pre processing and
therefore the number of voxels that are used for feature calculation.
Another problem can be that you have to many or too few gray values after discretization. You can check this by
comparing the range of gray values in the ROI (a First Order feature) with the value for your binWidth
parameter.
More bins capture smaller differences in gray values, but too many bins (compared to number of voxels) will yield low
probabilities in the texture matrices, resulting in noninformative features. There is no definitive answer for the
ideal number of discretized gray values, and this may differ between modalities.
One study [1] assessed the number of bins in PET and found that in the range of 16  128 bins, texture features did not
differ significantly.
Does PyRadiomics support voxelwise feature extraction?¶
No, currently PyRadiomics only supports lesionbased feature extraction. However, voxelbased feature extraction may be a good addition in the future. If you have thoughts or ideas on how to implement this, we’d welcome your input on the pyradiomics email list.
Miscellaneous¶
A new version of PyRadiomics is available! Where can I find out what changed?¶
When a new version is released, a changelog is included in the release statement. Between releases, changes are not explicitly documented, but all significant changes are implemented using pull requests. Check the merged pull request for the latest changes.
I have some ideas for PyRadiomics. How can I contribute?¶
We welcome suggestions and contributions to PyRadiomics. Check our guidelines to see how you can contribute to PyRadiomics. Signatures and code styles used in PyRadiomics are documented in the Developers section.
I found a bug! Where do I report it?¶
We strive to keep PyRadiomics as bug free as possible by thoroughly testing new additions before including them in the stable version. However, nothing is perfect, and some bugs may therefore exist. Report yours by opening an issue on the GitHub or contact us at the pyradiomics email list. If you want to help in fixing it, we’d welcome you to open up a pull request with your suggested fix.
My question is not listed here...¶
If you have a question that is not listed here, check the pyradiomics email list or the issues on GitHub. Feel free to post a new question or issue and we’ll try to get back to you ASAP.
[1]  Tixier F, ChezeLe Rest C, Hatt M, Albarghach NM, Pradier O, Metges JP, et al. Intratumor Heterogeneity Characterized by Textural Features on Baseline 18FFDG PET Images Predicts Response to Concomitant Radiochemotherapy in Esophageal Cancer. J Nucl Med. 2011;52:369–78. 
Release Notes¶
Next Release¶
New Features¶
 Add a row by row customization of the extraction label in the batch processing command line script, as well as both batchprocessing examples. (#262)
Bug fixes¶
 In GLCM, the matrix is made symmetrical by adding the transposed matrix. However,
numpy.transpose
returns a view and not a copy of the array, causing erroneous results when adding it to the original array. usenumpy.ndarray.copy
to prevent this bug. N.B. This affects the feature values calculated by GLCM when symmetrical matrix is enabled (as is the default setting). (#261)  Use a python implementation to compute eigenvalues for
shape.py
instead of SimpleITK. The implementation in SimpleITK assumes segmented voxels to be consecutive on the xaxis lines. Furthermore, it also assumes that all voxels on a given line of x have the same values for y and z (which is not necessarily the case). (#264)
Tests¶
 Update the C Matrices test, so that the C and python calculated matrices will have the same dimensions when compared
(In the previous implementation, the
_calculateCoefficients
function was applied to the C calculated matrix, but not in the python calculated matrix, for some texture matrices, this function can change the dimension of the matrix). This update ensures that_calculateCoefficients
is applied to neither matrix. (#265)
Documentation¶
Internal API¶
 Remove unnecessary rows and columns from texture matrices prior to feature calculation. This does not affect the value of the calculated features, as the i and j vectors are updated accordingly, but it does reduce both computation time and memory requirements. This is especially the case when calculating GLSZM on large segmentations, where there may be many ‘empty’ zone sizes (i.e. no zones of that size are present in the ROI). This reduces the size of the matrix, which therefore reduces the memory needed and the number of calculations performed in the vectorized operations. (#265)
 Remove circular import statement in
__init__.py` (circular with ``radiomics.base
) (#270)
PyRadiomics 1.2.0¶
Feature Calculation Changes¶
 Remove feature SumVariance, rename SumVariance2 to SumVariance. SumVariance reflected the formula as is defined in the paper by Haralick et al [1]. However, the variance is calculated by subtracting the entropy as opposed to subtracting the average, most likely due to a typo(‘f8’ instead of ‘f6’). SumVariance2 reflected the formula where the average is subtracted and is retrained as the only SumVariance. (#233)
 Redefine features Elongation and Flatness as the inverse of the original definition. This prevents a returned value of NaN when the shape is completely flat. (#234)
 In certain edge cases, the calculated maximum diameters may be too small when calculating using the python implementation. This is corrected by the C extension and a warning is now logged when calculating these features in python. N.B. As of this change, maximum diameter is not available for calculation in fullpython mode (#257)
 For certain formulas, a NaN value is returned in some edge cases. Catch this and return a predefined value instead. Document this behaviour in the docstrings of the features affected. (#248)
New Features¶
Bug fixes¶
Requirements¶
Documentation¶
 Update feature docstrings, making them more easily adaptable for article supplements (#233)
 Add FAQ concerning the cmatrices lib path (#233)
 Add developer install step to documentation (#245)
 Remove use of
sudo
(#233)  Fix subclass name in feature class signature (section “Developers”)
 Add subsection on customizing the extraction to the “Usage” section (#252)
 Remove SimpleITK installation workaround, this is no longer needed (#249)
 Add a changelog to keep track of changes and integrate this into the auto generated documentation (#255)
Examples¶
 Add
pandas
example, showing how to process PyRadiomics output/input using thepandas
library (#228)
Internal API¶
 Add function to get or download test case (#235)
 Rewrite C Extension algorithm for GSLZM. Instead of searching over the image for the next voxel when growing a region, store all unprocessed voxels in a stack. This yields a significant increase in performance, especially in large ROIs. Requires slightly more memory (1 array, type integer, size equal to number of voxels in the ROI) (#257)
 Implement C extension for calculation of maximum diameters. (#257)
Cleanups¶
 Restructure repository (#254)
 Move jupyter notebooks to separate root folder (
root/notebooks
)  Move example script to separate root folder (
root/examples
), with example settings in separate subfolder (root/examples/exampleSettings
) bin
folder now only contains support scripts for the core code (i.e. generators for input files for batch processing and scripts to generate new baselines or to resample a mask to the image geometry)
 Move jupyter notebooks to separate root folder (
PyRadiomics 1.1.1¶
Feature Calculation Changes¶
 Correct error in formula for Compactness1. N.B. Baseline updated! (#218)
 Remove feature Roundness, as this feature is identical to feature Sphericity, but uses different implementation for surface area calculation (all implemented in SimpleITK) (#218)
 Change handling of cases where
max(X) mod binwidth = 0
during image discretization. These used to be assigned to topmost bin, but this produces unexpected behaviour (i.e. in range 1, 2, 3, 4, 5 with binwidth 1, value 5 would be discretized to 4 in stead of 5). Value now assigned is topmost bin + 1 (in concordance with default behavior ofnumpy.digitize
) (#219)  Change default value for
voxelArrayShift
(from 2000 to 0), this is to prevent unknowingly using a too large shift when not necessary. Document effect of this parameter in the first order formulas affected. (#219)
New features¶
 Add forced 2D extraction (as alternative to resampling for handling anisotropy in voxels spacing)
 Enable specification of distances between neighbors for GLCM matrix calculation
(#215)
New Parameters¶
force2D
, Boolean defaultFalse
. Set toTrue
to force a by slice texture calculation. Dimension that identifies the ‘slice’ can be defined inforce2Ddimension
. If input ROI is already a 2D ROI, features are automatically extracted in 2D.force2Ddimension
, int, range 02, default 0. Specifies the ‘slice’ dimension for a byslice feature extraction. Value 0 identifies the ‘z’ dimension (axial plane feature extraction), and features will be extracted from the xy plane. Similarly, 1 identifies the y dimension (coronal plane) and 2 the x dimension (saggital plane).distances
, List of integers, default[1]
. This specifies the distances between the center voxel and the neighbor, for which angles should be generated.
(#215)
Bug fixes¶
 Add some missing python 3 compatibility lines to the supporting script
addClassToBaseline
and command line scriptpyradiomicsbatch
(#210, #214)  Fix bug when loading image as file path and mask as SimpleITK object. (#211)
 Change location of parameter schema files. These files are otherwise not included in the wheel distribution. (#221)
Documentation¶
 Split package documentation into “Pipeline Modules” (all nonfeatureclass modules) and “Feature Definitions” (feature class modules)
 Add developers section with documentation on how to implement new filters, feature and feature classes.
 Add FAQ section with some trouble shooting tips
 Rename some GLSZM features, this is to make them more consistent with GLRLM features, which are similar, but calculated on a different matrix
 Add documentation for Elongation and Flatness
 Document mathematical correlation between various Shape features.
(#216)
Internal API¶
 Update logging with more extensive debug logging and more informative info log messages. (#220)
 Replace parameter verbose with output printing implemented in logging. Control verbosity level to output (stderr) by
calling
setVerbosity()
, where level determines the verbosity level (as defined in python logging). This prints out the requested levels of the log messaging, where process reports with parameter verbose are now classified as INFOlevel messages (i.e. specify INFO or DEBUG to enable these). N.B. parameter verbose is not longer supported and will throw an error if passed in the parameter file (#220)  Add feature class and input image type checks in
featureextractor
when changing these settings. (#213)  Remove usage of
eval
(replaced by implementations ofgetattr
), this is a more secure approach. (#216)  Define default settings in featureextractor in a separate function. This is to ensure consistency in applied default settings, as well as make them easily available outside of featureextractor (#216)
 Update reference for citing PyRadiomics (#224)
Cleanups¶
 Remove unused variable (
self.provenance_on
infeatureextractor
, this value is now replaced by a customizable setting)
PyRadiomics 1.1.0¶
New features¶
 Image normalization. This feature enables the normalization of image intensity values prior to feeding them to the extraction pipeline (i.e. before any other preprocessing steps are performed). Normalization is based on the all gray values contained within the image, not just those defined by the ROI in the mask.
 C Extensions for texture matrix and surface area calculation. These extensions enhance performance of texture matrix
calculation associated GLCM, GLRLM and GLSZM features and of surface area calculation. Below shows the decrease in
computation time for the 5 test cases included in PyRadiomics.
(#158,
#200,
#202)
 GLCM 6913 ms > 3 ms
 GLRLM 1850 ms > 10 ms
 GLSZM 12064 ms > 58 ms
 Surface Area 3241 ms > 1 ms
New Parameters¶
additionalInfo
Boolean, defaultTrue
. Enables additional information in the output if set toTrue
. (#190)enableCExtensions
Boolean, defailtTrue
. Enables enhanced performance for texture matrix calculation using C extensions if set toTrue
. (#202)normalize
Boolean, default `` False``. If set to true, normalizes image before feeding it into the extraction pipeline. (#209)normalizeScale
Float, > 0, default 1. Enables scaling of normalized intensities by specified value. (#209)removeOutliers
Float, > 0, defaultNone
. If set, outliers (defined by the value specified) are removed by setting them to the outlier value. Outlier value is defined on the nonscaled values. (#209)
Bug fixes¶
Requirements¶
 Add requirement for
six>=1.10.0
, needed to make PyRadiomics compatible with both python 2 and 3.
Documentation¶
 Documentation on installation and usage is upgraded, with the addition of an embedded instruction video (in section “Usage”, cued at the section on usage examples). (#187)
 Updated contact information to point to the google groups.
 Updated the classifiers in the setup script to reflect the more advanced status of Pyradiomics. (#193)
Tests¶
 Add support for multiple python versions and platforms, now including python 2.7, 3.4, 3.5 (32/64bits) for Linux, Windows and Mac. (#183, #191, #199)
 Testing output is upgraded to ensure unique feature names (#195, #197)
 Add
test_cmatrices
to assert conformity between output from Python and C based texture matrix calculation.
Internal API¶
getFeatureClasses()
andgetInputImageTypes()
are moved from Feature Extractor <radiomicsfeatureextractorlabel> to the global radiomics namespace. This enumerates the possible feature classes and filters at initialization of the toolbox, and ensures feature classes are imported at initialization. (#190, #198) Python 3 Compatibility. Add support for compatibility with python 2.7 and python >= 3.4. This is achieved using
package
six
.  Standardize function names for calculating matrices in python and with C extensions to
_calculateMatrix
and_calculateCMatrix
, respectively.  Make C code consistent with C89 convention. All variables (pointers for python objects) are initialized at top of each block.
 Optimize GLSZM calculation (C extension)
 Define temporary array for holding the calculated zones. During calculation, the matrix must be able to store all possible zones, ranging from zone size 1 to total number of voxels (Ns), for each gray level (Ng). In this case, the GLSZM would be initialized with size Ng * Ns, which is very memory intensive. Instead, use a temporary array of size (Ns * 2) + 1, which stores all calculated zones in pairs of 2 elements: the first element holds the gray level, the second the size of the calculated zone. The first element after the last zone is set to 1 to serve as a stop sign for the second function, which translates the temporary array into the final GLSZM, which can be directly initialized at optimum size.
 Use
calloc
andfree
for the temporary array holding the calculated zones.  Use
char
datatype for mask. (signed char in GLSZM).  Uses
while
loops. This allows to reduce the memory usage. Additionally, we observed that with recursive functions it was ‘unexpectedly’ failing.  Optimized search that finds a new index to process in the region growing.
PyRadiomics 1.0.1¶
New features¶
Bug fixes¶
Requirements¶
 Revert numpy minimum requirement to
1.9.2
. All operations in PyRadiomics are supported by this version, and it is the version used by Slicer. By reverting the minimum required version, installing PyRadiomics in the slicer extension does not cause an update of the numpy package distributed by slicer. (#180)
Documentation¶
 Update on the documentation, reflecting recent changes in the code.
 Add developers and affiliations to ReadMe and documentation (#177)
 Added additional references and updated installation and usage section.
Internal API¶
Different implementation of the various filters. No changes to calculation, but has a changed signature.
N.B. This results in inputImages to be differently defined (different capitalization, e.g. “orginal” should now be “Original”). See documentation for definition of inputImages (featureextractor section).
PyRadiomics 1.0¶
New features¶
 Initial Release of PyRadiomics
Work in progress¶
 Full python calculation (C matrices branch not stable and reserved for later release)
Documentation¶
 Documentation published at readthedocs
[1]  Haralick R, Shanmugan K, Dinstein I: Textural features for image classification. IEEE Trans Syst Man Cybern 1973:610–621. 
Feature Classes¶
Currently supports the following feature classes:
 First Order Statistics
 Shapebased
 Gray Level Cooccurence Matrix (GLCM)
 Gray Level Run Length Matrix (GLRLM)
 Gray Level Size Zone Matrix (GLSZM)
On average, Pyradiomics extracts \(\approx 1300\) features per image, which consist of the 16 shape descriptors and features extracted from original and derived images (LoG with 5 sigma levels, 1 level of Wavelet decomposistions yielding 8 derived images and images derived using Square, Square Root, Logarithm and Exponential filters).
Detailed description on feature classes and individual features is provided in section Radiomic Features.
Filter Classes¶
Aside from the feature classes, there are also some builtin optional filters:
Laplacian of Gaussian
(LoG, based on SimpleITK functionality)Wavelet
(using the PyWavelets package)Square
Square Root
Logarithm
Exponential
For more information, see also Image Processing and Filters.
Supporting reproducible extraction¶
Aside from calculating features, the pyradiomics package includes additional information in the output. This information contains information on used image and mask, as well as applied settings and filters, thereby enabling fully reproducible feature extraction. For more information, see General Info Module.
3rdparty packages used in pyradiomics¶
 SimpleITK (Image loading and preprocessing)
 numpy (Feature calculation)
 PyWavelets (Wavelet filter)
 pykwalify (Enabling yaml parameters file checking)
 six (Python 3 Compatibility)
See also the requirements file.
Installation¶
PyRadiomics is OS independent and compatible with both Python 2.7 and Python >=3.4.
 Clone the repository
git clone git://github.com/Radiomics/pyradiomics
 Install on your system (Linux, Mac OSX), with prerequisites:
cd pyradiomics
python m pip install r requirements.txt
python setup.py install
 For more detailed installation instructions and installation on Windows see Installation Details
Pyradiomics Indices and Tables¶
License¶
This package is covered by the open source 3clause BSD License.
Developers¶
 Joost van Griethuysen^{1,3,4}
 Andriy Fedorov^{2}
 Nicole Aucoin^{2}
 JeanChristophe FillionRobin^{5}
 Ahmed Hosny^{1}
 Steve Pieper^{6}
 Hugo Aerts (PI)^{1,2}
^{1}Department of Radiation Oncology, DanaFarber Cancer Institute, Brigham and Women’s Hospital, Harvard Medical School, Boston, MA, ^{2}Department of Radiology, Brigham and Women’s Hospital, Harvard Medical School, Boston, MA ^{3}Department of Radiology, Netherlands Cancer Institute, Amsterdam, The Netherlands, ^{4}GROWSchool for Oncology and Developmental Biology, Maastricht University Medical Center, Maastricht, The Netherlands, ^{5}Kitware, ^{6}Isomics
Contact¶
We are happy to help you with any questions. Please contact us on the pyradiomics email list.
We’d welcome your contributions to PyRadiomics. Please read the contributing guidelines on how to contribute to PyRadiomics. Information on adding / customizing feature classes and filters can be found in the Developers section.