Working with DICOM Images in Python for Deep Learning
Introduction
DICOM (Digital Imaging and Communications in Medicine) is the international standard for medical images and related information. In this cookbook, we'll learn how to read DICOM files using Python, extract metadata, handle windowing/leveling (Hounsfield Units), and prepare the pixel data for PyTorch deep learning models using MONAI.
Architecture Overview
graph LR
DICOM(Raw DICOM Files) --> Pydicom(Pydicom Extract Metadata)
DICOM --> Window(Window / Leveling)
Window --> NIfTI(Optional: dcm2niix to NIfTI)
Window --> MONAI(MONAI Transform Pipeline)
MONAI --> Tensor(PyTorch Tensors)
Prerequisites
- Python 3.8+
- pydicom, MONAI, and dcm2niix installed
Step 1: Install Dependencies
pip install pydicom monai matplotlib numpy torch dcm2niix
Step 2: Read DICOM Metadata with pydicom
DICOM files contain more than just pixels; they hold critical PHI and scanner metadata.
import pydicom
# Load the DICOM file
ds = pydicom.dcmread('sample_image.dcm')
# Access metadata
print(f"Patient ID: {ds.PatientID}")
print(f"Modality: {ds.Modality}")
print(f"Study Date: {ds.StudyDate}")
# Extract raw pixel array
pixels = ds.pixel_array
Step 3: Handling Hounsfield Units (CT Windowing)
Raw pixel arrays often need to be converted to Hounsfield Units (HU) using the Rescale Intercept and Rescale Slope metadata tags. We then apply a "window" to isolate specific tissues (e.g., lungs vs bone).
import numpy as np
def apply_windowing(image, ds, window_center, window_width):
# Apply Rescale Slope / Intercept
slope = getattr(ds, 'RescaleSlope', 1)
intercept = getattr(ds, 'RescaleIntercept', 0)
image = image * slope + intercept
# Calculate Window Level min/max
img_min = window_center - window_width // 2
img_max = window_center + window_width // 2
# Clip and normalize
image = np.clip(image, img_min, img_max)
image = (image - img_min) / (img_max - img_min)
return image
# Example: Lung Window (Center: -600, Width: 1500)
lung_window_img = apply_windowing(pixels, ds, -600, 1500)
Step 4: Converting DICOM series to NIfTI
For 3D convolutional networks, it is often easier to convert a folder of 2D DICOM slices into a single 3D NIfTI volume using dcm2niix.
# Assuming dcm2niix is installed on your system
dcm2niix -z y -o ./output_folder/ -f %p_%i ./dicom_folder/
Step 5: Build a Data Loading Pipeline with MONAI
When training models, we need efficient data loaders. MONAI provides DICOM and NIfTI-native transforms.
import monai
from monai.transforms import Compose, LoadImaged, EnsureChannelFirstd, ScaleIntensityd, ToTensord
# Define a transformation pipeline for a dictionary of image paths
transforms = Compose([
LoadImaged(keys=["image"]),
EnsureChannelFirstd(keys=["image"]),
ScaleIntensityd(keys=["image"]),
ToTensord(keys=["image"])
])
# Create a dataset and dataloader
data = [{"image": "sample_image.dcm"}]
dataset = monai.data.Dataset(data=data, transform=transforms)
dataloader = monai.data.DataLoader(dataset, batch_size=1)
# Iterate through batches
for batch in dataloader:
img_tensor = batch["image"]
print(img_tensor.shape) # e.g. [1, 1, 512, 512]
Conclusion
With pydicom, proper windowing techniques, and MONAI, preparing raw hospital DICOM streams for high-performance PyTorch models is seamless and efficient.