Brats2021数据集下载与预处理完整指南:从数据获取到实战应用

1次阅读
没有评论

共计 3240 个字符,预计需要花费 9 分钟才能阅读完成。

image.webp

数据集背景与下载痛点

Brats2021 是脑肿瘤分割领域公认的标杆数据集,包含多模态 MRI 扫描(T1、T1c、T2、FLAIR)及专家标注的肿瘤区域标签。其临床价值在于:

Brats2021 数据集下载与预处理完整指南:从数据获取到实战应用

  • 提供胶质瘤(Glioblastoma)的完整影像学特征
  • 包含术前和术后扫描数据
  • 标注覆盖坏死区 / 增强肿瘤 / 水肿等细分结构

但官方获取流程存在三大障碍:

  1. 需要注册多个医学数据平台账户(如 CBICA、TCIA)
  2. 数据分散在多个压缩包(总计约 250GB)
  3. 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"
        )

元数据处理注意事项

  1. 保留 DICOM 中的 PatientID 和 StudyDate
  2. 检查像素间距(PixelSpacing)是否一致
  3. 确认扫描方向(ImageOrientationPatient)

方案拓展

迁移到其他数据集

  1. 修改认证逻辑(如 TCIA 使用 API Key)
  2. 调整预处理参数(如 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
– 开发交互式质量检查工具

正文完
 0
评论(没有评论)