CT肺结节检测YOLO数据集:从标注格式到训练实战
2026/9/13 13:09:12 网站建设 项目流程

简介:面向医学影像与目标检测学习者的YOLO肺结节检测数据集,提供5000张真实场景高质量图片,涵盖丰富数据场景,并使用LabelImg标注,标注框质量高。压缩包内包含VOC(xml)、COCO(json)和YOLO(txt)三种格式标签,分别存放于不同文件夹,可直接用于YOLO系列模型训练。资源共2000个文件,主要是1986个xml标签文件,另有说明文档html、核心脚本py与列表txt,整体大小77.56MB。除数据外,附赠YOLO环境搭建与训练教程(区分Linux/Windows版本)、数据集划分脚本,可自行划分训练集、验证集、测试集,便于快速上手实践。目前已有402人学习下载,适合计算机视觉初学者、医学影像研究人员及需要标准格式数据集进行算法验证的开发者使用。更多详情可参考作者博客。

1. 从 5000 张 CT 切片到可训练的 YOLO 模型:一份肺结节检测数据集的完整拆解

医学影像 AI 落地难,第一步往往不是模型选型,而是数据和标注格式的统一。最近处理一个肺结节检测需求,拿到这份 YOLO 肺结节目标检测数据集,包含 5000 张真实 CT 影像切片,且同时提供 VOC(xml)、COCO(json)、YOLO(txt) 三种标注格式,外加三个数据集划分脚本和完整的 YOLO 训练教程(区分 Linux 与 Windows)。这套资源把「数据准备 → 格式对齐 → 数据集划分 → 模型训练」整个链路补齐了,适合正在做医学影像目标检测、想快速在 YOLO 系列上跑通肺结节任务的开发者,也适合课程设计、毕业设计需要真实医学数据集的学生。它不是公开数据集那种几十张演示图片,而是可以实际送入训练管线、能跑出收敛曲线的完整数据包。下文从数据格式差异讲起,逐步拆解划分脚本逻辑,再给出训练配置与排错要点。

2. 三种标注格式的底层差异:VOC、COCO、YOLO 各自解决什么问题

2.1 格式本质:XML 树形结构 vs JSON 字典 vs 归一化文本

肺结节检测的数据格式转换,核心是理解三种格式对「一个目标」的表述方式差异。用 LabelImg 标注后的原始产物是 VOC 格式的 XML 文件,它把图像信息(宽度、高度、通道数)和目标框(xmin, ymin, xmax, ymax)用树形节点组织。COCO 格式则是一个大型 JSON 字典,包含imagesannotationscategories三个顶层数组,目标框以[x, y, width, height]的绝对像素值存储在 annotations 中。YOLO 格式最紧凑,每行一个目标,五个数字依次是class_id, x_center, y_center, width, height,全部归一化到 0-1。

# VOC xml 中一个目标节点的典型结构 <object> <name>nodule</name> <bndbox> <xmin>102</xmin> <ymin>203</ymin> <xmax>158</xmax> <ymax>267</ymax> </bndbox> </object>

XML 的优势在于人类可读性高,用文本编辑器就能检查标注框是否合理;劣势是单张图片的标注信息冗余较多,批量读取时需要遍历 XML 树。COCO 的 JSON 结构更适合用键值对快速索引,比如想知道某张图片有哪些标注对象,直接按image_id过滤即可,但修改数据时要保证字典内部的一致性。YOLO 格式最省存储空间,且与 Darknet 框架和 Ultralytics YOLO 的训练管线直接兼容,这也是为什么 YOLOv5、YOLOv8、YOLOv9 系列都默认读取 txt 标注的原因。

2.2 坐标体系转换:像素绝对坐标与归一化坐标的换算逻辑

数据集在 VOC 和 YOLO 格式间转换时,最常出的问题在坐标计算的舍入误差。VOC 的xmin, ymin, xmax, ymax是整数像素坐标,转换成 YOLO 归一化格式时必须除以图片宽高:

# VOC -> YOLO 坐标转换核心逻辑 import os def voc_to_yolo(xml_file, img_width, img_height, output_txt): # 解析 xml 中的每个 object # 对每个标注框执行归一化计算 # x_center = ((xmin + xmax) / 2) / img_width # y_center = ((ymin + ymax) / 2) / img_height # box_width = (xmax - xmin) / img_width # box_height = (ymax - ymin) / img_height # 将 class_id 和四个浮点数写入 txt,每行一个目标 pass

