fastai simplifies training fast and accurate neural nets using modern best practices
—
Specialized tools for working with DICOM (Digital Imaging and Communications in Medicine) files, the de-facto standard for medical imaging data. This module extends fastai's vision capabilities specifically for medical image processing workflows including CT scans, MRI, X-rays, and other medical imaging modalities.
Loading and accessing DICOM files with proper metadata handling and format support.
def get_dicom_files(path, recurse=True, folders=None):
"""
Get DICOM files in path recursively, optionally filtering by folders.
Parameters:
- path: Directory path to search
- recurse: Whether to search subdirectories (default: True)
- folders: List of specific folder names to search in (optional)
Returns:
List of DICOM file paths
"""
def dcmread(fn, force=False):
"""
Open a DICOM file using pydicom.
Parameters:
- fn: Path to DICOM file
- force: Force reading even if file appears corrupted
Returns:
DcmDataset object with enhanced functionality
"""Accessing and converting DICOM pixel data with proper scaling and normalization.
# Properties for DcmDataset objects
@property
def pixels(self):
"""Get pixel_array as a float32 tensor."""
@property
def scaled_px(self):
"""Get pixels scaled by RescaleSlope and RescaleIntercept DICOM tags."""
@property
def shape(self):
"""Returns the shape of a DICOM image as (rows, columns)."""Specialized tensor and PIL classes optimized for medical imaging display and processing.
class TensorDicom(TensorImage):
"""Tensor representation of DICOM images with grayscale display defaults."""
class PILDicom(PILBase):
"""PIL-based DICOM image loader with custom creation methods."""
class TensorCTScan(TensorImageBW):
"""Specialized tensor for CT scan data with bone colormap."""
class PILCTScan(PILBase):
"""PIL-based CT scan image loader."""Medical windowing operations for contrast and brightness adjustment using standard anatomical windows.
def windowed(self, w, l):
"""
Scale pixel intensity using window width (w) and window level (l).
Parameters:
- w: Window width (contrast range)
- l: Window level (brightness center)
Returns:
Windowed image tensor
"""
def pct_in_window(dcm, w, l):
"""
Calculate percentage of pixels within specified window.
Parameters:
- dcm: DcmDataset object
- w: Window width
- l: Window level
Returns:
Float percentage (0.0 to 1.0)
"""
# Predefined medical windows
dicom_windows = SimpleNamespace(
brain=(80,40),
subdural=(254,100),
stroke=(8,32),
brain_bone=(2800,600),
brain_soft=(375,40),
lungs=(1500,-600),
mediastinum=(350,50),
abdomen_soft=(400,50),
liver=(150,30),
spine_soft=(250,50),
spine_bone=(1800,400)
)Advanced normalization techniques using frequency histogram equalization for optimal contrast.
def freqhist_bins(self, n_bins=100):
"""
Split pixel value range into groups with equal pixel counts.
Parameters:
- n_bins: Number of histogram bins (default: 100)
Returns:
Tensor of bin boundaries
"""
def hist_scaled(self, brks=None, min_px=None, max_px=None):
"""
Scale tensor/DICOM using frequency histogram to values between 0 and 1.
Parameters:
- brks: Custom bin boundaries (optional, computed if None)
- min_px: Minimum pixel value clipping (DcmDataset only)
- max_px: Maximum pixel value clipping (DcmDataset only)
Returns:
Normalized tensor with values in [0,1]
"""Convert single DICOM images to multi-channel representations using multiple medical windows.
def to_nchan(self, wins, bins=None):
"""
Convert to multi-channel image using multiple windows.
Parameters:
- wins: List of (width, level) window tuples
- bins: Histogram bins for additional normalized channel (None includes it, 0 excludes it)
Returns:
Multi-channel TensorCTScan
"""
def to_3chan(self, win1, win2, bins=None):
"""
Convert to 3-channel image using two windows plus optional normalized channel.
Parameters:
- win1: First window (width, level) tuple
- win2: Second window (width, level) tuple
- bins: Include normalized channel (default: True)
Returns:
3-channel TensorCTScan
"""Specialized filtering operations optimized for medical images.
def uniform_blur2d(x, s):
"""
Apply uniform blurring using 2D convolution.
Parameters:
- x: Input tensor
- s: Blur kernel size
Returns:
Blurred tensor
"""
def gauss_blur2d(x, s):
"""
Apply Gaussian blur using kornia filters.
Parameters:
- x: Input tensor
- s: Gaussian sigma value
Returns:
Gaussian blurred tensor
"""Automatic mask generation and anatomical region cropping for focused analysis.
def mask_from_blur(self, window, sigma=0.3, thresh=0.05, remove_max=True):
"""
Create binary mask from blurred windowed image.
Parameters:
- window: Windowing parameters (w, l) tuple
- sigma: Gaussian blur sigma relative to image size
- thresh: Threshold for mask creation
- remove_max: Remove maximum intensity pixels
Returns:
Binary mask tensor
"""
def mask2bbox(mask):
"""
Convert binary mask to bounding box coordinates.
Parameters:
- mask: Binary mask tensor
Returns:
Bounding box tensor [x1, y1, x2, y2]
"""
def crop_resize(x, crops, new_sz):
"""
Crop and resize image using bounding box coordinates.
Parameters:
- x: Input tensor
- crops: Bounding box coordinates
- new_sz: Target size (int or tuple)
Returns:
Cropped and resized tensor
"""Export processed medical images to standard formats with proper scaling and compression.
def save_jpg(self, path, wins, bins=None, quality=90):
"""
Save tensor or DICOM as multi-channel JPEG.
Parameters:
- path: Output file path
- wins: List of windowing parameters
- bins: Include normalized channel
- quality: JPEG quality (0-100)
"""
def save_tif16(self, path, bins=None, compress=True):
"""
Save as 16-bit TIFF image.
Parameters:
- path: Output file path
- bins: Histogram binning parameters
- compress: Enable TIFF compression
"""
def to_uint16(self, bins=None):
"""
Convert to 16-bit unsigned integer array.
Parameters:
- bins: Histogram binning parameters
Returns:
numpy uint16 array
"""Specialized data loaders for medical image segmentation tasks with DICOM support.
class DicomSegmentationDataLoaders(DataLoaders):
"""Specialized data loaders for DICOM segmentation tasks."""
@classmethod
def from_label_func(cls, path, fnames, label_func, valid_pct=0.2, seed=None,
codes=None, item_tfms=None, batch_tfms=None, **kwargs):
"""
Create DICOM segmentation DataLoaders from label function.
Parameters:
- path: Base data path
- fnames: List of DICOM filenames
- label_func: Function to get segmentation mask from filename
- valid_pct: Validation split percentage
- seed: Random seed for splitting
- codes: Segmentation class codes
- item_tfms/batch_tfms: Data transformations
Returns:
DicomSegmentationDataLoaders instance
"""Extract and process DICOM metadata for analysis and quality control.
def as_dict(self, px_summ=True, window=dicom_windows.brain):
"""
Convert DICOM header to dictionary with optional pixel statistics.
Parameters:
- px_summ: Include pixel statistics (min, max, mean, std)
- window: Window for percentage calculation
Returns:
Dictionary of DICOM tags and statistics
"""
@classmethod
def from_dicoms(cls, fns, n_workers=0, **kwargs):
"""
Create pandas DataFrame from multiple DICOM files (attached to pd.DataFrame).
Parameters:
- fns: List of DICOM file paths
- n_workers: Number of parallel workers
- **kwargs: Additional arguments for as_dict
Returns:
DataFrame with DICOM metadata
"""from fastai.medical.imaging import *
# Load DICOM files
dicom_files = get_dicom_files('/path/to/dicoms')
dcm = dicom_files[0].dcmread()
# Display with medical windowing
dcm.show(scale=dicom_windows.brain)
# Create multi-channel representation
multi_chan = dcm.to_3chan(dicom_windows.brain, dicom_windows.subdural)from fastai.medical.imaging import *
from fastai.vision.all import *
# Setup medical image classification
items = get_dicom_files(path/"train")
df = pd.read_csv(path/"labels.csv")
dblock = DataBlock(
blocks=(ImageBlock(cls=PILDicom), CategoryBlock),
get_x=lambda x: path/x['file'],
get_y=lambda x: x['label'],
batch_tfms=[*aug_transforms(size=224), Normalize.from_stats(*imagenet_stats)]
)
dls = dblock.dataloaders(df.values)
learn = vision_learner(dls, resnet34, metrics=accuracy)
learn.fit_one_cycle(5)# DICOM segmentation pipeline
path = untar_data(URLs.TCGA_SMALL)
codes = np.loadtxt(path/'codes.txt', dtype=str)
fnames = get_dicom_files(path/'dicoms')
def get_mask(fn):
return path/'labels'/f'{fn.stem}.png'
dls = DicomSegmentationDataLoaders.from_label_func(
path, fnames, get_mask, codes=codes, bs=4,
item_tfms=[Resize(256)],
batch_tfms=[*aug_transforms(size=224), Normalize.from_stats(*imagenet_stats)]
)
learn = unet_learner(dls, resnet34)
learn.fit_one_cycle(10)# Advanced processing workflow
dcm = dicom_file.dcmread()
# Generate mask and crop region of interest
mask = dcm.mask_from_blur(dicom_windows.brain, sigma=0.5)
bbox = mask2bbox(mask)
cropped = crop_resize(dcm.scaled_px[None], bbox[...,None], 256)[0]
# Export processed images
dcm.save_jpg('processed.jpg', [
dicom_windows.brain,
dicom_windows.subdural,
dicom_windows.bone
])
# Batch metadata analysis
dicom_files = get_dicom_files(path)
df = pd.DataFrame.from_dicoms(dicom_files, n_workers=4)# External types (from pydicom)
DcmDataset # PyDicom dataset object
DcmTag # PyDicom tag object
DcmMultiValue # PyDicom multi-value objectInstall with Tessl CLI
npx tessl i tessl/pypi-fastai