news 2026/9/15 4:37:43

CT肾脏结石检测:YOLOv5数据集详解与训练调参实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CT肾脏结石检测:YOLOv5数据集详解与训练调参实践

简介:这是一份面向目标检测初学者及医学影像AI研究者的CT图像肾脏与结石检测数据集,已按YOLOv5格式整理,包含结石与肾脏两个类别,训练集325张、验证集135张,均配有对应txt标签文件。压缩包共923个文件,含460张JPG图像、461个txt标注文件及1个Python可视化脚本,整体大小约17MB。图像统一为640×640的RGB分辨率,来自CT扫描场景,边界框标注清晰完整,适合直接用于YOLOv5系列模型的训练与评估。压缩包内另附可视化py脚本,无需修改即可随机读取图片并绘制检测框,保存至当前目录,便于快速预览标注效果。整个数据集按datasets-images-train和datasets-images-val目录组织,结构直观,省去手动转换格式的步骤。目前已有132人学习下载,适合作为医学目标检测教学、课程设计或算法验证的入门数据。

1. 这套 CT 肾脏结石数据集,为什么建议直接拿来训练

做 CT 影像检测的同学大概都经历过这种尴尬:模型框架选 YOLOv5 只花一个小时,真正耗掉两周的是清洗 DICOM、裁剪窗口、转格式和逐张标框。这套 CT 肾脏与结石检测数据集压缩后仅 17 MB,460 张 640×640 的 RGB 图像,已经按 YOLOv5 的 images/labels 标准结构组织好,训练集 325 张、验证集 135 张,类别只有肾脏和结石 2 类,标签是 YOLO 格式的 txt 文件。拿过来写一个 data.yaml 就能直接开始迭代,省掉最枯燥的预处理环节。对正在做医学影像检测落地的工程师,它适合作为小样本迁移学习的起点;对熟手来说,真正值得读的是 CT 灰度影像在 YOLOv5 数据管线下的特殊问题,比如结石这类小目标的标注校验、类别不均衡对 mAP 的影响,以及可视化脚本怎么帮你快速判断标注可信度。

2. 目录结构与标签格式:YOLOv5 直接能读的 640×640 CT 图像

2.1 压缩包内的标准目录与同名配对机制

从文件名Stone-698-_jpg.rf.bb061fedc493e2891511718a880d0d29.jpg可以看出,这套数据保留了 Roboflow 导出时的命名习惯,.rf是导出工具自动追加的哈希标识。Roboflow 导出 YOLOv5 格式时默认按 images 和 labels 分好目录,解压后整体结构应该是这样的。

datasets/ └── Stone-704/ ├── images/ │ ├── train/ │ │ ├── Stone-698-_jpg.rf.bb061fedc493e2891511718a880d0d29.jpg │ │ └── ... 共 325 张 640×640 图像 │ └── val/ │ └── ... 共 135 张 ├── labels/ │ ├── train/ │ │ ├── Stone-698-_jpg.rf.bb061fedc493e2891511718a880d0d29.txt │ │ └── ... 共 325 个标签文件 │ └── val/ │ └── ... 共 135 个 └── data.yaml

YOLOv5 的 dataloader 在读取训练样本时,会自动把图片后缀.jpg替换为.txt去 labels 对应目录里找同名文件。所以图片与标签的同名关系是硬约束,其次才是目录名约定。这里保留.rf哈希不影响配对,只要不自己改文件名就行。如果下载后手动重命名过文件,训练时会出现大量 “No labels found” 警告,这一点比目录层级错误更隐蔽。

2.2 两个类别的 txt 标签:类别 ID 与归一化坐标

每一张图片对应的 txt 文件里,每一行代表一个标注框,共五个值,顺序固定为:类别 ID、归一化中心点 x、归一化中心点 y、归一化宽度、归一化高度。

0 0.5281 0.4122 0.1783 0.2418 1 0.4469 0.3850 0.0521 0.0675

第一列 0 或 1 是类别 ID,ID 从 0 开始计数,恰好对应两个类别,与 data.yaml 里 names 列表的下标一一对应。后面四个值全部做了归一化,实际像素坐标需要乘以图像的宽或高。例如输入图是 640×640,某框中心点 x 的归一化值为 0.5281,则像素坐标为 0.5281 乘以 640,约等于 338。宽高同理。YOLOv5 在训练时会对原图做 letterbox 缩放,如果标签是绝对像素坐标,缩放时要跟着做同步变换;归一化坐标天然免疫缩放,这是从 darknet 时代继承下来的标准约定,也是这套数据集不需要额外脚本就能直接训练的原因。

