news 2026/10/16 16:06:31

YOLOv5焊缝缺陷检测实战:从数据集标注到PyQt界面与RK3568边缘部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLOv5焊缝缺陷检测实战:从数据集标注到PyQt界面与RK3568边缘部署

简介:本资源面向工业质检与计算机视觉方向的开发者、学生及研究人员,提供一套基于YOLOv5的焊缝质量好坏检测完整方案,可用于钢材缺陷检测场景的算法验证与二次开发。压缩包共约2000个文件,包含1134张jpg图像、1134个xml标签与1135个txt标签,分别对应LabelImg标注的原始数据与YOLO训练格式,另附已训练好的检测模型及PR曲线、loss曲线等评估结果,整体约222.96MB。界面部分基于PyQt开发,支持图片、视频与摄像头三种输入方式,并提供相应选择项,便于直观演示检测效果。目前已有987人学习下载,读者可借此快速复现焊缝缺陷检测流程,理解数据集组织方式、模型训练指标含义与推理界面搭建思路,适合作为课程设计、毕业设计或工业检测项目的参考模板。

1. 焊缝质检的现场困局:为什么YOLOv5成了小团队的首选

在钢结构车间待过的人都知道,焊缝质检这件事长期靠老师傅拿放大镜看,一条两米长的角焊缝,气孔、咬边、焊瘤混在一起,肉眼判断一致性极差。更现实的问题是,一条产线每天几百个工件,全检根本排不过来,抽检又容易漏掉致命缺陷。YOLOv5焊缝质量好坏检测这套方案,本质上就是拿一个轻量目标检测模型,把焊缝区域里的缺陷框出来并分类,再配一个PyQt界面让质检员在工控机上直接操作。它适合的是有几百到几千张标注图、算力在单张消费级显卡或边缘盒子级别的小团队,不需要自建深度学习平台,也不需要标注团队从头搭流程。权重、数据集、界面三件套齐了,剩下的就是调参和踩坑。

2. 焊缝缺陷数据集怎么攒:从拍图到YOLO格式的完整链路

2.1 焊缝缺陷的类别定义与拍摄规范

焊缝质量好坏检测的第一步不是写代码,是定义清楚你要检测什么。常见做法是把缺陷分成五类:气孔(porosity)、咬边(undercut)、焊瘤(overlap)、裂纹(crack)、未熔合(lack of fusion)。但我不建议一上来就五类全上,原因很简单——裂纹和未熔合的样本量通常极少,强行五类训练会让模型在这两类上几乎学不到东西。我一般会先把气孔、咬边、焊瘤三类做扎实,等样本量上来了再合并裂纹类。

拍摄环节有几个硬约束。光源用条形LED从侧面打,角度控制在30到45度,正面打光会让气孔和咬边的阴影消失,模型根本分不出来。相机离焊缝距离固定在300到400毫米,太近景深不够,太远缺陷像素太少。每张图里焊缝要占画面宽度的60%以上,背景里不要出现其他焊缝干扰。拍的时候同一工件至少换两个角度,因为咬边在某个角度下可能完全看不见。

提示:拍图阶段就要按缺陷类别分文件夹存放,后面标注和划分数据集会省掉大量返工时间。

2.2 标注工具选型与YOLO格式转换

标注工具用LabelImg或者AnyLabeling都行,导出VOC格式的XML。但YOLOv5吃的是txt格式,每行是类别索引 中心x 中心y 宽 高,全部归一化到0到1。转换脚本我一般自己写一个,因为网上找的经常在边界框超出图像时不做裁剪,导致训练时报坐标越界。

import os import xml.etree.ElementTree as ET # 类别映射,顺序必须和训练时的data.yaml一致 CLASS_MAP = {"porosity": 0, "undercut": 1, "overlap": 2} def voc_to_yolo(xml_path, img_w, img_h, out_path): tree = ET.parse(xml_path) root = tree.getroot() lines = [] for obj in root.findall("object"): cls_name = obj.find("name").text.strip() if cls_name not in CLASS_MAP: continue bbox = obj.find("bndbox") xmin = float(bbox.find("xmin").text) ymin = float(bbox.find("ymin").text) xmax = float(bbox.find("xmax").text) ymax = float(bbox.find("ymax").text) # 边界裁剪,防止标注框超出图像范围 xmin = max(0, min(xmin, img_w)) xmax = max(0, min(xmax, img_w)) ymin = max(0, min(ymin, img_h)) ymax = max(0, min(ymax, img_h)) if xmax <= xmin or ymax <= ymin: continue cx = (xmin + xmax) / 2.0 / img_w cy = (ymin + ymax) / 2.0 / img_h w = (xmax - xmin) / img_w h = (ymax - ymin) / img_h lines.append(f"{CLASS_MAP[cls_name]} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}") with open(out_path, "w") as f: f.write("\n".join(lines))