注意浮点数保留位数,常见做法是保留 6 位小数。保留位数太少会导致目标框在训练时产生偏移,尤其是肺结节这种小目标,本身可能只有十几个像素的宽高,归一化后约 0.01 量级,如果只保留 2 位小数,信息几乎丢失。转换脚本里最好用format(coord, '.6f')控制输出精度。

2.3 类别映射与数据一致性检查

拿到这份肺结节数据集,第一步不要急着训练,先做一致性校验。打开三个格式文件夹,确认类别编号是否完全对齐:VOC 的<name>标签、COCO 的 categories 数组中的id字段、YOLO txt 中每行的第一个数字,三者必须指向同一个语义类别。比如肺结节在 VOC 中命名为nodule,那 COCO 的 categories 里就应该有{"id": 0, "name": "nodule"},YOLO txt 中类别编号为 0。一个常见的坑是标注工具导出的 COCO 格式可能从 1 开始编号,而 YOLO 训练配置要求类别从 0 开始,转换时需要做偏移修正。

# 统计三种格式的类别分布,排查标注异常 # 统计 YOLO txt 中所有类别编号 cat labels_train/*.txt | awk '{print $1}' | sort | uniq -c

提示:训练前花十分钟做格式一致性检查,能省下后面排查 loss 异常的两个小时。重点看类别编号是否连续从 0 排列,以及有没有空标注文件混入训练集。

3. 数据集划分脚本实战:训练集、验证集、测试集的正确切分姿势

3.1 脚本清单与适用场景分析

压缩包中附带三个 Python 脚本,功能定位各不相同。第一个「训练集、验证集划分脚本」和第二个「训练集、验证集、测试集划分脚本」分别适用二划分和三划分场景,第三个「split_train_val生成ImageSets下txt文件划分脚本.py」走的是更贴近 PASCAL VOC 传统的目录组织方式。实际项目里,训练集、验证集、测试集的比例通常设为 8:1:1 或 7:2:1。如果数据总量只有 5000 张,选择 7:2:1 更稳妥,因为验证集需要足够多的样本才能稳定评估模型在各类别上的表现,尤其肺结节检测中正负样本不均衡,验证集太小会导致 mAP 指标波动剧烈。

3.2 按文件夹复制 vs 生成 txt 索引的两种实现

三划分脚本实现的是「物理划分」策略,即将图片及其对应标签文件复制进新的 train、val、test 文件夹。这种做法方便人工检查数据分布,但会占用双倍磁盘空间。另一种做法是生成 train.txt、val.txt、test.txt,只记录图片路径,训练时由 dataloader 按列表读取,资源占用小且更灵活,YOLO 官方训练代码支持这种索引文件方式。

# 三划分脚本核心逻辑(按文件列表复制) import os, shutil, random all_imgs = [f for f in os.listdir('images') if f.endswith('.jpg')] random.seed(42) # 固定随机种子,保证复现 random.shuffle(all_imgs) train_ratio, val_ratio = 0.7, 0.2 train_n = int(len(all_imgs) * train_ratio) val_n = int(len(all_imgs) * val_ratio) train_set = all_imgs[:train_n] val_set = all_imgs[train_n:train_n + val_n] test_set = all_imgs[train_n + val_n:] # 对每个文件,同时复制图片和同名标签文件到对应目标目录 for subset_name, file_list in [('train', train_set), ('val', val_set), ('test', test_set)]: os.makedirs(f'{subset_name}/images', exist_ok=True) os.makedirs(f'{subset_name}/labels', exist_ok=True) for img_file in file_list: shutil.copy(f'images/{img_file}', f'{subset_name}/images/') label_file = img_file.replace('.jpg', '.txt') # 假设图片和标签同名 if os.path.exists(f'labels/{label_file}'): shutil.copy(f'labels/{label_file}', f'{subset_name}/labels/')

这里的random.seed(42)是关键,固定随机种子后才能保证多次划分得到完全相同的分组结果,这对实验可复现性至关重要。注意在复制时只复制与图片同名的 txt 标注,避免把无关文件混入训练目录。标签文件缺失时用os.path.exists判断并跳过,防止脚本崩溃。

