共计 3240 个字符,预计需要花费 9 分钟才能阅读完成。
数据集背景与下载痛点
Brats2021 是脑肿瘤分割领域公认的标杆数据集,包含多模态 MRI 扫描(T1、T1c、T2、FLAIR)及专家标注的肿瘤区域标签。其临床价值在于:

- 提供胶质瘤(Glioblastoma)的完整影像学特征
- 包含术前和术后扫描数据
- 标注覆盖坏死区 / 增强肿瘤 / 水肿等细分结构
但官方获取流程存在三大障碍:
- 需要注册多个医学数据平台账户(如 CBICA、TCIA)
- 数据分散在多个压缩包(总计约 250GB)
- DICOM 原始数据需转换为研究友好格式
自动化下载方案
身份认证处理
使用 Python 的 requests 库模拟浏览器登录,关键步骤:
import requests
from typing import Tuple
def get_auth_cookies(username: str, password: str) -> dict:
"""获取 CBICA 平台认证 cookies"""
login_url = "https://www.cbica.upenn.edu/login"
session = requests.Session()
try:
# 注意处理 SSL 证书验证
response = session.post(
login_url,
data={"username": username, "password": password},
verify="/path/to/cert.pem" # 医学平台常需自定义证书
)
response.raise_for_status()
return session.cookies.get_dict()
except requests.exceptions.RequestException as e:
print(f"认证失败: {str(e)}")
return {}
断点续传下载
通过 Content-Length 和Range头实现:
def download_file(url: str, save_path: str, cookies: dict, chunk_size=1024*1024):
"""支持断点续传的下载函数"""
headers = {"User-Agent": "Mozilla/5.0"}
try:
with requests.get(url, headers=headers, cookies=cookies, stream=True) as r:
r.raise_for_status()
total_size = int(r.headers.get('content-length', 0))
# 检查本地已下载部分
mode = 'ab' if os.path.exists(save_path) else 'wb'
downloaded_size = os.path.getsize(save_path) if mode == 'ab' else 0
if downloaded_size < total_size:
headers['Range'] = f'bytes={downloaded_size}-'
with requests.get(url, headers=headers, cookies=cookies, stream=True) as r:
with open(save_path, mode) as f:
for chunk in r.iter_content(chunk_size=chunk_size):
f.write(chunk)
except Exception as e:
print(f"下载中断: {str(e)}")
raise
数据格式转换
DICOM 转 NIFTI
使用 SimpleITK 处理扫描序列:
import SimpleITK as sitk
def dcm_to_nifti(dcm_dir: str, output_path: str):
"""将 DICOM 序列转为 NIFTI 格式"""
reader = sitk.ImageSeriesReader()
dicom_names = reader.GetGDCMSeriesFileNames(dcm_dir)
if not dicom_names:
raise ValueError("未找到有效 DICOM 文件")
reader.SetFileNames(dicom_names)
image = reader.Execute()
# 保留关键元数据
for key in ['0010|0020', '0020|000e']: # PatientID, SeriesInstanceUID
if reader.HasMetaDataKey(0, key):
image.SetMetaData(key, reader.GetMetaData(0, key))
sitk.WriteImage(image, output_path)
标准化预处理
强度归一化
采用 z -score 标准化处理各模态:
def normalize_intensity(image: np.ndarray, mask: np.ndarray) -> np.ndarray:
"""基于脑部 ROI 的强度归一化"""
brain_pixels = image[mask > 0]
mean = np.mean(brain_pixels)
std = np.std(brain_pixels)
return (image - mean) / (std + 1e-8)
MONAI 数据增强
构建训练 pipeline:
from monai.transforms import (
Compose, LoadImaged, AddChanneld, Spacingd,
ScaleIntensityRanged, RandRotated
)
train_transforms = Compose([LoadImaged(keys=["image", "label"]),
AddChanneld(keys=["image", "label"]),
Spacingd(keys=["image", "label"],
pixdim=(1.5, 1.5, 2.0), # 统一各向异性分辨率
mode=("bilinear", "nearest")
),
ScaleIntensityRanged(keys=["image"],
a_min=-100, # 根据模态调整
a_max=300,
b_min=0.0,
b_max=1.0
),
RandRotated(keys=["image", "label"],
range_x=0.3,
prob=0.5
)
])
避坑指南
速率限制处理
- 添加随机延迟(0.5- 2 秒)避免触发防护
- 使用代理 IP 池应对 IP 封锁
磁盘预警方案
import shutil
def check_disk_space(required_gb: float, path: str = '.'):
"""检查剩余磁盘空间"""
usage = shutil.disk_usage(path)
if usage.free < required_gb * 1024**3:
raise RuntimeError(f"需要{required_gb}GB 空间,当前仅剩{usage.free/1024**3:.1f}GB"
)
元数据处理注意事项
- 保留 DICOM 中的 PatientID 和 StudyDate
- 检查像素间距(PixelSpacing)是否一致
- 确认扫描方向(ImageOrientationPatient)
方案拓展
迁移到其他数据集
- 修改认证逻辑(如 TCIA 使用 API Key)
- 调整预处理参数(如 CT 数据的窗宽 / 窗位)
多模态融合策略
# 使用 torch.cat 进行通道融合
import torch
def fuse_modalities(t1: torch.Tensor, t2: torch.Tensor) -> torch.Tensor:
"""早期特征融合示例"""
return torch.cat([t1, t2], dim=1) # 沿通道维度拼接
结语
通过本文的自动化处理方案,开发者可快速获得研究可用的标准数据。建议进一步探索:
– 将预处理流程封装为 Docker 镜像
– 集成到 PyTorch Lightning 的 DataModule
– 开发交互式质量检查工具
正文完