这段脚本的核心逻辑是坐标归一化和边界裁剪。CLASS_MAP的索引顺序必须和后面data.yaml里的names列表严格一致,否则模型学出来的类别全是错的。裁剪那两行是血泪经验,标注时手抖把框拉到图像外面,不裁剪的话YOLOv5训练直接报错退出。:.6f保留六位小数是YOLOv5官方推荐精度,少了会在小目标上产生明显偏移。

2.3 数据集划分与data.yaml配置

图片和标签按8:1:1划分训练集、验证集、测试集。划分时要注意同一个工件的不同角度图不能跨集,否则验证集精度会虚高。目录结构长这样:

weld_dataset/ images/ train/ val/ test/ labels/ train/ val/ test/

data.yaml的写法:

path: /home/user/weld_dataset train: images/train val: images/val test: images/test nc: 3 names: ["porosity", "undercut", "overlap"]

nc是类别数,改了类别一定要同步改这里和转换脚本里的CLASS_MAP。我见过有人只改了一边,训练loss正常下降但mAP一直是零,排查了半天才发现是索引对不上。

3. YOLOv5训练焊缝检测模型:超参数怎么设才不翻车

3.1 环境搭建与预训练权重选择

环境用PyTorch加YOLOv5官方仓库就行。CUDA版本根据显卡驱动选,30系卡用CUDA 11.x比较稳。预训练权重选yolov5s.pt,焊缝检测这种场景不需要yolov5x,s版本在单张RTX 3060上batch size能开到16,训练速度快一倍以上,精度差距在焊缝缺陷这种纹理明显的任务上通常不到2个点。

git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt # 下载yolov5s预训练权重放到weights目录 python train.py --img 640 --batch 16 --epochs 150 \ --data ../weld_dataset/data.yaml \ --weights weights/yolov5s.pt \ --cfg models/yolov5s.yaml

--img 640是输入分辨率,焊缝缺陷里气孔可能只有十几个像素,640是底线,再低小目标就丢了。--batch 16在8G显存下比较安全,显存不够就降到8,但batch太小BN层统计不准,精度会掉。--epochs 150配合默认的余弦退火学习率,焊缝数据集通常100轮左右收敛,150轮留足余量。

3.2 焊缝场景下的关键超参数调整

YOLOv5默认超参数是给COCO调的,焊缝检测有几个必须改的地方。第一个是--hyp里的mosaic概率,默认1.0,但焊缝图拼接后会出现不自然的焊缝走向,我一般降到0.5。第二个是anchors,默认anchor是基于COCO的,焊缝缺陷的宽高比偏极端,咬边又细又长,气孔接近方形,重新聚类anchor能提2到3个点。

# 用k-means重新聚类anchor python utils/autoanchor.py --data ../weld_dataset/data.yaml \ --weights weights/yolov5s.pt --img 640

聚类完把输出的anchor写回models/yolov5s.yaml里的anchors字段。第三个是学习率,默认lr0=0.01对焊缝这种小数据集偏大,我一般降到0.005,配合--cos-lr余弦退火,loss曲线会平滑很多。

注意:改完anchor一定要重新从头训练,不要在旧权重上继续训,否则anchor和权重不匹配,mAP会先掉再涨,浪费大量时间。

3.3 训练过程监控与早停策略

训练时开TensorBoard看三个指标:train/box_loss、val/box_loss、metrics/mAP_0.5。正常情况box_loss在前20轮快速下降,之后缓慢收敛。如果val_loss在30轮后开始上升而train_loss还在降,就是过拟合了,要么加数据增强要么减模型容量。

早停用--patience 30,30轮mAP不涨就停。但焊缝检测有个坑——mAP可能在某个epoch突然跳一下又回落,这是验证集太小导致的波动。我一般把patience设到50,宁可多训一会儿也不错过真正的收敛点。

# 断点续训,意外中断后不用从头来 python train.py --resume runs/train/exp/weights/last.pt

