简介基于YOLOv8的热轧带钢表面缺陷检测实践资源包面向工业质检、机器视觉开发者和入门学习者覆盖横向裂缝、纵向裂缝、块状裂缝、龟裂、坑槽、修补网状裂缝等八类缺陷的自动识别与定位。资源共2000个文件压缩包74.49MB以1808个txt标注/说明文件为主体搭配161个md教程文档、14个Python训练推理脚本以及少量C/XML/YAML配置便于按需查阅和二次开发。已有841人学习下载。内容包含完整数据集、源码和详细使用教程从数据集制作、YOLOv8环境配置到模型训练、参数调优和推理评估均有清晰指引。对希望快速落地工业表检场景、理解YOLOv8工程化流程的开发者是一份可直接上手的实操参考资料。1. 基于yolov8的热轧带钢表面缺陷检测从数据集到源码落地的完整路径热轧带钢在产线高速运行时会因为轧辊磨损、冷却不均、氧化铁皮压入等原因产生表面缺陷一旦漏检带着缺陷的卷料流入下游就会变成质量事故。传统机器视觉靠人工设计边缘、纹理特征换一个钢种或者换一条产线就要重新调参鲁棒性很差。工业质检里真正落地的主流方案是把缺陷检测当成目标检测来做用yolov8在标注好的带钢表面缺陷数据集上训练得到能识别缺陷类别和位置的模型再封装成源码工程供产线调用。这套方案的优点在于不需要重新设计特征算子标注质量够、数据量够模型就能抗住复杂纹理背景。本文面向的读者是已经跑通过yolov8基础流程、想在工业表面缺陷检测上落地的工程师也适合刚入手目标检测、需要一个真实场景数据集来练手的新手。全文按数据准备、环境搭建、训练调参、推理部署的顺序展开最后给出几个生产环境里最容易被忽略的坑。2. 热轧带钢缺陷数据集与标注格式处理从NEU-DET到yolov8能直接训练的格式2.1 先认识这个任务里的六类缺陷热轧带钢表面缺陷检测最常用的公开数据集是NEU-DET东北大学发布包含六类缺陷rolled-in scale氧化铁皮压入、patches斑块、crack裂纹、pitted surface麻点、inclusion夹杂物、scratches划痕。每类约300张图片尺寸统一为200x200像素是灰度图转成三通道后的JPG。这个数据集规模不大但对工业场景来说非常有代表性——缺陷和背景纹理高度相似小目标多类间差异小属于典型的难例数据集。注意如果你的产线上缺陷类别和NEU-DET不同不要直接拿预训练权重硬扛。正确的做法是用NEU-DET做预训练或迁移学习的起点再用自有的产线数据做二次微调。下载到的原始数据集通常有两种组织方式一种是每类一个文件夹、图片无标注框另一种是Pascal VOC格式每张图片对应一个XML文件。无论哪种都需要转换成yolov8要求的格式。yolov8使用Ultralytics框架训练时读取的标注格式是YOLO txt格式每行一个目标内容是“类别id 中心点x 中心点y 宽度 高度”坐标值全部归一化到0到1之间。2.2 将VOC格式XML批量转为YOLO格式txt大多数公开缺陷数据集提供的是VOC格式标注需要写一个转换脚本。下面的Python脚本是工业质检项目里最常用的转换方式import os import xml.etree.ElementTree as ET from tqdm import tqdm def convert_voc_to_yolo(xml_path, output_dir, class_names): tree ET.parse(xml_path) root tree.getroot() image_name root.find(filename).text image_w int(root.find(size/width).text) image_h int(root.find(size/height).text) yolo_lines [] for obj in root.iter(object): class_name obj.find(name).text if class_name not in class_names: continue class_id class_names.index(class_name) xmin int(obj.find(bndbox/xmin).text) ymin int(obj.find(bndbox/ymin).text) xmax int(obj.find(bndbox/xmax).text) ymax int(obj.find(bndbox/ymax).text) # 计算归一化的中心点坐标和宽高 x_center (xmin xmax) / 2.0 / image_w y_center (ymin ymax) / 2.0 / image_h box_w (xmax - xmin) / image_w box_h (ymax - ymin) / image_h yolo_lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {box_w:.6f} {box_h:.6f}) txt_name os.path.splitext(image_name)[0] .txt with open(os.path.join(output_dir, txt_name), w) as f: f.write(\n.join(yolo_lines)) class_names [crazing, inclusion, patches, pitted_surface, rolled-in_scale, scratches] # 批量转换训练集和验证集路径按实际目录调整 for split in [train, val]: xml_dir fNEU-DET/ANNOTATIONS/{split} txt_dir fNEU-DET/labels/{split} os.makedirs(txt_dir, exist_okTrue) for xml_file in tqdm(os.listdir(xml_dir)): if xml_file.endswith(.xml): convert_voc_to_yolo(os.path.join(xml_dir, xml_file), txt_dir, class_names)这段脚本的关键在于坐标转换Pascal VOC记录的是左上角和右下角的绝对像素坐标yolov8需要的是归一化的中心点坐标和宽高。除以图片宽高完成归一化后无论输入图片尺寸如何变化标注都不会错位。class_names的顺序必须和训练时传入的data.yaml保持完全一致否则类别id会对不上。2.3 划分数据集并生成data.yamlyolov8需要一份描述数据集的YAML文件告诉框架训练和验证图片在哪、类别名是什么。以下是NEU-DET场景下推荐的数据划分方式和data.yaml内容# data.yaml train: ./NEU-DET/images/train val: ./NEU-DET/images/val nc: 6 names: [crazing, inclusion, patches, pitted_surface, rolled-in_scale, scratches]注意图片文件和txt标注文件要放在同名目录下Ultralytics会自动根据图片路径寻找同名的txt文件。建议按7:2:1划分训练集、验证集、测试集划分时使用sklearn的train_test_split并设置随机种子保证每次实验划分一致便于对比模型效果。工业场景下不要直接随机切分最好按卷号或批次切分防止同一卷钢材的图片同时出现在训练集和验证集中导致数据泄漏。3. 搭建yolov8表面缺陷检测环境CPU版本与GPU版本的坑3.1 conda环境与PyTorch安装在这个环节最常见的需求有两种一种是在ubuntu20.04上搭建yolov8环境CPU版本纯做推理验证另一种是本地有GTX 1660 Ti这类显卡需要装GPU版本跑训练。两种都从创建conda环境开始conda create -n yolo_defect python3.9 -y conda activate yolo_defect # CPU版本适合无显卡的开发机和边缘设备调试 pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu # GPU版本以GTX 1660 Ti为例CUDA 11.8 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralyticsCPU版本和GPU版本在代码层面没有任何区别差异只在推理速度和训练速度。GTX 1660 Ti是图灵架构6GB显存训练yolov8nnano版本时batch size设为16没有压力训练yolov8s时建议降到8。装完之后务必验证一下环境是否真的可用python -c import torch; print(torch.__version__, torch.cuda.is_available())如果是CPU版本torch.cuda.is_available()返回False是很正常的不要慌。但如果显示True却报CUDA out of memory那是显存不足不是环境坏了。跑yolov8训练时用小batch size卡在“CUDA out of memory”是6GB显存显卡的常态解决方案不是调代码而是降batch size或改用yolov8n。3.2 用预训练权重启动第一次训练环境搭好后先用官方预训练权重跑通整个流水线确认代码链路没问题再换自己的缺陷数据集。以下命令使用yolov8n预训练权重在NEU-DET上训练100轮yolo detect train \ dataNEU-DET/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ patience20 \ project./runs \ nameneu_defect提示第一次训练建议加上cacheTrue参数命令行写cacheTrueyolov8会先把图片加载到内存里避免每轮训练都重复读磁盘。NEU-DET数据集很小全部放进内存也就几百MB能明显加快训练速度。参数说明imgsz640是yolov8的默认输入尺寸NEU-DET原始图片只有200x200框架会自动resize到640x640这个操作会放大图片但也可能让缺陷纹理变模糊patience20表示20轮mAP没有提升就提前停止训练对工业场景来说这个值设在15到25之间比较合理modelyolov8n.pt不只是一个可选参数它会自动加载COCO上的预训练权重作为迁移学习起点千万不要随意用yolov8n.yaml那相当于从零开始训练NEU-DET这种规模的数据量远远不够。4. 训练参数调整与损失函数曲线分析让yolov8在缺陷检测上真正收敛4.1 三个必调参数imgsz、anchor、mosaicyolov8的默认参数在COCO这种通用场景上表现好但工业表面缺陷检测有自己的特殊性。缺陷尺寸通常很小200x200的图片里单个缺陷可能只有几十个像素。以下三个参数我几乎每次做缺陷检测都会调整imgszNEU-DET原始图片是200x200建议直接设成640或者更大。yolov8内部会做resize设成640等于把图片放大了3.2倍小目标的特征响应会更强。设置成imgsz800进一步放大但显存占用会明显上升。mosaic0.5yolov8默认mosaic数据增强概率是1.0即每张训练图片都是4张图拼出来的。但对带钢缺陷来说mosaic拼接后缺陷可能被切割到边缘反而让模型学到错误的上下文。建议降为0.3到0.5让模型看到更多完整的单张缺陷图。close_mosaic10yolov8会在训练最后10轮自动关闭mosaic这个不用改但你要知道它的存在是为了让模型在最后阶段适应无增强的真实分布。4.2 查看损失函数曲线判断训练是否正常训练开始后yolov8会在终端打印每一轮的box_loss、cls_loss、dfl_loss和mAP指标。但终端输出太稀疏推荐用tensorboard实时查看曲线tensorboard --logdir runs/neu_defect打开浏览器访问localhost:6006重点看三条曲线的走势train/box_loss应该持续下降并趋于平稳val/box_loss如果先降后升就是过拟合的典型信号metrics/mAP50应该在前30轮快速上升然后进入缓慢爬升阶段。如果训练了50轮mAP还停留在0.5以下先检查标注是否正确——最常见的错误是类别id和data.yaml里的names顺序对不上导致模型学习了错误的映射。4.3 训练完成后导出最佳权重yolov8训练结束后runs/neu_defect/weights/目录下会生成best.pt和last.pt两个文件。best.pt是验证集上mAP最高的权重工业场景下生产部署永远选best.pt不要用last.pt。用以下命令在验证集上做最终评估看每一类别的AP值yolo detect val \ modelruns/neu_defect/weights/best.pt \ dataNEU-DET/data.yaml输出结果里有一个Per Class的表格重点看pitted_surface和rolled-in_scale这两类的AP。NEU-DET数据集中这两类特征相似、边界模糊AP值比其它四类低0.1到0.2是正常现象。如果某类AP特别低通常不是模型问题而是标注框本身存在大量漏标或错标。5. 推理部署与RK3588板端迁移从best.pt到实际产线可调用的模型5.1 用Python脚本跑单张图片和视频流推理验证完模型精度下一步是封装推理代码。最常见的做法是用Ultralytics的Python API一个时间段内就能跑通单张图片、图片文件夹和视频流三种输入from ultralytics import YOLO # 加载训练好的缺陷检测模型 model YOLO(runs/neu_defect/weights/best.pt) # 单张图片推理 results model.predict(NEU-DET/images/val/example.jpg, conf0.35, iou0.5) # 批量推理整个文件夹并保存标注结果 results model.predict( sourceNEU-DET/images/val/, save_txtTrue, save_confTrue, conf0.35, iou0.5, imgsz640 ) # 打印检测到的缺陷类别和置信度 for r in results: for box in r.boxes: class_id int(box.cls[0]) conf float(box.conf[0]) print(f缺陷类别: {model.names[class_id]}, 置信度: {conf:.3f})conf0.35这个阈值在NEU-DET场景下是比较合理的起点。降得太低比如0.1会把大量纹理背景误检成缺陷升得太高比如0.7又会漏掉真实存在的麻点和夹杂。实际产线部署时建议做一次阈值扫描绘制置信度与误检率的关系曲线再确定最终阈值。5.2 导出ONNX并在RK3588上部署工业产线很少直接用Python跑推理更常见的需求是把模型部署到边缘设备上比如RK3588这类带NPU的板子。yolov8官方支持直接导出ONNX格式yolo export modelruns/neu_defect/weights/best.pt formatonnx opset12导出后会生成best.onnx文件这个文件可以被RKNN-Toolkit转换成RK3588 NPU可运行的rknn格式。转换过程中有两点必须注意一是opset12不要改成更高版本RKNN-Toolkit对高版本ONNX算子支持不完整二是导出时添加dynamicFalse参数固定输入尺寸NPU推理需要固定的输入shape动态尺寸会导致转换失败或推理性能大幅下降。在RK3588上部署yolov8做带钢表面缺陷检测推理耗时大概在20到40毫秒之间取决于NPU频率和输入尺寸完全能满足产线每秒25帧的实时检测需求。如果实测帧率不够优先把输入尺寸从640降到480AP值下降通常不到2个百分点但推理速度能提升接近一倍。5.3 用视频文件模拟产线在线检测拿到RK3588板子之前先用普通PC配合USB摄像头或视频文件验证整个检测链路是否稳定。yolov8的predict方法直接支持视频输入yolo detect predict \ modelruns/neu_defect/weights/best.pt \ source./defect_test.mp4 \ conf0.35 \ saveTrue \ showTrueshowTrue会在窗口中实时显示检测框适合现场调试saveTrue会保存标注后的视频方便回放分析。跑产线实时检测时真正决定检测质量的往往不是模型精度而是视频流是否卡顿——务必在抓帧环节做丢帧处理不要每一帧都送去推理工业摄像头通常给到30fps的流模型处理不了就丢帧宁可丢帧也不能让检测结果晚到。最后一个实践技巧用yolov8自带的混淆矩阵分析误检来源。在训练结束后运行yolo detect val框架会在runs/neu_defect/目录下生成confusion_matrix.png。观察这个矩阵如果patches和rolled-in_scale之间存在大量互相误检说明这两类缺陷需要增加差异化的训练样本如果背景类被频繁预测为缺陷优先调高conf阈值而不是重新训练——先确认是阈值问题还是模型问题再决定是否动数据。工业现场调试模型数据永远比模型结构更值得投入。本文还有配套的精品资源点击获取