2.3 类别含义与 data.yaml 的 names 对齐

根据数据集说明,检测目标为两类,推荐映射关系如下。

类别 IDnames 推荐名称目标含义
0stone结石,CT 图像中通常表现为高密度亮斑
1kidney肾脏,完整器官轮廓

实际下载的数据集里 data.yaml 的 names 顺序可能与此不同,使用前必须打开文件核对。如果 names 顺序与标注 ID 对不上,训练过程不会报错,但验证时 kidney 的 AP 会被记到 stone 名下,模型权重也随之错位。我拿到任何数据集的第一件事,就是把 data.yaml 里的 names 和一张可视化结果对着看,确认类别颜色和标签文字。

2.4 CT 灰度图与 YOLOv5 RGB 输入的适配问题

CT 原生影像是单通道灰度,这套数据集则将灰度拷贝为三通道的 RGB 图再存为 640×640 的 JPG。YOLOv5 模型第一个卷积层接收三通道输入,JPG 的 RGB 存储可以直接喂给模型,不需要额外转换。但要注意,YOLOv5 默认数据增强里有 HSV 色彩抖动,对 CT 这类语义完全依赖灰度结构的数据来说,颜色抖动没有意义,还可能在灰度值分布上引入不必要的扰动,这一点到第 5 章超参调整时会给出具体配置建议。

3. 训练/验证划分与 data.yaml:把 325/135 跑进 YOLOv5 流程

3.1 为什么 325 + 135 的留出法划分是合理配置

训练集 325 张、验证集 135 张,验证集占比约 29%。这个比例不是随手切的:验证集足够大,每个类别在验证阶段有足够多的正样本框做 AP 统计;如果验证集只有二三十张,mAP 的方差会很大,调参时很难判断模型是变好了还是随机波动。460 张图对 YOLOv5 来说属于小规模医学数据集,必须依赖 COCO 预训练权重做迁移学习,不能随机初始化训练。肾脏是大目标,轮廓清晰,容易学;结石是小目标,可能只占十几个像素,对 anchor 尺寸和输入分辨率都比较敏感,这在后面的超参数调整里是关键矛盾。

3.2 data.yaml:拿过来唯一需要改的配置

使用这个数据集时,训练前唯一必须写对的文件就是 data.yaml。YOLOv5 的 train.py 读取其中的 path、train、val、nc、names 五个字段。

# data.yaml path: ./datasets/Stone-704 # 数据集根目录,images 和 labels 的上一级 train: images/train # 训练图片目录,相对 path val: images/val # 验证图片目录,相对 path nc: 2 # 类别数量:结石 + 肾脏 names: 0: stone 1: kidney

path 建议用相对路径。换成别的机器或云 GPU 训练时,只要仓库根目录不变,data.yaml 就不用改。这里的 train 和 val 指向的是图片目录而不是标签目录,YOLOv5 会自动去同级的 labels 下找对应 txt 文件。常见错误是把 train 写成 images/train/ 的绝对路径,同时还指定了 labels 路径,导致加载两次;实际上 val 目录也必须有同名标签文件,验证集没标签就完全无法计算 mAP。

3.3 训练前校验:查数量、查空标签、查类别分布

正式训练之前,我习惯用一组命令快速验证数据完整性,避免训练两小时后才发现标签路径有问题。

# 1. 统计图片与标签文件总数 find datasets/Stone-704/images -name "*.jpg" | wc -l find datasets/Stone-704/labels -name "*.txt" | wc -l # 2. 查找空标签文件(图片存在但没有标注) find datasets/Stone-704/labels -type f -size 0 -name "*.txt" # 3. 统计全部标签中的类别 ID 分布 cat datasets/Stone-704/labels/train/*.txt datasets/Stone-704/labels/val/*.txt \ | awk '{print $1}' | sort | uniq -c

第一个命令输出图片总数,预期为 460,与 labels 的 txt 数量一致。第二个命令查找 0 字节标签文件,一旦存在,对应图片会被 YOLOv5 在训练时跳过并打出警告。第三个命令把训练集和验证集的标签全部打平,取每行第一列做计数,输出类似285 0320 1的结果,表示类别 0 出现 285 次、类别 1 出现 320 次。如果出现了大于等于 2 的 ID,说明类别数与 names 不匹配;如果某个 ID 完全没出现,该类别在训练中会缺少正样本,AP 直接为 0。

3.4 训练命令与参数选择

数据校验通过后,执行训练的命令如下。