--resume会恢复优化器状态和epoch计数,比重新加载权重再训要正确得多。我见过有人直接--weights last.pt接着训,学习率调度器重置了,结果loss直接炸掉。

4. PyQt界面集成:把模型塞进质检工位的落地细节

4.1 界面布局与推理线程分离

PyQt界面最容易翻车的地方是把推理放在主线程里,点一下检测按钮界面就卡死。正确做法是QThread开子线程跑推理,主线程只管刷新界面。

from PyQt5.QtCore import QThread, pyqtSignal import cv2 import torch class InferThread(QThread): result_ready = pyqtSignal(object, list) def __init__(self, model, img_path): super().__init__() self.model = model self.img_path = img_path def run(self): img = cv2.imread(self.img_path) # YOLOv5推理,size和训练时保持一致 results = self.model(img, size=640) boxes = results.xyxy[0].cpu().numpy() self.result_ready.emit(img, boxes)

pyqtSignal用来跨线程传结果,object传图像数组,list传检测框。推理时的size=640必须和训练时一致,改了会导致精度下降。results.xyxy[0]取的是第一张图的检测结果,格式是[x1, y1, x2, y2, conf, cls]。

4.2 检测结果可视化与置信度阈值调节

界面上要留一个滑动条调置信度阈值,因为不同产线的光照条件不一样,固定阈值要么漏检要么误报。可视化时按类别给不同颜色,气孔红色、咬边黄色、焊瘤蓝色,质检员一眼就能分辨。

def draw_boxes(img, boxes, conf_thres=0.4): colors = {0: (0, 0, 255), 1: (0, 255, 255), 2: (255, 0, 0)} names = {0: "porosity", 1: "undercut", 2: "overlap"} for box in boxes: x1, y1, x2, y2, conf, cls = box if conf < conf_thres: continue c = int(cls) cv2.rectangle(img, (int(x1), int(y1)), (int(x2), int(y2)), colors[c], 2) label = f"{names[c]} {conf:.2f}" cv2.putText(img, label, (int(x1), int(y1) - 8), cv2.FONT_HERSHEY_SIMPLEX, 0.6, colors[c], 2) return img

conf_thres默认0.4是焊缝场景的经验值,低于0.3误报会明显增多,高于0.6漏检率上升。colors字典的键要和CLASS_MAP一致,否则颜色和类别对不上,质检员会看懵。

4.3 模型加载与打包部署的注意事项

模型加载用torch.hub.load指定本地路径,不要让它去联网下载。

model = torch.hub.load('./yolov5', 'custom', path='weights/best.pt', source='local') model.conf = 0.4 model.iou = 0.45

source='local'是关键,不写的话每次启动都尝试联网,车间断网环境直接卡住。model.iou是NMS的IoU阈值,焊缝缺陷密集时调到0.5以上,避免相邻缺陷被合并。

打包用PyInstaller时要把yolov5目录和权重文件一起打进去,--add-data参数指定路径。打包后第一次运行会慢,因为要解压临时文件,这是正常现象。

5. 焊缝检测落地避坑:五条血泪经验

5.1 现象:训练mAP很高但现场漏检严重

原因通常是训练集和现场光照条件不一致。数据集是在实验室打的条形光,现场是车间顶灯,焊缝反光特性完全不同。解决办法是现场补拍200张图加入训练集,或者在推理前做直方图均衡化,把光照差异拉平。

5.2 现象:模型把焊缝本身的纹理误判为缺陷

原因是标注时把焊缝鱼鳞纹也框进去了。焊缝的鱼鳞纹在低分辨率下和气孔纹理接近,标注必须严格只框缺陷区域,不能把周围焊缝带进去。已经标错的要返工,没有捷径。

5.3 现象:PyQt界面在工控机上闪退

多半是OpenCV和PyQt的版本冲突。工控机通常装的是老版本Ubuntu,opencv-python要降到4.5.x,PyQt5用5.15.x,这两个版本组合最稳。闪退时在终端跑一遍看报错,通常是libGL.so.1找不到,装libgl1-mesa-glx就行。

5.4 现象:推理速度只有几帧,质检员嫌慢

检查是不是用了yolov5x权重,换成yolov5s速度能翻三倍。另外推理时开model.half()用FP16,30系卡上还能再快30%。如果还慢,把输入尺寸从640降到512,精度掉1个点左右但速度提升明显。

5.5 现象:换了一批工件后模型完全失效

