
简介这份腹部14器官分割数据集面向医学图像分割方向的学习者与研究者尤其适合正在做3D UNet、nnUNet等腹部多器官分割实验的同学。数据以3D医学nii.gz格式提供共30个样本及对应标签可用ITK-SNAP直接打开查看标注覆盖背景、脾脏、右肾、左肾、胆囊、食道、肝脏、胃、主动脉、下腔静脉、门静脉和脾静脉、胰腺、左右肾上腺共14类具体英文类别可参考随包json文件。资源包共61个文件以60个gz数据与标签文件和1个json类别说明为主压缩包约953.26MB采用7z格式打包目录结构清晰便于按训练集与标签集分别读取。目前已有713人学习下载适合需要真实腹部CT标注数据来搭建分割流程、验证模型效果或复现相关UNet项目的读者参考使用。1. 腹部14器官分割数据集从 nii.gz 文件到 3D 医学分割的第一道门槛拿到一个腹部 14 器官分割数据集很多人第一反应是直接喂给模型结果卡在第一步——nii.gz 文件打不开或者打开了发现方向不对、标签对不上、层厚不一致。腹部 14 器官分割数据集基于 3D 的医学 nii.gz 格式本质上是一批带体素级标注的 CT 或 MRI 容积数据覆盖肝、脾、肾、胰、胃、胆囊、食管、肾上腺、十二指肠、空肠、回肠、结肠、直肠、膀胱等腹腔与盆腔器官。它的核心价值在于你不需要从零标注可以直接用来训练 3D 分割网络比如 nnU-Net、V-Net、Swin UNETR 这类架构。适合谁做医学影像 AI 的算法工程师、影像组学研究者、以及想把 2D 分割经验迁移到 3D 的深度学习从业者。但前提是你得先搞懂 nii.gz 这个格式的脾气否则后面全是玄学。2. nii.gz 格式拆解与 3D 医学数据的读取逻辑2.1 为什么医学分割偏爱 nii.gz 而不是 png 序列nii.gz 是 NIfTI 格式的 gzip 压缩版本它把三维容积数据、仿射矩阵、体素间距、方向信息打包在一个文件里。和 png 序列相比它不会丢失层间距信息也不会因为文件名排序错误导致层面错位。腹部 CT 的层厚通常是 0.5 到 5 毫米不等层内像素间距可能是 0.6 到 1.0 毫米这种各向异性的体素在 nii.gz 里由 pixdim 字段精确记录。如果你把它转成 png 序列再读回来这些信息就丢了模型会把 5 毫米层厚和 0.6 毫米层内间距当成等向的分割边界直接糊掉。常见做法是用 nibabel 或 SimpleITK 读取保留原始仿射矩阵后续做重采样和归一化时才有依据。2.2 用 Python 读取 nii.gz 并检查关键元数据import nibabel as nib import numpy as np # 读取图像和标签 img nib.load(case_001_ct.nii.gz) label nib.load(case_001_seg.nii.gz) # 获取数据数组注意 dtype 和形状 img_data img.get_fdata() # float64形状 (X, Y, Z) label_data label.get_fdata() # float64标签通常是整数 # 关键元数据检查 print(图像形状:, img_data.shape) print(体素间距:, img.header.get_zooms()) # (sx, sy, sz) print(仿射矩阵:\n, img.affine) print(标签唯一值:, np.unique(label_data)) print(图像强度范围:, img_data.min(), img_data.max())这段代码的逻辑是先加载两个文件然后分别检查形状、体素间距、仿射矩阵和标签值。get_fdata()返回 float64 数组对于标签建议用np.asanyarray(label.dataobj)避免不必要的类型转换。体素间距的第三个值就是层厚如果它和层内间距差异大说明数据是各向异性的后续训练时要么做重采样到等向要么在数据增强时注意不要在 Z 轴做大幅旋转。标签唯一值必须核对腹部 14 器官的标签通常是 1 到 14如果出现 0 以外的非整数说明标注文件有问题。图像强度范围用于判断是否需要做窗宽窗位调整腹部 CT 的 HU 值通常在 -1000 到 3000 之间但有些数据集已经做过归一化范围可能是 0 到 1。2.3 仿射矩阵与方向最容易翻车的地方仿射矩阵决定了体素坐标到世界坐标的映射也决定了你看到的图像方向。不同扫描仪、不同重建软件导出的 nii.gz 可能带有不同的方向编码比如 RAS、LAS、LPS。如果你直接用 matplotlib 的imshow看某一层可能发现图像是上下颠倒或左右镜像的。更严重的是如果图像和标签的仿射矩阵不一致即使形状相同体素也可能对不上。我一般会先做一次方向统一用nib.as_closest_canonical()把图像转到 RAS 方向同时用同样的变换处理标签。注意这个操作会改变数据数组的形状所以必须在重采样之前做。另一个坑是有些数据集的标签仿射矩阵是单位矩阵而图像是真实仿射这种情况下标签和图像的空间对应关系是错的需要手动把图像的仿射赋给标签或者用resample_from_to做对齐。3. 从原始 nii.gz 到可训练张量预处理流水线怎么搭3.1 重采样到统一体素间距选 1.5mm 还是 2.0mm腹部 14 器官分割的公开数据集里原始层厚差异很大。有的薄层 CT 是 0.5mm有的常规 CT 是 5mm。直接混合训练会导致模型对层厚敏感薄层数据学到的细节在厚层数据上失效。常见做法是把所有数据重采样到统一的体素间距比如 1.5mm × 1.5mm × 1.5mm 或 2.0mm × 2.0mm × 2.0mm。选 1.5mm 能保留更多细节但显存占用大选 2.0mm 显存友好但对小器官如肾上腺、胆囊的分割精度会下降。我一般会先统计数据集的体素间距分布如果大部分数据层厚在 1mm 到 3mm 之间就选 1.5mm如果很多数据层厚超过 3mm选 2.0mm 更稳妥。重采样用 SimpleITK 的ResampleImageFilter插值方式图像用线性插值标签用最近邻插值否则标签会出现小数。import SimpleITK as sitk def resample_image(image, target_spacing, is_labelFalse): original_spacing image.GetSpacing() original_size image.GetSize() target_size [ int(round(original_size[i] * original_spacing[i] / target_spacing[i])) for i in range(3) ] resampler sitk.ResampleImageFilter() resampler.SetSize(target_size) resampler.SetOutputSpacing(target_spacing) resampler.SetOutputOrigin(image.GetOrigin()) resampler.SetOutputDirection(image.GetDirection()) resampler.SetInterpolator( sitk.sitkNearestNeighbor if is_label else sitk.sitkLinear ) return resampler.Execute(image)这段代码的核心是计算目标尺寸保持物理尺寸不变。target_size是原始物理长度除以目标间距四舍五入取整。SetOutputOrigin和SetOutputDirection保持和原图一致避免空间错位。插值器选择是关键标签必须用最近邻否则会出现 1.5 这种无意义的标签值。图像用线性插值虽然会轻微模糊但比最近邻的锯齿好。重采样之后图像的形状会变标签的形状必须和图像完全一致可以用sitk.Resample对标签做同样的操作或者用resample_from_to把标签重采样到图像空间。3.2 窗宽窗位调整与强度归一化腹部 CT 的 HU 值怎么处理腹部 CT 的原始 HU 值范围很大从空气的 -1000 到骨骼的 1000 以上。但腹部器官的软组织对比度主要集中在 -100 到 200 之间。如果直接把原始 HU 值喂给网络模型会被骨骼和空气的高对比度吸引忽略软组织边界。常见做法是做窗宽窗位裁剪比如腹部窗设为 WL40, WW400对应范围是 -160 到 240。裁剪之后再做归一化到 [0, 1] 或 z-score 标准化。我一般会先裁剪到 [-160, 240]然后除以 400 映射到 [0, 1]。注意这个操作只对图像做标签不动。有些数据集已经做过归一化范围是 0 到 1这时候不要再做窗宽窗位否则会破坏原始对比度。判断方法很简单看图像强度范围如果 min 接近 -1000就是原始 HU如果 min 接近 0就是已经归一化过。3.3 数据增强3D 场景下哪些增强不能乱用2D 分割里常用的随机旋转、翻转、缩放在 3D 医学数据里要谨慎。腹部器官有固定的解剖位置肝在右上腹脾在左上腹如果做左右翻转肝脏跑到左边模型会学到错误的解剖先验。所以左右翻转不能用上下翻转也不能用。随机旋转要限制角度一般 ±15 度以内否则器官会转到不自然的位置。缩放可以做但要注意保持体素间距的物理意义缩放后要重新计算 spacing。弹性形变可以用但幅度要小否则会把器官边界扭曲得不像真实解剖。我一般会用的增强包括随机旋转 ±10 度、随机缩放 0.9 到 1.1、随机弹性形变控制点间距 30mm形变幅度 5mm、随机亮度对比度扰动。注意所有增强必须同时作用于图像和标签标签用最近邻插值。4. 避坑与排查腹部 14 器官分割数据处理的 5 个血泪教训4.1 标签值不连续模型输出全零现象训练时 loss 一直不降预测结果全是背景。原因标签文件里器官的标签值不是 1 到 14 连续整数而是比如 1, 2, 3, 5, 8, 13中间缺了 4, 6, 7。模型输出通道数按 14 设但实际有效类别只有 6 个交叉熵计算时大量通道没有正样本梯度被背景主导。解决先统计所有标签文件的唯一值取并集重新映射成 0 到 N 的连续整数保存映射表。推理时再映射回去。4.2 图像和标签形状不一致广播报错现象数据加载时报错说图像和标签形状不匹配。原因图像和标签在重采样时用了不同的目标尺寸或者一个做了方向统一另一个没做。解决所有空间变换必须成对操作图像和标签用同一个变换矩阵。建议写一个apply_transform(image, label, transform)函数确保两者始终同步。4.3 层厚差异导致小器官消失现象胆囊、肾上腺在厚层数据上分割 Dice 接近 0。原因厚层数据层厚 5mm小器官在 Z 轴只有两三层重采样到 1.5mm 后虽然层数变多但信息是插值出来的没有新增细节。解决对小器官做单独评估如果数据集中厚层数据占比高考虑在损失函数里给小器官更高权重或者用两阶段分割先定位再细分。4.4 仿射矩阵单位化导致空间错位现象图像和标签看起来形状一样但叠加显示时器官位置偏移。原因标签的仿射矩阵是单位矩阵而图像是真实仿射。解决用nibabel的resample_from_to把标签重采样到图像空间或者手动把图像的 affine 赋给标签前提是形状一致。4.5 显存爆炸batch size 只能设 1现象3D 数据直接输入网络显存不够batch size 降到 1 还是 OOM。原因3D 卷积的显存占用是 2D 的立方级增长。解决用 patch-based 训练从每个容积里随机裁剪 128×128×128 或 96×96×96 的 patchbatch size 可以设 2 到 4。推理时用滑窗重叠率 0.5。另外混合精度训练和梯度检查点也能省显存。5. 用 nnU-Net 跑通腹部 14 器官分割从数据准备到推理的完整命令nnU-Net 是目前医学分割里最省心的框架它自动处理体素间距、patch size、网络深度等超参数。但前提是数据格式要符合它的要求。你需要把 nii.gz 文件整理成特定目录结构每个病例一个文件夹里面放_0000.nii.gz图像和.nii.gz标签。标签值必须是连续整数背景为 0。然后运行nnUNetv2_plan_and_preprocess做预处理它会自动重采样到中位体素间距并生成 patch 配置。训练用nnUNetv2_train推理用nnUNetv2_predict。我一般会先跑 2D 配置做快速验证再跑 3D 全分辨率。注意nnU-Net 默认用 5 折交叉验证如果数据量少可以只跑单折。推理时用--save_probabilities保存概率图方便后续做后处理。最后用nnUNetv2_evaluate_folder算 Dice 和 HD95。这套流程跑通后腹部 14 器官的平均 Dice 通常能到 0.85 以上小器官如胆囊、肾上腺可能在 0.6 到 0.7 之间。如果小器官指标太低可以试试在 nnU-Net 的损失函数里加 focal loss或者用 Tversky loss 调整 FP/FN 权重。我自己踩过的坑是nnU-Net 对标签值很敏感如果标签里有 15 或 -1它会直接报错所以预处理第一步就是清洗标签。希望帮到你。本文还有配套的精品资源点击获取