python train.py --img 640 --batch 8 --epochs 120 \ --data datasets/Stone-704/data.yaml \ --weights yolov5s.pt --device 0

参数含义:--img 640与数据集原始分辨率一致,避免额外的 letterbox 缩放损失;--batch 8在 6 GB 显存上跑 yolov5s 是安全值,显存低于 6 GB 就降到 4;--epochs 120是小数据集的常见区间,太少欠拟合,太多则过拟合,训练时重点观察最后一个 epoch 的 val loss 是否回升;--weights yolov5s.pt表示加载 COCO 预训练权重做迁移学习。在 3080 级别显卡上,460 张图的 120 epoch 完整训练大约 30 到 50 分钟。第一次跑建议加--epochs 5先验证数据加载和 loss 下降是否正常,再跑完整训练。

4. 可视化脚本:一条命令验证标注框是否贴合 CT 病灶

4.1 为什么先可视化而不是直接训练

目标检测项目的第一个教训:不要相信 txt 里的坐标。CT 图像对比度低,肾脏与周围组织边界模糊,结石可能只占几个像素;如果标注框框偏了或类别标反,模型在推理时会按照同样偏置的位置输出错误检测结果。可视化脚本的价值,是把标注质量在训练之前用图像直接暴露出来。数据集附带一个可视化 py 文件,设计逻辑是随机抽取一张图片,读取同名 txt 标签,把归一化坐标还原成像素坐标,绘制边界框和类别名,最后保存到当前目录。

4.2 核心实现:归一化坐标还原与逐框绘制

下面这段代码复刻了可视化脚本的核心逻辑,可以直接运行,不需要命令行参数。

import cv2 import os import random import glob CLASS_NAMES = ["stone", "kidney"] # 必须与 data.yaml 的 names 顺序一致 COLORS = [(0, 255, 0), (0, 0, 255)] def draw_one(image_path, label_path, save_path): # 1. 读图,取原始宽高作为坐标还原的基准 img = cv2.imread(image_path) h, w = img.shape[:2] # 2. 逐行读取 YOLO 标签:类别ID + 归一化的中心x/y/宽/高 with open(label_path, "r", encoding="utf-8") as f: for line in f: parts = line.strip().split() if len(parts) != 5: continue cls_id = int(parts[0]) x_c, y_c, bw, bh = map(float, parts[1:]) # 3. 归一化坐标还原为像素坐标(中心式转左上/右下角) x1 = int((x_c - bw / 2.0) * w) y1 = int((y_c - bh / 2.0) * h) x2 = int((x_c + bw / 2.0) * w) y2 = int((y_c + bh / 2.0) * h) # 4. 边界裁剪,防止标注超出图像范围导致绘图报错 x1, y1 = max(0, x1), max(0, y1) x2, y2 = min(w - 1, x2), min(h - 1, y2) cv2.rectangle(img, (x1, y1), (x2, y2), COLORS[cls_id], 2) cv2.putText(img, CLASS_NAMES[cls_id], (x1, max(0, y1 - 8)), cv2.FONT_HERSHEY_SIMPLEX, 0.7, COLORS[cls_id], 2) cv2.imwrite(save_path, img) def main(): train_images = glob.glob(os.path.join("images", "train", "*.jpg")) random.seed(2024) img_path = random.choice(train_images) label_path = img_path.replace("images", "labels").replace(".jpg", ".txt") draw_one(img_path, label_path, "visual_result.jpg") if __name__ == "__main__": main()

这段代码的关键在第三步的换算。YOLO 标签存的是「中心点 + 宽高」的归一化值,全部除以过原图尺寸,因此还原像素时先乘以 w 或 h,再把中心坐标展开成左上角和右下角两个角点。第四步的越界保护对应 CT 图像边界上被截断的器官或紧贴图像边缘的结石,标注框略微超出图像时,cv2.rectangle 会报错,裁剪后问题消失。CLASS_NAMES必须与 data.yaml 的 names 顺序一致,如果 names 是['kidney', 'stone'],这里的两项要对调,否则标注文字与真实类别错位。

归一化坐标到像素坐标的换算可以按下面这张表速查。

标签值换算公式640×640 图像上的像素结果
x_c = 0.52810.5281 × 640338
y_c = 0.41220.4122 × 640264
bw = 0.17830.1783 × 640114
bh = 0.24180.2418 × 640155

4.3 我一般会顺手做的两种标注质量检查

