ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

YOLOv8轮胎缺陷检测实战:从数据集标注到ONNX部署与GUI开发

YOLOv8轮胎缺陷检测实战:从数据集标注到ONNX部署与GUI开发 简介本资源是一套基于YOLOv8的轮胎缺陷检测系统完整工程包面向从事工业质检、智能制造方向的开发者与深度学习学习者可用于轮胎图像中debris、side_cut、ground、side等缺陷的自动识别与分类。包内共149个文件以jpg与png图像样本、xml标注、py源码、pt与onnx模型、yaml配置及csv评估记录为主另含PyQt5界面相关文件压缩包约34.74MB覆盖数据、训练、推理与可视化全流程。系统配套评估指标曲线便于查看准确率、召回率与mAP等表现并附带精美GUI界面非专业人员也能直观完成检测操作。目前已有494人学习下载适合希望快速复现YOLOv8工业缺陷检测项目、研究模型部署与界面集成的读者参考。1. 轮胎缺陷检测为什么值得用 YOLOv8 重做一遍轮胎表面缺陷检测在产线上是个老问题人工目检漏检率高、三班倒成本压不下来传统视觉方案又对光照和胎面纹理极其敏感。我见过不少厂子用 OpenCV 阈值加轮廓匹配硬扛换一批胎、换一个工位就得重新调参维护成本比部署成本还高。YOLOv8 这类单阶段检测器把这件事拉回了可复现的轨道——标注几百张缺陷图训一个模型导出 ONNX配一个 GUI 界面整条链路在 Python 里就能闭环。这套「源码 ONNX 模型 评估指标曲线 GUI」的组合本质上是把训练、验证、部署三个环节打包成一个能直接跑起来的最小系统。适合谁适合手里有缺陷样本、想快速验证检测可行性、又不想从零搭框架的工程师。下面我按自己落地的顺序把数据、训练、导出、界面、排错一层层拆开讲。2. 从数据集到 YOLOv8 训练标注、划分与参数怎么定2.1 轮胎缺陷的类别定义与标注规范轮胎缺陷检测的类别定义直接决定模型能不能收敛。常见缺陷包括鼓包、裂纹、异物嵌入、胎侧划伤、气泡这几类但我不建议一上来就分七八类。血泪经验是类别越细单类样本越少模型越容易在混淆矩阵里把裂纹和划伤搞混。我一般先合并成三到四类——结构性缺陷鼓包、气泡、表面线性缺陷裂纹、划伤、异物跑通基线后再拆。标注工具用 labelme 或 labelImg 都行关键是框要贴紧缺陷边缘不要为了「保险」把框画大。YOLOv8 用的是 YOLO 格式标注每张图对应一个 txt每行是类别索引 中心x 中心y 宽 高坐标全部归一化到 0~1。labelme 标完是 JSON需要转一道转换脚本如下import json import os # labelme JSON 转 YOLO txt # classes 顺序必须和训练时的 data.yaml 完全一致 classes [bulge, crack, foreign] def convert(json_path, out_dir, img_w, img_h): with open(json_path, r, encodingutf-8) as f: data json.load(f) lines [] for shape in data[shapes]: label shape[label] if label not in classes: continue cls_id classes.index(label) pts shape[points] xs [p[0] for p in pts] ys [p[1] for p in pts] # 计算外接矩形并归一化 x_min, x_max min(xs), max(xs) y_min, y_max min(ys), max(ys) cx (x_min x_max) / 2.0 / img_w cy (y_min y_max) / 2.0 / img_h w (x_max - x_min) / img_w h (y_max - y_min) / img_h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) name os.path.splitext(os.path.basename(json_path))[0] with open(os.path.join(out_dir, name .txt), w) as f: f.write(\n.join(lines)) # 调用时 img_w/img_h 必须传原图尺寸不能传缩放后的这段逻辑里最容易翻车的是 img_w 和 img_h。labelme 记录的是原图像素坐标如果你传了缩放后的尺寸归一化坐标就全错了训练时 loss 会一直不降。参数上 classes 列表的顺序就是最终类别索引改顺序等于改标签必须和 data.yaml 里的 names 一一对应。2.2 数据集划分与 data.yaml 配置标注完不要随手按 8:2 切。轮胎图像往往来自连续拍摄相邻帧高度相似随机切会让训练集和验证集「串味」验证指标虚高。我一般按拍摄批次或时间段切保证验证集里的胎和训练集不是同一批。目录结构建议dataset/ images/ train/ val/ labels/ train/ val/data.yaml 是训练的入口配置字段不多但每个都关键path: /data/tire_defect train: images/train val: images/val nc: 3 names: [bulge, crack, foreign]nc 是类别数必须和 names 长度一致也和标注里的最大类别索引对得上。常见错误是 nc 写了 3 但标注里出现了索引 3训练直接报 index out of range。path 用绝对路径最稳相对路径在不同工作目录下跑容易找不到图。2.3 YOLOv8 训练命令与关键参数环境搭好后训练就一行命令的事但参数决定成败yolo detect train \ data/data/tire_defect/data.yaml \ modelyolov8n.pt \ epochs150 \ imgsz640 \ batch16 \ lr00.01 \ patience30 \ projectruns/tire \ nameexp1model 选 yolov8n 还是 yolov8s 看你的算力和精度要求。GTX1660Ti 这类 6G 显存的卡yolov8n 配 batch16、imgsz640 基本能跑满yolov8s 就得把 batch 降到 8。epochs 不是越多越好patience30 表示 30 轮验证指标不升就早停省时间。lr0 初始学习率 0.01 是默认值小数据集可以降到 0.005 防止震荡。imgsz 要和部署时的输入尺寸一致训练 640 推理 320 精度会掉一截。训练过程中重点关注三个信号box_loss 是否稳定下降、mAP50 是否在涨、cls_loss 有没有突然飙升。cls_loss 飙升通常是标注里有空 txt 或者类别索引越界。跑完在 runs/tire/exp1 下会有 results.csv 和权重文件评估指标曲线就是从 results.csv 画出来的。3. 评估指标曲线怎么读mAP、PR 曲线与损失曲线的实战解读3.1 results.csv 里到底有哪些指标训练结束后 results.csv 每行对应一个 epoch列包括 train/box_loss、train/cls_loss、metrics/mAP50、metrics/mAP50-95、precision、recall 等。很多人只看 mAP50 一个数其实 PR 曲线和 F1 曲线才能告诉你模型在哪个置信度阈值下最平衡。画损失函数曲线用 matplotlib 几行就够import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(runs/tire/exp1/results.csv) df.columns [c.strip() for c in df.columns] # 列名可能带空格 fig, axes plt.subplots(1, 2, figsize(12, 4)) axes[0].plot(df[epoch], df[train/box_loss], labelbox_loss) axes[0].plot(df[epoch], df[train/cls_loss], labelcls_loss) axes[0].set_xlabel(epoch); axes[0].legend(); axes[0].set_title(train loss) axes[1].plot(df[epoch], df[metrics/mAP50], labelmAP50) axes[1].plot(df[epoch], df[metrics/mAP50-95], labelmAP50-95) axes[1].set_xlabel(epoch); axes[1].legend(); axes[1].set_title(mAP) plt.savefig(curves.png, dpi150)逻辑说明box_loss 反映定位精度cls_loss 反映分类精度两条曲线应该同步下降。如果 box_loss 降但 cls_loss 不降说明框对了但类别分不清多半是类别样本不均衡。mAP50 和 mAP50-95 的差距能看出定位精度差距大说明框不够准。3.2 PR 曲线与置信度阈值的选择PR 曲线是 precision 对 recall 的曲线曲线下面积就是 AP。实际部署时你要选一个置信度阈值阈值高则 precision 高、recall 低漏检多阈值低则反过来误检多。轮胎缺陷检测里漏检的代价通常大于误检所以我一般把 conf 阈值压到 0.25 左右宁可多报几个让复检环节兜底。这个阈值不是拍脑袋是在验证集上跑yolo detect val后看 F1 曲线峰值对应的 conf 值来定的。3.3 混淆矩阵暴露的标注问题验证输出的混淆矩阵经常能抓出标注错误。如果 bulge 和 crack 之间大量互相误判先别急着改模型结构回去看标注是不是有些鼓包边缘的裂纹被标成了两类或者同一张图里两个缺陷框重叠。我遇到过一类情况背景被误检成 foreign查下来是负样本太少模型把胎面花纹当成了异物。解决办法是往训练集里补一批纯背景图不加任何标注让模型学会「什么都没有」也是一种结果。4. 导出 ONNX 与 GUI 界面推理链路怎么搭才不翻车4.1 PyTorch 转 ONNX 的正确姿势训练完的 .pt 权重不能直接给非 Python 环境用导出 ONNX 是标准动作yolo export modelruns/tire/exp1/weights/best.pt formatonnx imgsz640 opset12 simplifyTrueopset 选 12 兼容性最好simplifyTrue 会做一层图优化去掉冗余算子。导出后务必用 onnxruntime 验证一遍输出和 PyTorch 对齐import onnxruntime as ort import numpy as np sess ort.InferenceSession(best.onnx, providers[CPUExecutionProvider]) inp np.random.randn(1, 3, 640, 640).astype(np.float32) out sess.run(None, {sess.get_inputs()[0].name: inp}) print(out[0].shape) # 应为 (1, 4nc, 8400)输出形状里 8400 是候选框数量4nc 是框坐标加类别分数。如果形状不对多半是 imgsz 或 opset 没对齐。想进一步压缩可以用 ONNX 量化 int8但轮胎缺陷这种小目标场景int8 量化后精度掉得比较明显我一般只在算力实在不够时才上而且要拿验证集重新测一遍 mAP。4.2 GUI 界面的最小可用结构GUI 用 PyQt5 或 tkinter 都行核心就三块选图/选视频、调 conf 和 iou 阈值、显示带框结果。用 PyQt5 的话主线程只负责界面推理放子线程否则点一下卡三秒。推理部分直接调 onnxruntime前处理要做 letterbox 保持长宽比后处理做 NMS。前处理里最常见的坑是通道顺序OpenCV 读进来是 BGR模型要 RGB忘了转颜色会整体偏色检测框乱飞。界面上把 conf 阈值做成滑块让操作员能实时调比写死在代码里实用得多。显示结果时把类别名和置信度画在框上方字体大小随框宽自适应小框上的字别糊成一团。4.3 从 ONNX 到端侧部署的路径如果最终要上 RK3588 这类板子ONNX 还要转 RKNN上 ncnn 就转 ncnn。转换工具链各有一套量化校准流程核心都是拿一批代表性图片跑校准生成量化参数。这里不展开但记住一条转换后的模型必须拿同一批验证图跑一遍和 ONNX 的输出做数值对比差异超过阈值就说明转换环节有问题别直接上板子。5. 轮胎缺陷检测落地避坑五条踩出来的经验5.1 现象训练 loss 正常但验证 mAP 始终为 0原因data.yaml 里的 path 或 train/val 路径写错模型实际在训空数据集或者标注 txt 和图片没对上名。解决训练前用脚本统计 images/train 和 labels/train 的文件数是否一致打印几张图的标注行数确认非空。5.2 现象推理时框位置整体偏移原因前处理 letterbox 的 padding 计算和后处理还原时不一致或者训练 imgsz 和推理 imgsz 不同。解决把前处理的缩放比、padding 值打印出来后处理严格按同一组参数逆变换训练和推理尺寸保持一致。5.3 现象ONNX 推理结果和 PyTorch 对不上原因导出时没加 simplify或者 opset 版本和 onnxruntime 不匹配也可能是动态轴设置问题。解决导出加 simplifyTrueopset 固定 12用同一张图分别跑 PyTorch 和 ONNX逐元素比对输出定位是哪一层开始偏的。5.4 现象GUI 点推理就卡死原因推理跑在主线程阻塞了 Qt 事件循环。解决把推理封装成 QThread 子类通过信号槽把结果传回主线程更新界面别在按钮回调里直接跑模型。5.5 现象小缺陷漏检严重原因imgsz 太小导致小目标特征丢失或者训练集里小目标样本占比低。解决提高 imgsz 到 960 或 1280或者在数据增强里加 mosaic 和 copy-paste 增加小目标出现频率验证集单独统计小目标的 recall。6. 把 mAP 再提几个点的进阶技巧与验证习惯模型跑通只是起点真正决定能不能上线的是稳定性和可复现性。我自己的习惯是每次改完参数或数据固定跑一遍验证集把 mAP50、mAP50-95、各类别 AP 记到一张表里横向对比。下面这张表是我常用的记录格式实验编号模型imgsz增强策略mAP50mAP50-95备注exp1yolov8n640默认0.820.51基线exp2yolov8n960默认0.860.56小目标提升exp3yolov8s960mosaiccopy-paste0.890.61显存吃紧进阶方向有几个性价比高的一是 freeze 主干前几层做微调小数据集上能防过拟合二是换 head 结构比如加一个针对小目标的检测头三是用 SAHI 切片推理把大图切成小块分别检测再合并对小缺陷特别有效代价是推理时间线性增长。验证习惯上我坚持留一个「从未参与训练和调参」的测试集只在最终定版时跑一次这个数才是能拿去汇报的数。调参阶段看的验证集指标再高也可能只是过拟合了验证集。最后说个我自己的教训早期我总想一步到位把类别分得很细、模型换得很大结果两个月没跑出一个能看的基线。后来老老实实三类、yolov8n、640 起步一周就跑通了全链路再在这个基础上迭代。先让系统转起来再谈优化这个顺序别反。希望帮到你。本文还有配套的精品资源点击获取
返回列表