3.3 划分后的体检项:漏标、错标、路径不一致

划分完成不等于数据准备好了。有三个体检项必须做。第一,统计每张图片的标注框数量,排查是不是有大量图片没有任何标注框——这些在目标检测里是纯背景样本,可以保留但不宜过多,否则模型会偏向预测背景。第二,检查图片与标签是否一一对应,用 find 命令对比文件名集合差集。

# 对比 images 和 labels 目录中的文件名,找出不一致项 ls images | sed 's/.jpg$//' | sort > img_names.txt ls labels | sed 's/.txt$//' | sort > label_names.txt diff img_names.txt label_names.txt

第三,检查是否有重复图片。5000 张 CT 切片来自多个患者病例,医学数据中相邻切片可能高度相似甚至相同,重复样本会让训练集和验证集之间存在数据泄漏,导致 mAP 虚高。常见做法是计算图片的 MD5 哈希值去重:

md5sum images/*.jpg | sort | uniq -w 32 -d

提示:训练集和测试集之间的重复样本,会让测试集上的 mAP 数值失去参考意义。医学影像数据尤其要注意这个坑。

4. YOLO 环境搭建与训练流程:从 Darknet 到 Ultralytics 的完整路径

4.1 环境依赖版本选择:Linux 和 Windows 各自的坑

压缩包中的环境搭建教程区分了 Linux 和 Windows 两个版本。以当前主流的 Ultralytics YOLOv8 为例,Linux 环境推荐 Python 3.8-3.10,CUDA 版本 11.8-12.1,对应 PyTorch 2.0+。Windows 环境首先需要注意 CUDA 驱动版本与 PyTorch 的匹配关系——不是 CUDA 装得越高越好,而是要保证显卡驱动支持目标 CUDA 版本。

# Linux 环境下安装 Ultralytics YOLO conda create -n yolo python=3.9 conda activate yolo pip install ultralytics torch torchvision --index-url https://download.pytorch.org/whl/cu118

Windows 上的差异主要在于路径分隔符和文件权限。使用 Anaconda Prompt 执行以上命令时,建议将 conda 环境创建在非系统盘,避免文件权限导致的写盘失败。如果显卡是 NVIDIA 的 GTX 16 系或 RTX 20 系,CUDA 11.8 比 12.1 更稳定,因为部分老卡在 CUDA 12 下会出现AssertionError: CUDA out of memory的误报——实际是显存管理差异,而非真正的显存不足。

4.2 数据集配置文件与 YAML 写法

YOLOv8 训练时通过一个 YAML 文件指定数据路径和类别映射。针对这个肺结节数据集,配置如下:

# lung_nodule.yaml train: ./datasets/lung_nodule/train # 训练集图片目录 val: ./datasets/lung_nodule/val # 验证集图片目录 test: ./datasets/lung_nodule/test # 测试集图片目录(可选) nc: 1 # 类别数量,这里只有一类:肺结节 names: ['nodule']

路径写法上注意两点:第一,用相对路径容易出问题,训练时如果工作目录切换,路径解析会失败,建议写成绝对路径或用os.path.abspath转换;第二,在 Windows 上路径分隔符建议统一用正斜杠/,避免反斜杠转义字符在 YAML 解析时出问题。

4.3 训练命令与关键超参数

训练启动命令在 Linux 和 Windows 上基本一致,核心超参数包括imgszbatchepochspatience

# 单卡训练命令 yolo detect train data=lung_nodule.yaml model=yolov8n.pt epochs=100 batch=16 imgsz=640 patience=20 device=0 # Windows 无 GPU 时使用 CPU 训练 yolo detect train data=lung_nodule.yaml model=yolov8n.pt epochs=50 batch=8 imgsz=640 device=cpu

由于肺结节本身是小目标,imgsz建议从 640 起步,如果显存允许可以升到 1024,小目标检测效果会有明显提升。batch大小视显存而定,RTX 3060 12G 显存跑 YOLOv8n 时 batch 可以设 16,如果报显存不足就减半。patience是早停参数,连续 20 个 epoch 验证集 mAP 没有提升就自动停止,省时间。

Batch 参数对医学图像训练尤为重要,CT 切片灰度图通道数虽少,但输入分辨率提高后显存占用增长很快。如果单卡 batch 上不去,一个折中方案是用梯度累积,Ultralytics 没有直接暴露该参数,需要手动在训练循环里改accumulate逻辑。

4.4 模型选型建议:n、s、m、l 怎么选

YOLOv8 提供了 n/s/m/l/x 五个规模,对应不同的参数量和推理速度。肺结节检测中,由于数据量只有 5000 张,不建议一上来就选 l 或 x 这两个大模型——参数越多越容易过拟合,医学数据标注成本高,数据增强空间有限。用 YOLOv8n 做 baseline,跑通整个流程、确认 loss 正常下降后,再尝试 YOLOv8s 或 YOLOv8m 提升精度。

如果追求更高的检测精度,也可以试试 YOLOv9 或 YOLOv11,Ultralytics 的接口统一,配置文件不用改。但要注意不同版本的model参数写法略有差异:YOLOv9 用yolov9c.pt,YOLOv11 用yolo11n.pt,训练时data参数完全相同。

# 切换到 YOLOv11 训练(同样支持上述 yaml 配置) yolo detect train data=lung_nodule.yaml model=yolo11n.pt epochs=100 imgsz=640 device=0

5. 数据增强策略与验证技巧:在不增加标注量的前提下提升 mAP

5.1 医学影像特定的增强手段

通用目标检测的数据增强(如 Mosaic、MixUp)在医学影像上要谨慎使用。以肺结节检测为例,CT 切片的像素值分布有解剖学含义,过度的颜色抖动和随机擦除可能生成不符合医学逻辑的样本。推荐优先使用以下增强组合:随机水平翻转、小幅旋转、缩放平移、轻度亮度对比度调整。在 Ultralytics 中通过augment=True启用默认增强,但建议自定义增强参数:

# augment.yaml 自定义增强配置(训练时用 augment=augment.yaml 覆盖默认值) hsv_h: 0.0 # 色调不变 hsv_s: 0.0 # 饱和度不变 hsv_v: 0.1 # 明度轻微调整 degrees: 10 # 旋转角度 ±10 度 translate: 0.1 # 平移比例 10% fliplr: 0.5 # 水平翻转概率 50% mosaic: 0.5 # Mosaic 概率降低,防止小目标被切割

CT 图像不需要色调与饱和度增强,保留默认值反而会引入噪声。将 Mosaic 概率从默认的 1.0 降到 0.5,是因为 Mosaic 把四张图拼在一起时会缩小目标占比,肺结节原本可能只有 32x32 像素,再缩小后信息几乎不可辨识。医学影像中,空间变换类增强(旋转、平移、翻转)比颜色变换更安全。

5.2 模型验证:超过训练 loss 的参考指标

训练完成后,不要只盯着loss曲线。在目标检测任务中,验证集的mAP@0.5mAP@0.5:0.95才是真正的考核指标。用以下命令在测试集上评估:

yolo detect val data=lung_nodule.yaml model=runs/detect/train/weights/best.pt

评估输出中需要重点看三个数值:mAP@0.5反映了定位和分类的综合质量,0.8 以上说明模型基本可用;mAP@0.5:0.95对边界框精度要求更高,一般比 mAP@0.5 低 10-20 个百分点属正常;各别类的 Precision/Recall 单独看,如果 Recall 远低于 Precision,说明有大量肺结节漏检,优先用降低置信度阈值的方式推理,找到漏检的原因。推理时,正式诊断辅助场景建议把conf设到 0.15-0.25,宁可多一些误检框也不放过可能的结节:

yolo predict model=best.pt source=test_images conf=0.2 iou=0.5

5.3 遇到 loss 不下降的排错清单

训练中遇到 loss 震荡或 mAP 始终为 0,按以下顺序排查:第一,用yolo train data=lung_nodule.yaml model=yolov8n.pt epochs=5跑一个极短的实验,确认数据加载流程是否顺畅,如果这一步报错,多半是 YAML 中路径配置问题。第二,检查标注框是否过小,CT 切片中 10 像素以下的标注框对模型训练几乎没有贡献,考虑过滤或扩大输入分辨率。第三,显存充足但模型的 loss 在 3 个 epoch 内不下降,将学习率从默认的 0.01 调低到 0.001,看看是否缓解。第四,确认类别平衡,如果 5000 张图里包含大量无结节切片,单类训练影响不大,但多类场景就要考虑采样权重了。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询