随机抽样看一张图,只能证明脚本能跑通。我通常会再补两种检查:一是手动固定抽一张多目标图,打开对应的 txt 文件,如果行数很多,说明这张图有多个结石框,专门看这类小目标框是否框住了完整的强回声斑块,而不是只框住亮点中心;二是按类别分别统计所有标注框的宽高像素值,结石的框宽高通常在几十像素以内,如果出现几百像素的结石框,大概率是把整片肾脏区域误标成了结石,这种标注会直接影响小目标的 anchor 匹配。

5. 小目标与类别不均衡:YOLOv5 在 CT 检测中的调参与排错

5.1 针对 2 类 CT 检测的超参数调整清单

在 460 张小数据集上直接跑默认参数,通常会出现两个问题:结石小目标漏检,以及两个类别样本数不均导致 mAP 涨得慢。对照 yolov5s 自带的hyp.scratch-low.yaml,针对这套 CT 数据的调整建议如下。

超参数默认值CT 场景建议调整理由
mosaic1.00.5四图拼接会把结石缩小到原来的四分之一,小目标更难学
hsv_h / hsv_s / hsv_v0.015 / 0.7 / 0.40 / 0 / 0CT 是灰度影像,颜色抖动无增益
fliplr0.50.5腹部左右对称,水平翻转不破坏语义
degrees0.05.0小幅旋转容忍体位偏差,大角度旋转不建议

把以上字段写入hyp_ct.yaml,训练时通过--hyp传入。

python train.py --img 640 --batch 8 --epochs 120 \ --data datasets/Stone-704/data.yaml \ --weights yolov5s.pt \ --hyp hyp_ct.yaml --device 0

5.2 验证阶段重点看 per-class AP 而不是总 mAP

训练完成后,用 val.py 输出每个类别的 AP。

python val.py --data datasets/Stone-704/data.yaml \ --weights runs/train/exp/weights/best.pt \ --img 640 --task val

如果 stone 的 AP 明显低于 kidney,优先检查 anchor 而不是盲目加数据。YOLOv5 默认 anchor 是 COCO 尺度聚类的结果,CT 结石远小于 COCO 中的常见目标,可以重新用 kmeans 对训练集标注框做聚类,把新 anchor 写回模型 yaml 后重新训练,这一步对结石的 recall 提升往往比调 loss 更直接。

5.3 训练中常见的三个坑

日志里出现WARNING: No labels found,先查 data.yaml 的 path 与 labels 目录是否存在,而不是改代码。某个类别 AP 全程为 0,回到第 3.3 节的uniq -c命令核对类别 ID 是否实际存在。loss 出现 nan,通常是小 batch 下学习率偏大,batch 4 时把--lr0 0.01降到 0.001 再试。验证时如果想知道模型到底漏在哪一类目标,可以加--save-txt --save-conf把预测结果导出成 txt,与真实标签做逐框对比,漏检的是极小的结石还是被遮挡的肾脏,看导出文件就能定位到具体切片。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 4:36:47

微电网两阶段鲁棒优化算法与Matlab实现

1. 微网多电源容量配置的挑战与两阶段鲁棒优化算法概述微电网作为分布式能源系统的重要形态,其电源容量配置直接影响着系统经济性和可靠性。传统确定性优化方法在面对风光出力不确定性、负荷波动等现实因素时,往往表现出配置方案保守或抗风险能力不足的缺…

作者头像 李华
网站建设 2026/9/15 4:35:56

遗传算法突变风险测试:DEAP/PIT/Hypothesis三款工具实战指南

做软件测试这些年,我接过不少“算法型”系统的测试任务,最头疼的往往不是功能逻辑,而是那种“跑十次结果十个样”的随机性系统。尤其是基于基因算法(Genetic Algorithm,国内也叫遗传算法)的程序——它靠选择…

作者头像 李华
网站建设 2026/9/15 4:35:29

CISP认证2026版考试指南与高效备考策略

1. CISP认证核心价值解析CISP(Certified Information Security Professional)作为国内信息安全领域最具权威性的专业认证之一,其含金量主要体现在三个维度:首先,它是由中国信息安全测评中心直接颁发的国家级证书&#…

作者头像 李华
网站建设 2026/9/15 4:34:58

本地运行AI助手:从成本失控到算力自主的实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 4:34:48

免费企业网站模板php实战案例:5个规范救活丑站

免费企业网站模板php实战案例:5个规范救活丑站 还在忍受那种一眼假、排版乱的免费PHP模板?真的,模板网站太丑不够用是常态。很多兄弟花大价钱买的“高端模板”,上线后客户还是跑单,问题出在哪?不是代码,是设计没章法。我见过太多 实战案例…

作者头像 李华