YOLOv5息肉检测实战:从数据配置到Tkinter界面全链路 简介这份资源面向医学影像分析人员、机器学习开发者及疾病筛查研发工程师提供一套基于YOLOv5的直肠息肉检测系统完整实现方案用于辅助医疗专家进行息肉自动检测与早期筛查。压缩包内共1个docx文档约41KB以图文形式系统梳理了从环境准备、数据预处理、数据集配置、模型训练到ONNX模型导出、性能评估、指标可视化再到GUI界面搭建与代码整合的完整流程并涵盖精确度、召回率、F1分数等评估指标说明。文档还探讨了多类别检测、数据增强、集成学习与云部署等未来改进方向并提示数据质量、硬件要求与过拟合监控等注意事项。目前已有120人学习适合希望快速掌握医疗图像目标检测落地流程、对照目录结构逐步实践并查漏补缺的读者参考。1. 从一张肠镜截图说起这套 YOLOv5 息肉检测系统到底能干什么肠镜室里最耗神的不是操作是盯着屏幕找那几毫米的隆起。一个熟练医师的漏检率依然存在而 YOLOv5 这类单阶段检测器恰好擅长在 640×640 的输入下做实时框选。这套资源给的不是一段孤立的推理脚本而是一条从数据目录组织、polyp.yaml配置、训练、ONNX 导出、指标可视化到 Tkinter 实时界面的完整链路附带可运行的程序和数据。它适合三类人想拿医学图像练手 YOLOv5 的算法工程师、需要给筛查流程加一层辅助框选的研发、以及要交一个能跑起来的课程设计的学生。核心价值在于把训练自己的数据集这件事拆成了可复现的九步而不是丢一个权重让你猜怎么来的。下面按我实际拆包的顺序讲参数怎么设、哪里会翻车都落到具体命令上。2. 环境与数据把 YOLOv5 训练链路先跑通2.1 依赖安装与版本对齐这套资源基于 YOLOv5PyTorch 是底座。原文给的安装命令带了cu113索引说明作者是在 CUDA 11.3 环境下验证的。我一般会先确认显卡驱动支持的 CUDA 上限再决定装哪个 wheel否则会出现torch.cuda.is_available()返回 False 的经典翻车。# 先看驱动能支持到哪个 CUDA 版本 nvidia-smi # 按驱动上限选 wheelcu113 只是原文验证过的组合 pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu113 # 图像处理、绘图、GUI、导出四件套 pip install opencv-python matplotlib tkinter onnx逻辑说明torch系列必须一次装齐版本错位会导致torchvision的 C 扩展加载失败。tkinter在部分 Linux 发行版里是系统包而非 pip 包如果pip install tkinter报找不到改用apt install python3-tk。参数上cu113不是必须它只是原文的验证环境你按nvidia-smi右上角的 CUDA Version 往下选一档更稳。接着克隆 YOLOv5 仓库并装它自己的依赖git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txtrequirements.txt里锁定了numpy、pillow、pyyaml等版本这一步别跳过直接复用你环境里的旧版 numpy 很容易在results.render()时炸出 dtype 错误。2.2 数据集目录与 polyp.yaml 配置YOLO 格式对目录结构有硬性约定图片和同名 txt 标签必须成对。资源里给的结构是标准的 images/labels 双分支polyp_data/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/标签 txt 每行是class x_center y_center width height全部归一化到 0~1。这里最常见的坑是坐标没归一化训练时 loss 直接飙到 nan。配置文件polyp.yaml只有四行但每一行都关键train: ../polyp_data/images/train val: ../polyp_data/images/val nc: 1 # 类别数息肉只有一类 names: [polyp]逻辑说明train和val是相对polyp.yaml所在位置的路径不是相对项目根目录写错会报No labels found。nc必须和标签里的最大 class id 对齐只有一类就写 1写成 0 或 2 都会在构建检测头时报维度不匹配。names的顺序决定类别索引单类场景下写[polyp]即可。提示验证集别用训练集切出来的同一批图否则 mAP 虚高评估指标失去意义。3. 训练、导出与评估参数怎么设才不白跑3.1 训练命令与关键超参原文的训练命令是--img 640 --batch 16 --epochs 50 --weights yolov5s.pt。这套组合对单类小数据集是合理的起点但每个参数都有边界。python train.py \ --img 640 \ --batch 16 \ --epochs 50 \ --data polyp.yaml \ --weights yolov5s.pt逻辑说明--img 640是 YOLOv5 的默认输入尺寸医学图像里息肉占比往往很小盲目降到 320 会让小目标特征在 P3 层就丢干净。--batch 16取决于显存8G 显存跑 640 大概能到 16爆显存就减半并配合--accumulate补回等效批量。--epochs 50对单类是够的但要看results.csv里mAP_0.5是否还在涨早停了浪费晚停了过拟合。--weights yolov5s.pt是 COCO 预训练权重从零训在小数据集上几乎不可能收敛这一步别省。训练产物落在runs/train/exp/其中weights/best.pt是后续所有环节要用的文件。如果exp已存在YOLOv5 会自动递增为exp2、exp3脚本里写死exp路径的人经常在这里翻车。3.2 ONNX 导出与 val 评估训练完导出 ONNX是为了脱离 PyTorch 环境部署比如后续往 RK3568 这类边缘设备量化迁移时会用到。python export.py \ --weights runs/train/exp/weights/best.pt \ --img-size 640 \ --batch-size 1 \ --device 0 \ --include onnx逻辑说明--batch-size 1是导出动态轴时的稳妥选择批量导出容易在推理端 shape 对不上。--device 0指定 GPUCPU 导出会慢很多但结果一致。--include onnx只导 ONNX需要 TensorRT 就再加engine。导出后同目录会出现best.onnx用onnxruntime加载验证一次输入输出维度别等到部署端才发现。评估用val.pypython val.py \ --weights runs/train/exp/weights/best.pt \ --data polyp.yaml \ --img 640逻辑说明val.py会输出 Precision、Recall、mAP0.5、mAP0.5:0.95。单类息肉检测重点看 Recall漏检比误检代价高。如果 Recall 明显低于 Precision说明模型偏保守可以调低推理时的--conf-thres或在训练时增加正样本比例。3.3 指标可视化脚本原文用 matplotlib 读results.csv画损失和精度曲线这个思路对但列名要按实际 CSV 来。import matplotlib.pyplot as plt import pandas as pd # results.csv 由 train.py 自动生成列名含空格需注意 data pd.read_csv(runs/train/exp/results.csv) data.columns data.columns.str.strip() # 去掉列名首尾空格 plt.figure(figsize(12, 6)) plt.subplot(1, 2, 1) plt.plot(data[epoch], data[train/box_loss], labelBox Loss, colorblue) plt.title(Box Loss over Epochs) plt.xlabel(Epoch) plt.ylabel(Loss) plt.grid() plt.subplot(1, 2, 2) plt.plot(data[epoch], data[metrics/precision], labelPrecision, colorgreen) plt.title(Precision over Epochs) plt.xlabel(Epoch) plt.ylabel(Precision) plt.grid() plt.tight_layout() plt.show()逻辑说明原文写的data[loss]和data[precision]在实际results.csv里并不存在真实列名是train/box_loss、metrics/precision这种带斜杠的。data.columns.str.strip()是血泪经验YOLOv5 某些版本导出的列名带前导空格直接索引会 KeyError。参数上figsize和subplot布局按需调不影响数据。4. Tkinter 实时界面从摄像头到框选渲染4.1 推理循环与渲染GUI 部分用 Tkinter 加 OpenCV 摄像头核心是把model(frame)的结果渲染回图像再塞进 Label。import cv2 import tkinter as tk from PIL import Image, ImageTk import torch def recognize_polyp(): cap cv2.VideoCapture(0) # sourcelocal 强制走本地权重避免联网拉取 model torch.hub.load(ultralytics/yolov5, custom, pathruns/train/exp/weights/best.pt, sourcelocal) while True: ret, frame cap.read() if not ret: break results model(frame) frame results.render()[0] # 渲染检测框 img Image.fromarray(frame) img ImageTk.PhotoImage(imageimg) panel.imgtk img # 必须保留引用否则图像不显示 panel.config(imageimg) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()逻辑说明sourcelocal是关键参数不加的话torch.hub.load会尝试联网检查仓库版本离线环境直接卡死。panel.imgtk img这行看着多余实则是 Tkinter 的经典坑——不保留引用PhotoImage 会被 GC 回收界面一片空白。results.render()[0]返回的是 BGR numpy 数组转 PIL 时颜色通道要对否则框选颜色会偏。4.2 按钮整合与线程问题原文把训练、导出、评估、可视化、检测五个功能都挂到按钮上思路清晰但有个隐患recognize_polyp里的while True会阻塞 Tkinter 主线程点完Start Detection后其他按钮全部失灵。import threading def start_detection_thread(): t threading.Thread(targetrecognize_polyp, daemonTrue) t.start() start_button tk.Button(root, textStart Detection, commandstart_detection_thread) start_button.pack()逻辑说明把推理循环丢进 daemon 线程主线程继续响应按钮。daemonTrue保证关窗时线程跟着退出不然进程会挂住。注意 Tkinter 的控件更新不是线程安全的严格做法是用root.after轮询队列但单窗口 demo 里直接更新 Label 通常也能跑属于可接受的简化。注意训练、导出、评估这三个按钮背后是长耗时脚本直接绑command会让界面假死建议同样走线程或改成子进程调用。5. 避坑与排查这套代码最容易翻车的五个地方5.1 报 No labels found现象train.py启动后直接退出提示找不到标签。原因polyp.yaml里的train路径是相对 yaml 文件本身不是相对项目根目录或者 labels 目录里 txt 文件名和图片没对上。解决进到polyp.yaml所在目录用ls ../polyp_data/labels/train | head确认 txt 存在且文件名不含扩展名和 images 里一一对应。5.2 CUDA out of memory现象训练几个 batch 后爆显存。原因--batch 16对 8G 以下显存偏大或--img 640叠加了 mosaic 增强导致峰值显存上升。解决--batch 8配合--accumulate 2保持等效批量或临时--img 512。别直接关 mosaic小数据集上它对抗过拟合有用。5.3 导出 ONNX 后推理结果全错现象PyTorch 权重检测正常ONNX 输出框全乱。原因导出时--img-size和推理时输入尺寸不一致或没做 letterbox 预处理。解决导出和推理统一 640推理端严格复现 YOLOv5 的 letterbox等比缩放加灰边填充别直接 resize。5.4 GUI 图像不刷新或闪退现象点开始检测后窗口空白或几秒后崩溃。原因PhotoImage引用被回收或摄像头被其他程序占用导致cap.read()返回 False 后循环没退出。解决保留panel.imgtk引用cap.read()失败时break并释放确认没有其他程序占着摄像头。5.5 评估指标虚高现象val.py的 mAP 接近 1.0实际用起来漏检严重。原因验证集和训练集有重叠图片或标签泄漏。解决按病人维度划分训练/验证集同一病人的不同帧不能跨集这是医学图像最容易被忽视的坑。6. 进阶技巧把单类检测推到能用的边界这套资源给的是单类息肉检测的基线真要用起来有几个我踩过之后固定下来的习惯。第一是推理阈值分场景调筛查场景把conf-thres降到 0.25 保召回复核场景提到 0.5 降误报别一个阈值走天下。第二是导出时顺手做一次onnxruntime的数值对齐用同一张图跑 PyTorch 和 ONNX比较输出框的 IoU低于 0.95 就说明导出链路有问题这一步能省掉部署端大量扯皮。第三是数据增强的取舍。YOLOv5 默认开了 mosaic、HSV、翻转医学图像里上下翻转通常不合理肠镜视角有方向性可以在data/hyps/hyp.scratch-low.yaml里把flipud设为 0。第四是模型监控训练时盯results.csv的train/box_loss和val/box_loss分叉点一旦验证损失回升就是过拟合信号早停比硬跑完 50 轮划算。如果后续要往多类走比如区分增生性和腺瘤性息肉nc改成对应类别数names按顺序补全标签里的 class id 同步改其余链路不用动。往边缘设备迁移时ONNX 之后接量化工具输入尺寸和归一化参数必须和训练时完全一致差一个 255 的除数输出就全废。从那以后我每次拿到一个新的检测数据集都强制先跑一遍单图过拟合——拿一张图训 100 轮看 loss 能不能降到接近 0。这一步过了才说明数据管线和标签格式没问题再去铺全量训练能省掉大量训了半天发现标签是错的的后悔药。希望帮到你。本文还有配套的精品资源点击获取