Radiomics: Feature Extraction and Analysis
Module: Healthcare AI | Difficulty: Advanced
GLCM Energy
GLCM Entropy
Wavelet Features
Radiomics Feature Categories
| Category | Feature Count | Example Features | |----------|--------------|------------------| | First-order | 18 | Mean, variance, skewness, kurtosis | | Shape | 14 | Volume, surface area, sphericity | | GLCM | 24 | Contrast, correlation, energy | | GLRLM | 16 | SRE, LRE, GLNU | | GLSZM | 16 | SAE, LAE, ZSN | | NGTDM | 5 | Coarseness, contrast, busyness |
import numpy as np
from skimage.feature import graycomatrix, graycoprops
def extract_first_order_features(volume):
features = {}
features['mean'] = np.mean(volume)
features['std'] = np.std(volume)
features['skewness'] = float(np.mean(
((volume - features['mean']) / (features['std'] + 1e-8))**3))
features['kurtosis'] = float(np.mean(
((volume - features['mean']) / (features['std'] + 1e-8))**4) - 3)
features['energy'] = float(np.sum(volume**2))
return features
def extract_glcm_features(volume_2d, distances=[1, 2, 4], angles=[0, np.pi/4, np.pi/2]):
volume_2d = (volume_2d / volume_2d.max() * 255).astype(np.uint8)
glcm = graycomatrix(volume_2d, distances=distances, angles=angles,
levels=256, symmetric=True, normed=True)
features = {}
for prop in ['contrast', 'dissimilarity', 'homogeneity', 'energy', 'correlation']:
vals = graycoprops(glcm, prop)
features[f'glcm_{prop}_mean'] = float(np.mean(vals))
features[f'glcm_{prop}_std'] = float(np.std(vals))
return features
def extract_wavelet_features(volume, wavelet='db4'):
import pywt
coeffs = pywt.wavedec3(volume, wavelet, level=2)
features = {}
for i, coeff in enumerate(coeffs):
if isinstance(coeff, np.ndarray):
features[f'wavelet_level{i}_mean'] = float(np.mean(np.abs(coeff)))
features[f'wavelet_level{i}_energy'] = float(np.sum(coeff**2))
return features
def build_radiomics_pipeline(volume, mask):
masked = volume * mask
features = {}
features.update(extract_first_order_features(masked[mask > 0]))
slice_idx = volume.shape[2] // 2
features.update(extract_glcm_features(masked[:, :, slice_idx]))
return features
volume = np.random.rand(64, 64, 64)
mask = (volume > 0.3).astype(float)
features = build_radiomics_pipeline(volume, mask)
print(f'Extracted {len(features)} radiomics features')
Research Insight: Radiomics features are susceptible to scan protocol variations. The Image Biomarker Standardization Initiative (IBSI) provides standardized feature definitions and phantom-based validation. ComBat harmonization and other batch effect correction methods are essential when combining data from multiple institutions.