BarcodeExtractor
The BarcodeExtractor class provides a higher-level interface for extracting persistence barcodes from images.
Overview
BarcodeExtractor wraps the persistent homology computation functions into a convenient class interface. It’s used internally by FeatureExtractor but can also be used standalone.
Key Features:
Simple interface for barcode extraction
Configurable filtration type and construction method
Automatic dimension detection
Flexible configuration
Basic Usage
Quick Start
from medtda import BarcodeExtractor
extractor = BarcodeExtractor()
barcodes = extractor.execute(image_array)
# Access barcodes by dimension
h0 = barcodes['H0']
h1 = barcodes['H1']
Custom Configuration
extractor = BarcodeExtractor(
filtration_type='superlevel',
construction='V',
max_dimension=2
)
barcodes = extractor.execute(image_array)
Dynamic Reconfiguration
extractor = BarcodeExtractor()
# Extract with sublevel filtration
barcodes_sub = extractor.execute(image)
# Change to superlevel
extractor.set_filtration_type('superlevel')
barcodes_sup = extractor.execute(image)
Class Documentation
- class medtda.BarcodeExtractor(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)[source]
Bases:
objectExtract raw persistence barcodes from medical images.
This class handles the full pipeline: image loading, preprocessing, and persistent homology computation, returning raw barcodes without vectorization.
- Parameters:
spacing (tuple or None, default=None) – Target voxel spacing for resampling (3D/4D only). If None, no resampling is performed.
window (tuple or None, default=None) – Windowing parameters as (center, width). If None, no windowing is applied.
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. If None, automatically determined based on normalization and dimensionality.
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 (computes H0, H1, …, H_max_dimension). If -1, automatically determined based on image dimensionality (uses ndim - 1).
Examples
>>> from medtda import BarcodeExtractor >>> extractor = BarcodeExtractor( ... normalize=True, ... normalize_method='minmax', ... filtration_type='sublevel', ... max_dimension=2 ... ) >>> barcodes = extractor.execute( ... image='path/to/image.nii.gz', ... mask='path/to/mask.nii.gz' ... ) >>> print(barcodes.keys()) # e.g., dict_keys(['H0', 'H1', 'H2']) >>> print(barcodes['H1'].shape) # (n_features, 2) for (birth, death) pairs
- __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)[source]
Initialize BarcodeExtractor with parameters.
- set_filtration_type(filtration_type)[source]
Set persistent homology filtration type.
- Parameters:
filtration_type ({'sublevel', 'superlevel'}) – Filtration type.
- Return type:
- set_construction(construction)[source]
Set cubical complex construction type.
- Parameters:
construction ({'T', 'V'}) – Construction type.
- Return type:
- get_settings()[source]
Get current settings for preprocessing and PH computation.
- Returns:
Dictionary containing all current settings.
- Return type:
- execute(image, mask=None, label=<object object>)[source]
Execute barcode extraction pipeline.
This method performs the complete extraction pipeline: 1. Preprocess image (load, resample, window, normalize, crop, mask) 2. Compute persistent homology 3. Format barcodes by dimension
- Parameters:
image (str, Path, or numpy.ndarray) – Input image. Can be a file path or numpy array.
mask (str, Path, numpy.ndarray, or None, default=None) – Optional mask. Can be a file path or numpy array.
label (int or None, optional) – Label value to extract from mask. If None, uses instance default.
- Returns:
barcodes – Dictionary with keys as homology dimensions (e.g., ‘H0’, ‘H1’, ‘H2’) and values as barcode arrays of shape (n_features, 2) containing (birth, death) pairs.
- Return type:
Examples
>>> extractor = BarcodeExtractor(normalize=True) >>> barcodes = extractor.execute('image.nii.gz', 'mask.nii.gz') >>> print(f"H1 has {len(barcodes['H1'])} features")
Constructor Parameters
Parameter |
Type |
Description |
|---|---|---|
|
tuple or None |
Target voxel spacing for resampling, e.g. |
|
tuple or None |
CT windowing as |
|
bool |
Enable intensity normalization (default: |
|
str |
Normalization method: |
|
tuple or None |
Clip intensities to |
|
float or None |
Background pixel value, auto-determined if |
|
int or None |
Label to extract from multi-label mask (default: |
|
bool |
Crop to ROI bounding box when mask is provided (default: |
|
int |
Padding around ROI in pixels (default: |
|
str |
|
|
str |
Cubical complex construction: |
|
int |
Maximum homology dimension, |
Methods
execute
- BarcodeExtractor.execute(image, mask=None, label=<object object>)[source]
Execute barcode extraction pipeline.
This method performs the complete extraction pipeline: 1. Preprocess image (load, resample, window, normalize, crop, mask) 2. Compute persistent homology 3. Format barcodes by dimension
- Parameters:
image (str, Path, or numpy.ndarray) – Input image. Can be a file path or numpy array.
mask (str, Path, numpy.ndarray, or None, default=None) – Optional mask. Can be a file path or numpy array.
label (int or None, optional) – Label value to extract from mask. If None, uses instance default.
- Returns:
barcodes – Dictionary with keys as homology dimensions (e.g., ‘H0’, ‘H1’, ‘H2’) and values as barcode arrays of shape (n_features, 2) containing (birth, death) pairs.
- Return type:
Examples
>>> extractor = BarcodeExtractor(normalize=True) >>> barcodes = extractor.execute('image.nii.gz', 'mask.nii.gz') >>> print(f"H1 has {len(barcodes['H1'])} features")
Execute the barcode extraction pipeline.
Signature:
def execute(
self,
image: Union[str, Path, np.ndarray],
mask: Union[str, Path, np.ndarray, None] = None
) -> Dict[str, np.ndarray]
Parameters:
image (str, Path, or np.ndarray) - Input image (file path or array)
mask (str, Path, np.ndarray, or None) - Optional binary or multi-label mask
Returns:
barcodes (dict) - Dictionary mapping dimension to barcode arrays
Keys: homology dimension strings (
'H0','H1','H2', …)Values: NumPy arrays of shape
(n_features, 2)with[birth, death]columns
Example:
extractor = BarcodeExtractor()
barcodes = extractor.execute(image)
for dim_key, barcode in barcodes.items():
print(f"{dim_key}: {len(barcode)} features")
set_filtration_type
- BarcodeExtractor.set_filtration_type(filtration_type)[source]
Set persistent homology filtration type.
- Parameters:
filtration_type ({'sublevel', 'superlevel'}) – Filtration type.
- Return type:
Change the filtration type.
Signature:
def set_filtration_type(self, filtration_type: str) -> None
Parameters:
filtration_type (str) -
'sublevel'or'superlevel'
Example:
extractor = BarcodeExtractor()
extractor.set_filtration_type('superlevel')
set_construction
- BarcodeExtractor.set_construction(construction)[source]
Set cubical complex construction type.
- Parameters:
construction ({'T', 'V'}) – Construction type.
- Return type:
Change the cubical complex construction method.
Signature:
def set_construction(self, construction: str) -> None
Parameters:
construction (str) -
'T'or'V'
Example:
extractor = BarcodeExtractor()
extractor.set_construction('V')
set_max_dimension
- BarcodeExtractor.set_max_dimension(max_dimension)[source]
Set maximum homology dimension to compute.
Change the maximum homology dimension.
Signature:
def set_max_dimension(self, max_dimension: int) -> None
Parameters:
max_dimension (int) - Maximum dimension, or
-1for auto
Example:
extractor = BarcodeExtractor()
extractor.set_max_dimension(1) # Only H0 and H1
Complete Examples
Example 1: Basic Barcode Extraction
import numpy as np
from medtda import BarcodeExtractor
from medtda.loaders import load_image
# Load image
image, metadata = load_image('medical_image.nii.gz')
# Create extractor
extractor = BarcodeExtractor(
filtration_type='sublevel',
construction='T'
)
# Extract barcodes
barcodes = extractor.execute(image)
# Analyze results
for dim_key in barcodes:
barcode = barcodes[dim_key]
persistence = barcode[:, 1] - barcode[:, 0]
print(f"\n{dim_key}:")
print(f" Features: {len(barcode)}")
print(f" Avg persistence: {persistence.mean():.4f}")
print(f" Max persistence: {persistence.max():.4f}")
Example 2: Comparing Filtrations
from medtda import BarcodeExtractor
extractor = BarcodeExtractor()
# Sublevel: features from low to high intensity
extractor.set_filtration_type('sublevel')
barcodes_sub = extractor.execute(image)
# Superlevel: features from high to low intensity
extractor.set_filtration_type('superlevel')
barcodes_sup = extractor.execute(image)
# Compare H1 features
print(f"Sublevel H1 features: {len(barcodes_sub['H1'])}")
print(f"Superlevel H1 features: {len(barcodes_sup['H1'])}")
Example 3: Progressive Dimension Analysis
from medtda import BarcodeExtractor
extractor = BarcodeExtractor(construction='T')
# Start with H0 only (fast)
extractor.set_max_dimension(0)
barcodes_h0 = extractor.execute(image)
print(f"H0 features: {len(barcodes_h0['H0'])}")
# Add H1 if needed
extractor.set_max_dimension(1)
barcodes_h01 = extractor.execute(image)
print(f"H1 features: {len(barcodes_h01['H1'])}")
# Add H2 for full 3D topology (slower)
extractor.set_max_dimension(2)
barcodes_full = extractor.execute(image)
print(f"H2 features: {len(barcodes_full['H2'])}")
Example 4: Integration with Preprocessing
from medtda import BarcodeExtractor, Preprocessor
from medtda.loaders import load_image, load_mask
# Load data
image, _ = load_image('ct_scan.nii.gz')
mask, _ = load_mask('tumor_mask.nii.gz')
# Preprocess
preprocessor = Preprocessor(
normalize=True,
crop_to_roi=True,
roi_padding=5
)
processed_image, _ = preprocessor.preprocess(image, mask)
# Extract barcodes
extractor = BarcodeExtractor(
filtration_type='sublevel',
max_dimension=2
)
barcodes = extractor.execute(processed_image)
# Analyze topology
h1_persistence = barcodes['H1'][:, 1] - barcodes['H1'][:, 0]
significant_loops = np.sum(h1_persistence > 0.1)
print(f"Significant loops in tumor: {significant_loops}")
Example 5: Batch Processing
from medtda import BarcodeExtractor
import glob
extractor = BarcodeExtractor()
# Process multiple images
image_paths = glob.glob('images/*.nii.gz')
all_barcodes = []
for path in image_paths:
image, _ = load_image(path)
barcodes = extractor.execute(image)
all_barcodes.append(barcodes)
# Quick summary
h1_count = len(barcodes['H1'])
print(f"{path}: {h1_count} H1 features")
Common Use Cases
Use Case 1: Topology Characterization
Extract all topological features:
extractor = BarcodeExtractor(max_dimension=2)
barcodes = extractor.execute(preprocessed_image)
# Characterize topology
n_components = len(barcodes['H0'])
n_loops = len(barcodes['H1'])
n_voids = len(barcodes['H2'])
Use Case 2: Feature Filtering
Extract and filter by persistence:
extractor = BarcodeExtractor()
barcodes = extractor.execute(image)
# Keep only significant features
threshold = 0.1
for dim_key in barcodes:
barcode = barcodes[dim_key]
persistence = barcode[:, 1] - barcode[:, 0]
barcodes[dim_key] = barcode[persistence > threshold]
Use Case 3: Method Comparison
Compare T and V construction:
# T-construction
extractor_t = BarcodeExtractor(construction='T')
barcodes_t = extractor_t.execute(image)
# V-construction
extractor_v = BarcodeExtractor(construction='V')
barcodes_v = extractor_v.execute(image)
# Compare feature counts
for dim_key in barcodes_t:
print(f"{dim_key}: T={len(barcodes_t[dim_key])}, V={len(barcodes_v[dim_key])}")
Performance Tips
Start with lower dimensions:
Use
max_dimension=0ormax_dimension=1initially:extractor = BarcodeExtractor(max_dimension=1)
Choose construction wisely:
T-construction: More features per image
V-construction: Fewer features, faster for large images
Pass mask directly to execute:
Let BarcodeExtractor handle preprocessing:
extractor = BarcodeExtractor(crop_to_roi=True) barcodes = extractor.execute(image, mask)
Reuse extractor:
Create once, use multiple times:
extractor = BarcodeExtractor() for image in images: barcodes = extractor.execute(image)
See Also
PH Computer - Underlying PH computation functions
FeatureExtractor - High-level feature extraction
Vectorizers - Convert barcodes to feature vectors
Persistent Homology - PH guide