焊缝检测模型对工件材质和厚度敏感。碳钢上训的模型直接用到不锈钢上,反光差异会让mAP掉20个点以上。换材质必须补拍数据重新微调,至少50张图,冻结主干只训检测头,20轮就能恢复。

6. 把焊缝检测模型压到边缘盒子:RK3568量化部署的实操技巧

焊缝质检的最终形态往往不是工控机加显卡,而是产线边上放一个RK3568这类边缘盒子,成本低、功耗小、不用风扇。但YOLOv5直接往RK3568上搬会碰到算子不支持的问题,必须走ONNX转RKNN的量化路线。

第一步是导出ONNX。YOLOv5仓库自带export.py,但要注意输出节点。RKNN对动态shape支持不好,导出时固定batch为1。

python export.py --weights weights/best.pt --include onnx \ --img 640 --batch 1 --opset 12

--opset 12是关键,opset 11在RKNN转换时Slice算子会报错,opset 13又太新,12是实测最稳的版本。

第二步是量化校准。RK3568的NPU是INT8推理,需要一批校准图来统计激活值范围。校准图从训练集里随机抽200张,覆盖各种光照和缺陷类型。

from rknn.api import RKNN rknn = RKNN() rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]], target_platform='rk3568') rknn.load_onnx(model='best.onnx') rknn.build(do_quantization=True, dataset='calib.txt') rknn.export_rknn('best.rknn')

mean_values和std_values要和训练时的归一化参数一致,YOLOv5默认是除以255,所以std填255。calib.txt每行是一张校准图的路径。量化后mAP通常会掉1到3个点,如果掉超过5个点,说明校准集代表性不够,要补一些极端光照的图。

第三步是板上推理。RK3568的NPU推理YOLOv5s 640输入大概能到15到20帧,够产线节拍用。后处理里的NMS建议放在CPU上做,NPU做NMS效率反而低。

# 板上推理核心调用 outputs = rknn.inference(inputs=[img]) # outputs是三个尺度的特征图,需要自己写decode和NMS boxes = decode_outputs(outputs, anchors, img_shape) keep = nms(boxes, iou_thres=0.45)

decode_outputs要把三个尺度的特征图还原成边界框,这部分代码YOLOv5的utils/general.py里有参考实现,移植时注意anchor顺序要和导出ONNX时一致。NMS的iou_thres在焊缝密集场景下调到0.5,避免相邻气孔被误合并。

量化部署这条路我走过好几次,最大的教训是:不要等模型在PC上调到完美再上板,因为量化本身会改变精度分布。正确做法是PC上训到mAP 0.85左右就导出量化,板上实测看哪些类别掉点严重,再针对性补数据微调。这样迭代两三轮,板上精度能追到PC的95%以上。焊缝检测这种工业场景,稳定比极致精度重要,一个能在边缘盒子上7x24小时跑的0.82 mAP模型,比一个需要水冷显卡的0.90 mAP模型有价值得多。希望帮到你。

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

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

动态规划状态机巧解股票交易系列|从一次交易到K笔

最近在力扣上面刷题&#xff0c;把Best Time to Buy and Sell Stock这个系列的股票交易问题完整过了一遍。以前总觉得这类题就是套几个公式&#xff0c;背一背状态转移就完事&#xff0c;直到自己动手推导、把边界case一个个踩过去&#xff0c;才意识到里面藏着动态规划从入门到…

作者头像 李华
网站建设 2026/10/16 9:29:07

西门子TP700 Comfort固件刷写实战:ProSave离线重装OS与恢复出厂设置

简介&#xff1a;本资源是一份面向工业自动化工程师、西门子HMI现场维护人员及PLC初学者的实操指南&#xff0c;系统讲解如何使用ProSave软件对西门子触摸屏执行OS固件更新与恢复出厂设置&#xff0c;解决设备升级失败、界面异常或版本兼容性等典型现场问题。资源为单文件Word文…

作者头像 李华
网站建设 2026/10/14 23:53:19

顶级咨询顾问技能培训:掌握金字塔结构与假设驱动的思考法

我一直觉得&#xff0c;市面上关于咨询顾问的培训资料&#xff0c;十有八九都把人带沟里了。要么堆满玄乎的模型名词&#xff0c;让你觉得学完就能指点江山&#xff1b;要么就是鸡汤式的“思维升级”&#xff0c;读完热血沸腾&#xff0c;关上文档啥也不会。直到我啃完一套顶级…

作者头像 李华