nnUNet数据集格式详解:轻松构建符合规范的医学影像数据集
【免费下载链接】nnUNet 项目地址: https://gitcode.com/gh_mirrors/nn/nnUNet
引言:你还在为医学影像数据集格式不统一而头疼吗?
医学影像分割领域的研究者和开发者常常面临一个共同挑战:如何准备符合主流框架要求的数据集。nnUNet(神经网络通用分割框架,Neural Network Universal Segmentation)作为医学影像分割的标杆工具,其数据集格式规范虽然强大但也较为严格。错误的格式会导致训练失败、结果异常或性能下降,浪费宝贵的计算资源。
本文将系统解析nnUNet的数据集格式规范,包括文件组织结构、命名约定、元数据配置等核心内容,并通过实例演示如何从零构建一个符合要求的医学影像数据集。读完本文后,你将能够:
- 理解nnUNet数据集的三大核心组成部分
- 正确组织训练/测试数据文件结构
- 编写符合规范的dataset.json元数据文件
- 处理多模态数据和不同影像格式
- 解决常见的数据格式错误和兼容性问题
一、nnUNet数据集核心组成
nnUNet数据集包含三个不可缺少的组件,三者协同工作确保框架能够正确解析和处理数据:
1.1 训练案例的构成
每个训练案例由图像集和对应的分割标签组成,通过唯一标识符(CASE_IDENTIFIER)关联:
- 图像集:每个输入通道(模态)单独存储为一个文件,通过文件名末尾的四位数字标识通道序号(如0000表示第一个通道,0001表示第二个通道)
- 分割标签:单个文件存储,包含整数型语义标签,背景必须为0,标签值需连续(0,1,2,...n)
关键要求:同一案例的所有图像和标签必须具有相同的空间几何(尺寸、间距、方向),且已完成配准。
1.2 支持的文件格式
nnUNet v2相比v1极大扩展了支持的文件格式,无需再将所有数据转换为NIfTI格式:
| 读取器/写入器 | 支持格式 | 适用场景 | 特殊说明 |
|---|---|---|---|
| NaturalImage2DIO | .png, .bmp, .tif | 2D自然图像 | 支持RGB三通道合并存储 |
| NibabelIO | .nii.gz, .nrrd, .mha | 3D医学影像 | 使用nibabel库处理 |
| NibabelIOWithReorient | .nii.gz, .nrrd, .mha | 需要重定向的影像 | 自动将影像重定向为RAS方向 |
| SimpleITKIO | .nii.gz, .nrrd, .mha | 3D医学影像 | 使用SimpleITK库处理 |
| Tiff3DIO | .tif, .tiff | 3D Tiff堆栈 | 需要额外.json文件存储 spacing信息 |
⚠️ 重要提示:所有文件必须使用无损压缩格式,禁止使用.jpg等有损压缩格式,以免破坏分割标签的准确性。
二、目录结构规范
nnUNet对数据集的目录结构有严格要求,正确的组织方式是成功训练的基础。
2.1 顶级目录结构
数据集必须存储在nnUNet_raw目录下,每个数据集作为独立子目录,命名遵循DatasetXXX_Name格式:
nnUNet_raw/
├── Dataset001_BrainTumour/ # 脑肿瘤数据集(示例)
├── Dataset002_Heart/ # 心脏数据集(示例)
├── Dataset003_Liver/ # 肝脏数据集(示例)
└── DatasetXXX_YourDataset/ # 自定义数据集
XXX:三位数字数据集ID(001-999),避免与现有数据集冲突Name:简洁描述数据集内容,使用大写字母和下划线
2.2 数据集内部结构
每个数据集目录包含以下子目录和文件:
DatasetXXX_YourDataset/
├── dataset.json # 数据集元数据配置文件(必需)
├── imagesTr/ # 训练集图像(必需)
├── imagesTs/ # 测试集图像(可选)
└── labelsTr/ # 训练集标签(必需)
2.2.1 多模态数据示例(以脑肿瘤数据集为例)
脑肿瘤数据集包含4个模态(FLAIR、T1w、T1gd、T2w),其文件结构如下:
Dataset001_BrainTumour/
├── dataset.json
├── imagesTr
│ ├── BRATS_001_0000.nii.gz # 案例BRATS_001,通道0(FLAIR)
│ ├── BRATS_001_0001.nii.gz # 案例BRATS_001,通道1(T1w)
│ ├── BRATS_001_0002.nii.gz # 案例BRATS_001,通道2(T1gd)
│ ├── BRATS_001_0003.nii.gz # 案例BRATS_001,通道3(T2w)
│ ├── BRATS_002_0000.nii.gz # 案例BRATS_002,通道0(FLAIR)
│ └── ...
├── imagesTs
│ ├── BRATS_485_0000.nii.gz # 测试案例BRATS_485,通道0
│ └── ...
└── labelsTr
├── BRATS_001.nii.gz # 案例BRATS_001的标签
├── BRATS_002.nii.gz # 案例BRATS_002的标签
└── ...
2.2.2 单模态数据示例(以心脏数据集为例)
心脏数据集仅包含1个模态,其文件结构如下:
Dataset002_Heart/
├── dataset.json
├── imagesTr
│ ├── la_003_0000.nii.gz # 案例la_003,通道0
│ ├── la_004_0000.nii.gz # 案例la_004,通道0
│ └── ...
├── imagesTs
│ ├── la_001_0000.nii.gz # 测试案例la_001,通道0
│ └── ...
└── labelsTr
├── la_003.nii.gz # 案例la_003的标签
├── la_004.nii.gz # 案例la_004的标签
└── ...
2.3 文件命名规范
nnUNet通过文件名建立图像与标签的关联,必须严格遵循以下命名规则:
2.3.1 图像文件命名
{CASE_IDENTIFIER}_{CHANNEL_ID}.{FILE_ENDING}
CASE_IDENTIFIER:案例唯一标识符(如BRATS_001、la_003)CHANNEL_ID:四位数字通道编号(0000至9999)FILE_ENDING:文件扩展名(如.nii.gz、.png)
示例:patient_001_0000.nii.gz表示患者001的第0个通道图像。
2.3.2 标签文件命名
{CASE_IDENTIFIER}.{FILE_ENDING}
示例:patient_001.nii.gz表示患者001的分割标签。
⚠️ 重要提示:同一案例的所有图像文件和标签文件必须使用完全相同的CASE_IDENTIFIER,确保nnUNet能够正确关联图像和标签。
三、dataset.json元数据文件详解
dataset.json是描述数据集元数据的关键文件,nnUNet通过它了解数据的通道组成、标签含义和文件格式。
3.1 核心字段说明
以某腺体数据集(Dataset005_Prostate)为例,标准的dataset.json结构如下:
{
"channel_names": {
"0": "T2",
"1": "ADC"
},
"labels": {
"background": 0,
"PZ": 1,
"TZ": 2
},
"numTraining": 32,
"file_ending": ".nii.gz",
"overwrite_image_reader_writer": "SimpleITKIO"
}
各字段的含义和要求:
| 字段 | 类型 | 描述 | 必要性 |
|---|---|---|---|
| channel_names | 对象 | 通道ID到通道名称的映射 | 必需 |
| labels | 对象 | 标签名称到整数值的映射 | 必需 |
| numTraining | 整数 | 训练案例数量 | 必需 |
| file_ending | 字符串 | 数据集文件扩展名 | 必需 |
| overwrite_image_reader_writer | 字符串 | 指定使用的读写器类 | 可选 |
3.2 字段详细解析
3.2.1 channel_names
定义每个通道的名称,影响nnUNet的归一化策略:
- 键(key):字符串形式的通道ID("0"、"1"等),对应文件名中的CHANNEL_ID
- 值(value):通道名称,若名称为"CT",nnUNet将使用CT专用的归一化方法;其他名称使用默认的z-score归一化
示例:
"channel_names": {
"0": "T1", // T1加权MRI
"1": "T2", // T2加权MRI
"2": "FLAIR", // FLAIR序列
"3": "CT" // CT图像(将使用特殊归一化)
}
3.2.2 labels
定义标签名称与整数值的映射,背景必须为0:
- 键(key):标签名称,建议使用描述性名称
- 值(value):整数标签值,必须从0开始连续编号(0,1,2,...n)
正确示例:
"labels": {
"background": 0,
"tumor_core": 1,
"edema": 2,
"enhancing_tumor": 3
}
错误示例:
"labels": {
"background": 1, // 错误:背景必须为0
"tumor": 3 // 错误:标签值不连续
}
3.2.3 numTraining
指定训练集案例数量,必须与imagesTr和labelsTr中的文件数量一致:
- 对于单模态数据:imagesTr中的文件数应等于numTraining
- 对于多模态数据(n个模态):imagesTr中的文件数应等于numTraining × n
3.2.4 file_ending
指定数据集使用的文件扩展名,所有图像和标签文件必须使用相同的扩展名:
常见取值:.nii.gz、.png、.tif等
3.2.5 overwrite_image_reader_writer(可选)
显式指定用于该数据集的图像读写器类,当自动检测失败时使用:
常见取值:"SimpleITKIO"、"NibabelIO"、"NaturalImage2DIO"等
3.3 特殊情况处理:3D Tiff图像
对于3D Tiff格式,需要为每个图像文件提供额外的.json文件存储空间信息:
文件结构:
imagesTr/
├── cell6.json // 空间信息文件
└── cell6_0000.tif // 3D Tiff图像
labelsTr/
├── cell6.json // 空间信息文件
└── cell6.tif // 3D Tiff标签
cell6.json内容:
{
"spacing": [7.6, 7.6, 80.0] // 各维度的像素间距(单位:毫米)
}
3.4 自动生成dataset.json
手动编写dataset.json容易出错,推荐使用nnUNet提供的生成工具:
python -m nnunetv2.dataset_conversion.generate_dataset_json
/path/to/dataset
-channel_names "0:channel_name_0" "1:channel_name_1"
-labels "background:0" "label1:1" "label2:2"
-file_ending .nii.gz
-numTraining 100
参数说明:
- 第一个参数:数据集根目录路径
- -channel_names:每个通道的ID和名称,格式为"ID:name"
- -labels:每个标签的名称和值,格式为"name:value"
- -file_ending:文件扩展名
- -numTraining:训练案例数量
四、实战指南:构建自己的nnUNet数据集
4.1 步骤概览
构建符合nnUNet规范的数据集通常需要以下步骤:
4.2 数据准备检查清单
在开始组织数据集前,确保原始数据满足以下条件:
- 所有图像和标签已完成配准
- 同一案例的多模态图像具有相同空间几何
- 标签为整数型,背景值为0,且标签值连续
- 图像和标签文件格式一致且为无损压缩
- 文件名不包含特殊字符(推荐使用字母、数字和下划线)
4.3 2D与3D数据的特殊处理
4.3.1 2D数据处理
nnUNet v2原生支持2D数据,无需再转换为伪3D格式:
- 使用NaturalImage2DIO读写器(支持.png、.bmp、.tif)
- RGB图像可合并存储在单个文件中,无需拆分通道
- 目录结构与3D数据相同,nnUNet会自动检测数据维度
2D数据集示例:
Dataset120_RoadSegmentation/
├── dataset.json
├── imagesTr
│ ├── road_001_0000.png # 道路图像(单通道)
│ ├── road_002_0000.png
│ └── ...
└── labelsTr
├── road_001.png # 道路分割标签
├── road_002.png
└── ...
4.3.2 3D数据处理
3D医学影像通常使用NIfTI格式(.nii.gz):
- 确保图像方向一致(推荐RAS方向)
- 检查并统一体素间距(可选,nnUNet会自动处理不同间距)
- 对于没有间距信息的格式(如3D Tiff),需提供额外的.json文件
4.4 常见错误与解决方案
| 错误类型 | 症状 | 解决方案 |
|---|---|---|
| 文件命名错误 | 训练时报"找不到标签"或"通道缺失" | 检查CASE_IDENTIFIER是否一致,通道编号是否连续 |
| 空间几何不匹配 | 预处理阶段报错"尺寸不匹配" | 使用SimpleITK或nibabel检查并统一图像尺寸和间距 |
| dataset.json格式错误 | 加载数据集时JSON解析错误 | 使用JSON验证工具检查语法,确保键名正确 |
| 标签值不连续 | 评估时指标异常或训练损失为0 | 重新映射标签值,确保从0开始连续编号 |
| 通道数量不匹配 | 训练时报"通道数量不一致" | 确保每个案例都包含所有通道的图像文件 |
五、数据集转换与迁移
5.1 从nnUNet v1迁移数据集
如果你有nnUNet v1的数据集,可使用官方提供的转换工具一键迁移:
nnUNetv2_convert_old_nnUNet_dataset \
/path/to/nnUNet_v1_TaskXXX \
DatasetXXX_NewName
参数说明:
- 第一个参数:v1数据集路径(包含ImagesTr、ImagesTs等文件夹)
- 第二个参数:新数据集名称(遵循DatasetXXX_Name格式)
5.2 医学影像分割挑战赛(MSD)数据集转换
MSD数据集可使用专用转换脚本转换为nnUNet格式:
nnUNetv2_convert_MSD_dataset \
/path/to/MSD/Task01_BrainTumour \
Dataset001_BrainTumour
5.3 自定义数据集转换示例
以一个假设的肺结节CT数据集为例,展示完整的转换过程:
5.3.1 原始数据结构
LungNoduleData/
├── train/
│ ├── patient001_ct.nii.gz
│ ├── patient001_seg.nii.gz
│ ├── patient002_ct.nii.gz
│ ├── patient002_seg.nii.gz
│ └── ...
└── test/
├── patient101_ct.nii.gz
├── patient102_ct.nii.gz
└── ...
5.3.2 转换步骤
- 创建目标目录结构:
mkdir -p nnUNet_raw/Dataset123_LungNodule/{imagesTr,labelsTr,imagesTs}
- 重命名并移动训练图像:
for i in $(ls LungNoduleData/train/*_ct.nii.gz); do
id=$(basename $i _ct.nii.gz)
cp $i nnUNet_raw/Dataset123_LungNodule/imagesTr/${id}_0000.nii.gz
done
- 重命名并移动标签:
for i in $(ls LungNoduleData/train/*_seg.nii.gz); do
id=$(basename $i _seg.nii.gz)
cp $i nnUNet_raw/Dataset123_LungNodule/labelsTr/${id}.nii.gz
done
- 处理测试集:
for i in $(ls LungNoduleData/test/*.nii.gz); do
id=$(basename $i _ct.nii.gz)
cp $i nnUNet_raw/Dataset123_LungNodule/imagesTs/${id}_0000.nii.gz
done
- 生成dataset.json:
python -m nnunetv2.dataset_conversion.generate_dataset_json \
nnUNet_raw/Dataset123_LungNodule \
-channel_names "0:CT" \
-labels "background:0" "nodule:1" \
-file_ending .nii.gz \
-numTraining 100
六、数据集验证与更新
6.1 数据集完整性验证
创建数据集后,建议使用nnUNet提供的验证工具检查完整性:
nnUNetv2_verify_dataset_integrity Dataset123_LungNodule
该工具将检查:
- 文件命名是否符合规范
- 所有训练案例是否有对应的标签
- 图像和标签的空间几何是否匹配
- dataset.json是否正确配置
6.2 数据集更新最佳实践
当需要更新数据集(如添加新案例或修正标签)时,应遵循以下步骤:
- 删除旧的预处理数据:
rm -rf nnUNet_preprocessed/DatasetXXX_Name
-
更新nnUNet_raw中的原始数据
-
重新运行预处理:
nnUNetv2_plan_and_preprocess -d XXX --verify_dataset_integrity
- (可选)删除基于旧数据的训练结果:
rm -rf nnUNet_results/DatasetXXX_Name
七、总结与最佳实践
构建符合nnUNet规范的数据集是成功训练模型的基础,关键要点包括:
- 严格遵循文件组织结构:使用DatasetXXX_Name命名,包含imagesTr、labelsTr和dataset.json
- 正确命名文件:使用统一的CASE_IDENTIFIER,图像文件包含通道编号
- 准确配置dataset.json:正确定义通道名称、标签映射和文件格式
- 确保数据质量:验证图像和标签的配准,检查标签连续性
- 使用提供的工具:利用转换和验证脚本减少手动错误
遵循这些规范和建议,将帮助你顺利构建高质量的nnUNet数据集,为后续的模型训练和推理打下坚实基础。正确的数据集准备不仅能避免训练过程中的技术问题,还能充分发挥nnUNet的性能优势,获得更准确的医学影像分割结果。
nnUNet的数据集规范虽然严格,但这种严格性正是其能够在各种医学影像分割任务上取得优异成绩的重要原因之一。花时间正确准备数据,将在后续实验中节省大量调试时间,并最终获得更好的结果。
附录:数据集格式检查清单
使用以下清单确保你的数据集符合所有要求:
目录结构
- 数据集位于nnUNet_raw目录下
- 数据集目录命名为DatasetXXX_Name
- 包含imagesTr、labelsTr目录
- imagesTs目录(如需要)已创建
文件命名
- 图像文件命名格式为{CASE_IDENTIFIER}_{XXXX}.{ENDING}
- 标签文件命名格式为{CASE_IDENTIFIER}.{ENDING}
- 同一案例的所有文件使用相同的CASE_IDENTIFIER
- 通道编号从0000开始连续编号
数据内容
- 所有图像和标签具有相同的空间几何
- 标签为整数类型,背景值为0
- 标签值从0开始连续编号
- 使用无损压缩格式
dataset.json
- 包含channel_names、labels、numTraining和file_ending字段
- channel_names中的键与图像文件的通道编号匹配
- labels中的值包含所有标签的整数映射
- numTraining与实际训练案例数量一致
- file_ending与实际文件扩展名匹配
通过这份详细指南,你现在应该能够构建一个完全符合nnUNet要求的医学影像数据集。正确的数据准备是成功的一半,这将确保你能够充分利用nnUNet的强大能力,获得出色的分割结果。
【免费下载链接】nnUNet 项目地址: https://gitcode.com/gh_mirrors/nn/nnUNet
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



