FeatureExtractor

The FeatureExtractor class is the main high-level interface for extracting topological features from medical images.

Overview

FeatureExtractor combines preprocessing, persistent homology computation, and vectorization into a single convenient interface. It is the recommended entry point for most users.

Key Features:

  • End-to-end feature extraction pipeline

  • Configurable preprocessing options

  • Multiple vectorization methods

  • Batch processing support

  • Optional raw barcode extraction

Basic Usage

Quick Start

Extract features from a single image:

from medtda import FeatureExtractor

# Create extractor with default settings
extractor = FeatureExtractor()

# Extract features
features = extractor.execute('path/to/image.nii.gz')

With Mask

Process an image with a binary mask:

extractor = FeatureExtractor(
    normalize=True,
   vectorization_method='PersImage'
features = extractor.execute(
    image='path/to/image.nii.gz',
    mask='path/to/mask.nii.gz'
)

Multiple Vectorization Methods

Extract features using multiple methods simultaneously:

extractor = FeatureExtractor()
extractor.enable_vectorization_methods([
    'PersStats',
    'BettiCurve',
    'PersImage'
])

features = extractor.execute('image.nii.gz')
# features is a dict with keys like: 'PersStats_H0_mean', 'BettiCurve_H0_f0', etc.

Class Documentation

class medtda.FeatureExtractor(spacing=None, window=None, normalize=False, normalize_method='minmax', clip_percentiles=None, background_value=None, label=1, crop_to_roi=True, roi_padding=1, filtration_type='sublevel', construction='T', max_dimension=-1, return_barcodes=False, vectorization_method='PersStats')[source]

Bases: object

Extract vectorized TDA features from medical images.

This class handles the complete pipeline: image loading, preprocessing, persistent homology computation, and vectorization of barcodes into fixed-length feature vectors.

Parameters:
  • spacing (tuple or None, default=None) – Target voxel spacing for resampling (3D/4D only).

  • window (tuple or None, default=None) – Windowing parameters as (center, width).

  • normalize (bool, default=False) – Whether to apply normalization.

  • normalize_method ({'minmax', 'zscore', 'robust'}, default='minmax') – Normalization method (only used if normalize=True).

  • clip_percentiles (tuple of float, optional) – If provided, clip intensities to percentile range (lower, upper) before normalization. For example, (1, 99) clips to 1st and 99th percentiles. Only applied if normalize=True.

  • background_value (float or None, default=None) – Value to assign to background pixels when a mask is provided.

  • label (int or None, default=1) – For multi-label masks, which label value to consider as foreground. If None, treat mask as binary (any non-zero value is foreground).

  • crop_to_roi (bool, default=True) – If True and a mask is provided, crop image and mask to the bounding box of the ROI with padding. This reduces memory usage and speeds up persistent homology computation.

  • roi_padding (int, default=1) – Number of background pixels to include on all sides of the ROI when crop_to_roi is enabled.

  • filtration_type ({'sublevel', 'superlevel'}, default='sublevel') – Type of filtration for persistent homology.

  • construction ({'T', 'V'}, default='T') – Type of cubical complex construction: - ‘T’: T-construction (pixels/voxels as top-cells, 8-neighborhood in 2D) - ‘V’: V-construction (pixels/voxels as 0-cells, 4-neighborhood in 2D)

  • max_dimension (int, default=-1) – Maximum homology dimension to compute. If -1, automatically determined based on image dimensionality.

  • return_barcodes (bool, default=False) – If True, return computed barcodes along with features.

  • vectorization_method (str or list, default='PersStats') – Single method name or list of method names to apply. Options: ‘BettiCurve’, ‘EntropySummary’, ‘PersStats’, ‘PersTropicalCoordinates’, ‘PersLandscape’, ‘PersImage’, ‘PersLifespan’, ‘PersSilhouette’

Examples

>>> from medtda import FeatureExtractor
>>> extractor = FeatureExtractor(
...     normalize=True,
...     vectorization_method='PersStats'
... )
>>> features = extractor.execute('image.nii.gz', 'mask.nii.gz')
>>> print(features.keys())  # e.g., dict_keys(['PersStats_H0_mean', ...])
__init__(spacing=None, window=None, normalize=False, normalize_method='minmax', clip_percentiles=None, background_value=None, label=1, crop_to_roi=True, roi_padding=1, filtration_type='sublevel', construction='T', max_dimension=-1, return_barcodes=False, vectorization_method='PersStats')[source]

Initialize FeatureExtractor with parameters.

set_spacing(spacing)[source]

Update spacing parameter.

Return type:

None

set_window(window_center, window_width)[source]

Set windowing parameters.

Return type:

None

set_normalize(enabled, method='minmax')[source]

Enable/disable normalization and set method.

Return type:

None

set_clip_percentiles(percentiles)[source]

Set percentile clipping for outlier removal.

Parameters:

percentiles (tuple of float or None) – If provided, should be (lower_percentile, upper_percentile) where 0 <= lower_percentile < upper_percentile <= 100. Values outside these percentiles will be clipped. Set to None to disable clipping.

Return type:

None

set_background_value(value)[source]

Set background value for masked regions.

Return type:

None

set_label(label)[source]

Set label value to extract from multi-label mask.

Parameters:

label (int or None) – Label value to extract. If None, treat mask as binary.

Return type:

None

set_filtration_type(filtration_type)[source]

Set persistent homology filtration type.

Return type:

None

set_construction(construction)[source]

Set cubical complex construction type.

Return type:

None

set_max_dimension(max_dimension)[source]

Set maximum homology dimension to compute.

Return type:

None

set_return_barcodes(return_barcodes)[source]

Enable/disable barcode return.

Parameters:

return_barcodes (bool) – If True, execute() returns (features, barcodes) tuple.

Return type:

None

set_vectorization_method(method, **params)[source]

Set a single vectorization method with optional parameters.

This replaces all currently enabled methods with just this one.

Parameters:
  • method (str) – Vectorization method name.

  • **params – Method-specific parameters.

Return type:

None

set_vectorization_params(method, **params)[source]

Update parameters for a vectorization method.

Parameters:
  • method (str) – Vectorization method name.

  • **params – Method-specific parameters to update.

Return type:

None

enable_vectorization_methods(methods)[source]

Enable multiple vectorization methods.

Parameters:

methods (list of str) – List of method names to enable.

Return type:

None

enable_all_vectorization_methods()[source]

Enable all available vectorization methods.

Return type:

None

disable_vectorization_method(method)[source]

Disable a specific vectorization method.

Parameters:

method (str) – Method name to disable.

Return type:

None

get_enabled_vectorization_methods()[source]

Get list of currently enabled vectorization methods.

Returns:

Enabled method names.

Return type:

list of str

get_vectorization_params(method)[source]

Get current parameters for a vectorization method.

Parameters:

method (str) – Method name.

Returns:

Current parameters for the method.

Return type:

dict

get_settings()[source]

Get current settings for extraction.

Returns:

Dictionary containing all current settings.

Return type:

dict

execute(image, mask=None, label=<object object>)[source]

Execute feature extraction pipeline.

This method performs: 1. Preprocess image (via BarcodeExtractor) 2. Compute persistent homology (get barcodes) 3. Vectorize barcodes using enabled methods 4. Format features with naming convention

Parameters:
  • image (str, Path, or numpy.ndarray) – Input image.

  • mask (str, Path, numpy.ndarray, or None, default=None) – Optional mask.

  • label (int or None, optional) – Label value to extract from mask. If None, uses instance default.

Return type:

Union[Dict[str, Any], Tuple[Dict[str, Any], Dict[str, ndarray]]]

Returns:

  • features (OrderedDict) – Feature dictionary with keys following naming convention: - Dict-based methods (e.g., PersStats): ‘{method}_{dimension}_{feature_name}’ - Array-based methods (e.g., BettiCurve): ‘{method}_{dimension}_f{index}’

  • barcodes (dict (optional)) – If return_barcodes=True, returns (features, barcodes) tuple.

Examples

>>> extractor = FeatureExtractor(
...     normalize=True,
...     vectorization_method=['PersStats', 'BettiCurve']
... )
>>> features = extractor.execute('image.nii.gz')
>>> print(list(features.keys())[:5])  # First 5 feature names

Constructor Parameters

Preprocessing Parameters

Parameter

Type

Description

spacing

tuple or None

Target voxel spacing for resampling (e.g., (1.0, 1.0, 1.0))

window

tuple or None

Windowing as (center, width) for CT images

normalize

bool

Enable intensity normalization (default: False)

normalize_method

str

Normalization method: 'minmax', 'zscore', or 'robust' (default: 'minmax')

clip_percentiles

tuple or None

Clip intensities to (lower, upper) percentiles before normalization (default: None)

background_value

float or None

Background pixel value (auto-detected if None)

label

int or None

Extract specific label from multi-label mask (default: 1)

crop_to_roi

bool

Crop to ROI bounding box (default: True)

roi_padding

int

Padding around ROI in pixels (default: 1)

Persistent Homology Parameters

Parameter

Type

Description

filtration_type

str

'sublevel' or 'superlevel' (default: 'sublevel')

construction

str

Cubical complex construction: 'T' or 'V' (default: 'T')

max_dimension

int

Maximum homology dimension, -1 for auto (default: -1)

Vectorization Parameters

Parameter

Type

Description

vectorization_method

str or list

Vectorization method(s) to use (default: 'PersStats')

return_barcodes

bool

Return raw barcodes with features (default: False)

Valid vectorization methods:

  • 'PersStats' - Statistical summaries

  • 'BettiCurve' - Betti numbers over filtration

  • 'PersImage' - 2D histogram representation

  • 'PersLandscape' - Functional landscape

  • 'PersSilhouette' - Average landscape

  • 'EntropySummary' - Information-theoretic features

  • 'PersLifespan' - Lifespan distribution

  • 'PersTropicalCoordinates' - Tropical algebra

Methods

execute

FeatureExtractor.execute(image, mask=None, label=<object object>)[source]

Execute feature extraction pipeline.

This method performs: 1. Preprocess image (via BarcodeExtractor) 2. Compute persistent homology (get barcodes) 3. Vectorize barcodes using enabled methods 4. Format features with naming convention

Parameters:
  • image (str, Path, or numpy.ndarray) – Input image.

  • mask (str, Path, numpy.ndarray, or None, default=None) – Optional mask.

  • label (int or None, optional) – Label value to extract from mask. If None, uses instance default.

Return type:

Union[Dict[str, Any], Tuple[Dict[str, Any], Dict[str, ndarray]]]

Returns:

  • features (OrderedDict) – Feature dictionary with keys following naming convention: - Dict-based methods (e.g., PersStats): ‘{method}_{dimension}_{feature_name}’ - Array-based methods (e.g., BettiCurve): ‘{method}_{dimension}_f{index}’

  • barcodes (dict (optional)) – If return_barcodes=True, returns (features, barcodes) tuple.

Examples

>>> extractor = FeatureExtractor(
...     normalize=True,
...     vectorization_method=['PersStats', 'BettiCurve']
... )
>>> features = extractor.execute('image.nii.gz')
>>> print(list(features.keys())[:5])  # First 5 feature names

Signature:

def execute(
    self,
    image: Union[str, Path, np.ndarray],
    mask: Union[str, Path, np.ndarray, None] = None
) -> Union[Dict[str, np.ndarray], Tuple[Dict[str, np.ndarray], Dict[int, np.ndarray]]]

Parameters:

  • image (str, Path, or np.ndarray) - Input image (file path or array)

  • mask (str, Path, np.ndarray, or None) - Optional binary mask

Returns:

  • features (dict) - Dictionary mapping feature names to values. Keys follow format: ‘{method}_{dimension}_{feature}’ for dict-based methods or ‘{method}_{dimension}_f{i}’ for array-based methods.

  • OR (features, barcodes) (tuple) - If return_barcodes=True

Example:

extractor = FeatureExtractor(
    normalize=True,
    vectorization_method='PersImage',
    return_barcodes=True
)

features, barcodes = extractor.execute('image.nii.gz', mask='mask.nii.gz')

# features is a dict: {'PersImage_H0_f0': 0.12, 'PersImage_H0_f1': 0.45, ...}
# barcodes is a dict: {0: array([[b,d],...]), 1: array([[b,d],...])}

set_vectorization_method

FeatureExtractor.set_vectorization_method(method, **params)[source]

Set a single vectorization method with optional parameters.

This replaces all currently enabled methods with just this one.

Parameters:
  • method (str) – Vectorization method name.

  • **params – Method-specific parameters.

Return type:

None

Change the vectorization method and its parameters.

Signature:

def set_vectorization_method(self, method: str, **params) -> None

Parameters:

  • method (str) - Vectorization method name

  • params - Method-specific parameters

Example:

extractor = FeatureExtractor()

# Change to persistence image with custom parameters
extractor.set_vectorization_method(
    'PersImage',
    resolution=50,
    bandwidth=0.1
)

enable_vectorization_methods

FeatureExtractor.enable_vectorization_methods(methods)[source]

Enable multiple vectorization methods.

Parameters:

methods (list of str) – List of method names to enable.

Return type:

None

Enable multiple vectorization methods.

Signature:

def enable_vectorization_methods(self, methods: List[str]) -> None

Parameters:

  • methods (list of str) - List of vectorization method names

Example:

extractor = FeatureExtractor()
extractor.enable_vectorization_methods([
    'PersStats',
    'BettiCurve',
    'PersImage'
])

features = extractor.execute('image.nii.gz')
# Returns dict with 3 keys

set_vectorization_params

FeatureExtractor.set_vectorization_params(method, **params)[source]

Update parameters for a vectorization method.

Parameters:
  • method (str) – Vectorization method name.

  • **params – Method-specific parameters to update.

Return type:

None

Configure parameters for a specific vectorization method when using multiple methods.

Signature:

def set_vectorization_params(self, method: str, **params) -> None

Parameters:

  • method (str) - Vectorization method name

  • params - Method-specific parameters

Example:

extractor = FeatureExtractor()
extractor.enable_vectorization_methods(['BettiCurve', 'PersImage'])

# Configure individual method parameters
extractor.set_vectorization_params('BettiCurve', resolution=200)
extractor.set_vectorization_params('PersImage', resolution=30)

Complete Example

Advanced Usage with All Options

from medtda import FeatureExtractor
import numpy as np

# Initialize with comprehensive configuration
extractor = FeatureExtractor(
    # Preprocessing
    spacing=(1.0, 1.0, 1.0),
    window=(40, 400),  # CT abdomen window
    normalize=True,
    normalize_method='robust',
    crop_to_roi=True,
    roi_padding=5,

    # Persistent Homology
    filtration_type='sublevel',
    construction='T',
    max_dimension=2,

    # Vectorization
    vectorization_method='PersImage',
    return_barcodes=True
)

# Extract features
features, barcodes = extractor.execute(
    image='path/to/ct_scan.nii.gz',
    mask='path/to/liver_mask.nii.gz'
)

# Access results
# features is a flat dict: {'PersImage_H0_f0': 0.12, 'PersImage_H0_f1': 0.45, ...}
h0_barcode = barcodes['H0']  # Connected components
h1_barcode = barcodes['H1']  # Loops/tunnels
h2_barcode = barcodes['H2']  # Voids/cavities

print(f"Feature vector shape: {pi_features.shape}")
print(f"H1 features: {len(h1_barcode)} persistence pairs")

Multi-Method Extraction

from medtda import FeatureExtractor

# Create extractor
extractor = FeatureExtractor(normalize=True)

# Configure multiple methods
extractor.enable_vectorization_methods([
    'PersStats',
    'BettiCurve',
    'PersImage',
    'PersLandscape'
])

# Customize parameters for each
extractor.set_vectorization_params('BettiCurve', resolution=150)
extractor.set_vectorization_params('PersImage', resolution=25, bandwidth=0.15)
extractor.set_vectorization_params('PersLandscape', num_landscapes=10)

# Extract all features — returns flat dict of individual feature values
features = extractor.execute('image.nii.gz')

# Use in machine learning
import numpy as np
feature_vector = np.array(list(features.values()))

See Also