ARTICLE DETAIL

资讯详情

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

基于YOLOv5s与PLC的汽车制造零件检测系统:从图像识别到报警闭环

基于YOLOv5s与PLC的汽车制造零件检测系统:从图像识别到报警闭环 简介一份基于机器视觉技术的汽车制造零件检测系统研究文档面向汽车制造、智能制造及机器视觉从业者聚焦多车型混线生产中零件错装、漏装的自动化检测。全文共1个PDF文件压缩包约1.08MB便于快速下载与阅读。方案以YOLOv5s为核心结合PLC、RFID、Python、OpenCV和钉钉通讯借助Snap7与西门子PLC交互通过变频器与编码器获取车辆位置利用RTSP协议调用网络摄像头拍照完成图像预处理、模型识别与异常报警。针对酒精管道插头、胶堵、空调冷凝管等易错装部件系统训练了11种零件模型样本经OpenCV均值滤波去噪后参与训练模型准确率与召回率均超98%实际提醒准确率超99%优于人工检测且满足生产节拍。文档还给出数据样本准备、图像归一化、模型部署等关键实现细节对汽车制造、工业质检类项目具有直接参考价值。目前已有213人学习适合需要了解机器视觉落地路径的工程师与研究者。1. 机器视觉与汽车制造零件检测为什么一套开源 YOLO 系统能替代整条终检线的人工整车厂生产线上错漏装是个长期痛点车门装成低配、酒精罐插头漏插、胶堵少一个任何一项漏到终检工位都意味着返修、停台甚至客户投诉。机器视觉在这里真正解决了人工检测的可靠性问题尤其是多车型混线生产下检查员对配置清单的记忆和疲劳程度就是最大不可控项。王金成和刘兴在《汽车工艺与材料》发表的这篇论文给出了一套完整的汽车制造零件检测系统方案YOLOv5s 做零件识别Snap7 读西门子 PLC 里的 RFID 吊具信息OpenCV 从网络摄像头抓 RTSP 流识别结果走钉钉 Webhook 和语音屏双通道报警。系统在现场跑了两个月识别准确率 99% 以上把车间漏检返修从每年 240 次压到半年 1 次。如果你正在做机器视觉方向的检测系统选型或者被混线生产的错漏装折磨过这套系统的架构参数和排错思路值得你对着论文原文拆一遍。2. 为什么选 YOLOv5s 而不是更重的模型选型逻辑与十一种零件的样本准备2.1 模型选型精度够用、推理够快才是产线第一原则做机器视觉检测很多人的第一反应是模型越重精度越高。实际情况恰恰相反在产线节拍约束下YOLOv5s 反而是工程上最舒服的选择。YOLOv5 家族里 s、m、l、x 四个版本网络深度和宽度依次递增s 的推理速度最快权重文件也最小论文里明确写了选它的理由——精度要求满足整车生产现场的实际需求。需要理解一点这里的“满足需求”不是论文里的客套话。整车装配类零件检测和通用目标检测不一样检测对象是位置固定、形态差异明显的零件比如门槛亮条、侧标、车顶天线、胶堵。这类目标没有细粒度分类压力s 模型的感受野和特征提取能力足够覆盖。真正约束选型的是节拍从车辆到位、拍照、推理到报警必须在一个工位的停留时间内完成模型每慢 100 毫秒节拍压力就大一分。如果后续你的产线要求更高帧率可以先试 m 版本对比精度收益但论文实测 s 已经跑出了 99% 的识别概率没必要为一点点精度提升付出推理延迟代价。2.2 数据采集与预处理RTSP 抓图、均值滤波降噪、640×640 归一化论文里处理的 11 类零件有一个共同特点位置固定但容易漏装或装错配置。数据样本集全部来自现场摄像头实时采集不是网上找的公开数据集这一步很关键——现场光线、角度、遮挡情况都在样本分布里模型才能在现场工况下发挥作用。原始采集图像有两个典型问题摄像头自身机件噪声和信号传输干扰会产生高斯噪声与椒盐噪声反映在图片上就是那种影响视觉判断的黑白像素点。论文用 OpenCV 的cv2.blur()均值滤波函数做降噪处理卷积核取的是 15×5。这个 15×5 的核值得注意它不是随便拍的参数宽度方向取 15、高度方向取 5说明现场干扰的分布更倾向把横向相邻像素一起脏掉用纵向窄核保留边缘细节是一种贴合实际噪声形态的选择。滤波之后做归一化和尺寸统一所有图片缩放到 640×640对应 YOLOv5s 的默认输入尺寸。归一化公式用的是Y(Xi-min(X))/(Xi-max(x))把像素值压到 0 到 1 区间这一步对收敛稳定性影响很大。import cv2 import numpy as np def preprocess_frame(frame): # 均值滤波去噪核大小 15x5对应论文中公式(1)的 K 矩阵 blurred cv2.blur(frame, (15, 5)) # 统一到 640x640YOLOv5s 默认输入尺寸 resized cv2.resize(blurred, (640, 640)) # 归一化到 [0, 1] 区间替代论文中公式(2)的 min-max 操作 normalized resized.astype(np.float32) / 255.0 return normalized这段代码逻辑上分三步先降噪再统一尺寸最后归一化。cv2.blur()的核大小直接影响降噪力度核越大图像越平滑但边缘细节保留越差15×5 是论文实测折中的结果如果你换工位场景建议先从 5×5 开始调试观察噪声残留和边缘模糊程度再调整。归一化这里直接除以 255和论文里 min-max 归一化的效果等价因为图像像素分布已经相对集中没必要逐图算 min 和 max省一点预处理时间。2.3 样本分布11 个零件类别与 11 个独立模型样本准备阶段最容易被新手忽略的是“每类零件单独训练一个模型”这个决策。论文里明确写了系统需要完成 11 种零件的整体检测暂定每类零件都进行一次模型训练生成 11 个训练模型。这不是偷懒是工程权衡——混线生产下新车型随时可能增加新配置如果一个模型同时识别 11 类零件新增配置就必须重新标注全部数据再整体重训牵一发动全身拆成 11 个小模型后哪个零件出现新形态就只重训哪一个其他模型不受影响。训练集和测试集是按零件实际情况准备的从论文表 1 能看出各类样本量差异很大。零件类别训练图片数测试图片数门槛亮条3722712侧标3120652车顶天线69693尾标3600300酒精罐插头1314307左胶堵1960243右胶堵1381306车顶天线训练集只有 696 张尾标测试集只有 300 张但最终精确率都达到 99% 以上说明这类目标形态简单、背景干扰小少量样本就能收敛。反过来如果目标本身外观接近或者背景复杂样本量就要往上加——不要盲目追求“每个类别都凑 5000 张”先跑一轮看验证集指标数据不够再补。样本标注用的是 Labelimg这也是 YOLO 系列最常用的标注工具输出 VOC 格式的 XML 标注文件再转成 YOLO 训练的 txt 格式。有一个细节值得留意标注时要统一只框零件本体别把周边的安装孔、螺栓也圈进去不然模型学到的是“带螺栓的局部区域”换一个螺栓位置就误检。另外因为是多车型混线生产每种车型的每个配置都要尽量覆盖到采集时注意按车型和配置分组整理目录方便后续单独补样本。3. 模型训练与验收学习率 0.01、batchsize 64 之外还要盯什么3.1 训练参数这些数字不是默认值是现场跑出来的折中论文给出的训练参数是初始学习率 0.01weight decay 0.0005batchsize 64训练 epoch 300 轮。这套参数直接对应 YOLOv5 官方仓库的默认推荐组合但它能直接用起来前提是数据集规模和论文类似——数千张级别的样本量。batchsize 64 对 YOLOv5s 来说需要一定显存。如果用单张 16G 显存的显卡640×640 输入下 batch 64 是可以跑起来的如果你只有 8G 显存老老实实把 batchsize 降到 16 或 32同时学习率按比例往下调否则大 batch 配大学习率容易在训练初期就发散。epoch 300 对应的是 YOLOv5 默认的早停策略一般训练到 180~250 轮 loss 就已经平台了300 轮是保证收敛的上限。这些参数不是拍脑袋定的。学习率 0.01 搭配 weight decay 0.0005对 YOLOv5s 这个体量的网络是经验区间如果你换用更大的 m 或 l 模型weight decay 要适当加大抑制过拟合学习率也要重新搜。论文里没有贴 loss 曲线但凭结果反过来看这套参数至少没有出现梯度爆炸或收敛过慢的问题。3.2 验收指标精确率、召回率都要看只看一个会被打脸模型训练完论文用精确率和召回率作为最终衡量指标并在 IOU 阈值为 0.5 的条件下统计了每个模型的精确率。这里贴几个有代表性的数字。零件类别IOU 0.5 验证集精确率门槛亮条0.98917车顶天线0.99977酒精罐插头0.99957左胶堵0.99308右胶堵0.9990911 个模型精确率全部超过 0.988非常整齐。但要注意精确率高不代表召回率一定高。精确率衡量的是“模型报警说有问题的里面真的有多少是有问题的”召回率衡量的是“真有问题的里面模型找回了多少”。汽车零件错漏装场景里漏报的代价远大于误报——漏报意味着错装车直接流到下个工位甚至客户手里误报最多让检查员多看一眼。所以论文里强调的是准确率和召回率都在 98% 以上两个指标一起卡比单看精确率严格得多。3.3 训练启动命令与迁移学习不要从零训练论文提到“利用迁移学习训练网络模型”这是整个训练环节最省时间的做法。不要从随机初始化开始训练YOLOv5s 官方提供在 COCO 数据集上预训练好的权重直接拿来当初始权重在大数据集上学到的通用特征能为你的小数据集提供很好的起点。python train.py \ --data parts.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 64 \ --epochs 300 \ --lr0 0.01 \ --weight-decay 0.0005参数含义逐个拆--data parts.yaml指向你的数据集配置文件里面写清 train 和 val 图片路径、类别数量和类别名字--weights yolov5s.pt是官方预训练权重如果提示下载失败检查网络权限也可以手动下载后放到项目根目录--img 640和训练时的预处理尺寸保持一致--lr0 0.01是初始学习率YOLOv5 默认会配合余弦退火调度器在训练后期把学习率降到底--weight-decay 0.0005是 L2 正则化强度防止模型在 300 轮训练里把训练集背下来。训练完成后跑验证集确认精确率和召回率是否达标再导出成推理用的权重文件。如果验证集精确率不够先别急着调参回去翻训练集标注有没有错标漏标的框——标注错误对模型精度的损伤比参数不理想大得多这是血泪经验。4. 五大模块联调Snap7 读西门子 S7-300 的 DB 块、RTSP 抓图和 MySQL 落库4.1 系统功能模块先说清楚数据从哪里流到哪里整套系统的组成论文写得很清楚共 5 大模块图像采集模块、车辆配置信息获取模块、车辆信息采集模块、图像识别模块和系统报警模块。实际工程里新手最容易搞反的是数据流方向——以为是“先拍照再查配置”事实上车辆配置信息是驱动识别逻辑的前提。工作流程是这样的车辆通过 RFID 读码设备进入工位吊具上的数据载体标签被阅读器识别底盘号实时写入西门子 S7-300 系列 PLC 的 DB 块。Python 通过 Snap7 库周期性读取 DB 块中的底盘号写入本地 MySQL。拿到底盘号后先判断是不是新车——如果和识别数据库里已有的底盘号不一致说明来了新车辆需要从车辆配置信息 FIS 服务器的 SQL Server 库里获取车型和配置代码一并存入 MySQL。随后网络摄像头拍照图像预处理完交给 YOLOv5s 模型逐个识别 11 类零件识别结果写回 MySQL。最后系统报警模块根据结果决定是否推送钉钉、触发语音屏。这个链路里PLC 那一环是很多人眼里的黑匣子但论文用的 Snap7 库把它简化成了一个函数调用。4.2 Snap7 读取 PLC DB 块Python 直接和西门子 S7-300 对话import snap7 from snap7.util import get_string # 连接 PLC参数分别是 IP、机架号、槽号 plc snap7.client.Client() plc.connect(192.168.1.10, 0, 2) # 读取 DB1 中从偏移 0 开始、长度 32 字节的区域 # areaS7AreaDB 表示读数据块dbnumber1 是数据块编号 area snap7.types.S7AreaDB data plc.read_area(area, dbnumber1, start0, size32) # 将原始字节解析为字符串32 字节的底盘号 chassis_no get_string(data, 0, 32) print(f当前吊具底盘号: {chassis_no})read_area就是这个系统的核心通信入口。它的四个参数area指定存储区域这里用S7AreaDB对应数据块dbnumber是数据块编号车间里一般会有约定俗成的编号对应不同工位start是起始字节偏移size是读取长度。论文原文写的是read_area(self, area, dbnumber, start, size)和上面的调用方式完全一致。解析底盘号用的get_string是 snap7.util 里的工具函数它按西门子字符串格式第一个字节存长度从原始字节流里解析出字符串。如果你读的不是字符串而是整数或实数snap7.util 里也有对应的get_int、get_real别用错了。还有一个关键点RFID 读取和 PLC 写入不是瞬时的程序要设计轮询间隔论文里的做法是用底盘号比对判断“是否来新车”避免重复处理同一台车。4.3 图像采集RTSP 协议控制普通网络摄像头不花工业相机的钱图像采集模块用的是 OpenCV 的 Python 库基于 RTSP 协议调用普通网络摄像头。这里有一个明确的成本考量工业相机性能好但贵网络摄像头加 RTSP 协议就能满足拍照需求论文强调系统“成本较低”这是其中一个落点。import cv2 import mysql.connector from preprocess import preprocess_frame # 上一章的预处理函数 # RTSP 地址格式rtsp://用户名:密码IP:端口/流路径 rtsp_url rtsp://admin:password192.168.1.20:554/stream1 cap cv2.VideoCapture(rtsp_url) # 读取一帧画面 ret, raw_frame cap.read() if not ret: print(抓帧失败检查 RTSP 地址和摄像头网络) exit() # 预处理降噪、resize、归一化 processed_frame preprocess_frame(raw_frame) # 保存原图用于后续追溯 cv2.imwrite(capture_raw.jpg, raw_frame)这段代码里VideoCapture()的参数就是 RTSP 流地址OpenCV 底层调用 FFmpeg 解流只要摄像头支持 RTSP 协议就能用。抓帧失败的常见原因有两个一是 RTSP 地址里的用户名密码错误二是摄像头并发连接数超限——有些低端网络摄像头只允许 2~3 个并发连接调试时开了一堆窗口后台取流就会断。图像抓取完成后的处理路径是这样的原始图保存一份留底预处理后的图送进 YOLOv5 模型推理。论文系统对每台车会拍多张图、逐个识别 11 类零件识别结果存储到 MySQL 的数据表里。数据库结构论文里给了 13 张表功能分三类实时结果表、历史记录表、图片配置表。实时表用_realtime后缀标识历史表用_history图片配置表存拍照参数和图片路径。如果你的系统准备落地建议直接照这个思路分表——实时表保持短小查询快历史表定期归档别混在一张表里。5. 报警闭环与常见问题排查钉钉 Webhook、语音屏逻辑和五个现场坑5.1 钉钉报警创建自定义机器人后一条 HTTP POST 推给责任人论文里用钉钉作为移动端报警渠道实现方式很标准在钉钉报警工作群创建自定义机器人获取 Webhook 地址用 Python 向这个地址发起 HTTP POST 请求。这部分的代码量和复杂度都极低但对整个系统来说却是闭环里不可缺的一环——没有报警识别得再准也没人知道有问题。import requests import json # Webhook 地址在钉钉群机器人设置里生成 webhook https://oapi.dingtalk.com/robot/send?access_tokenYOUR_TOKEN # 构造报警消息关键信息工位、底盘号、异常零件 payload { msgtype: text, text: { content: f错漏装告警工位 4040底盘号 {chassis_no}零件 {part_name} 未安装 } } # 发起 HTTP POST 请求 resp requests.post(webhook, jsonpayload, timeout5) print(f钉钉返回状态码: {resp.status_code})requests.post的jsonpayload参数会自动把字典序列化为 JSON 并设置 Content-Type。钉钉机器人要求签名机制时Webhook 地址会多一个timestampxxxsignxxx参数用官方给的加签代码生成sign值拼到 URL 上。系统里对报警频率没有做限流但我个人的习惯是给每台车设一个去重标记同一底盘号同一零件异常只推一次避免 PLC 轮询期间重复报警把群炸掉。5.2 语音屏闭环前端 Vue.js、后端 Node.js核心是“人工确认”这个动作钉钉推送是异步的检查员不一定马上看手机所以论文里在生产线尾部署了语音屏实现同步提醒。语音屏的逻辑链路比钉钉复杂一截通过 PLC 实时获取当前车辆底盘号底盘号更新说明来新车了到 MySQL 查这台车的视觉识别结果。全部合格则不提醒放行下一台车存在不合格结果语音屏弹窗并用语音合成技术播报直到检查人员确认后才关闭报警未确认就持续报警。这一段流程里最有工程价值的点是“未确认持续报警”。很多视觉检测系统做到报警弹窗就停了但现场噪声大、人员注意力分散弹窗被忽略是常事。论文的语音屏设计把“确认”作为一个显式动作写进流程报警不被确认就不消失这个设计思路值得复用。技术栈上语音屏用 Vue.js 做前端、Node.js 做后端后端通过 WebSocket 或轮询从 MySQL 读取识别结果再调用语音合成接口播报。报警逻辑树大致是循环读 PLC 底盘号 → 对比 MySQL 最近处理过的底盘号 → 新底盘号则查询识别结果 → 有异常则弹窗 语音播报 → 等人工确认 → 确认后关闭进入下一台车。5.3 现场常见问题排查五个真实踩坑记录坑一新车型上线模型开始误报。现象混线生产中突然进来一个新配置车型系统把本来就正确的零件报成缺失。原因新配置的零件外观和训练集里的都不一样模型没见过这个形态置信度低导致误判。解决论文的做法是每隔一个月用新增的样本图片重新训练模型并把新车型的配置信息加入识别数据库。新车型量产前有个更省事的法子——拿新配置的实拍图先跑一轮批量推理挑出置信度低于阈值的目标人工判断后补入训练集再重训。坑二摄像头逆光零件特征被阴影吞掉。现象上午和下午的识别准确率不稳定同一工位同一车型结果时好时坏。原因现场自然光角度变化零件表面反光或阴影导致图像特征被破坏。解决给拍照工位加补光灯并把样本采集时段覆盖早中晚不同光线条件。论文里做预处理降噪和灰度化已经能减轻一部分光照影响但补光才是最根本的解法。坑三训练 loss 降了召回率就是上不去。现象训练过程 loss 曲线平滑下降验证集精确率尚可但漏检的零件总是那几个。原因正负样本不均衡故障样本零件缺失/装错在训练集里占比太低模型没见过足够多的异常形态。解决采集异常样本时不要只拍正常状态故意模拟错装、漏装情况拍照让模型学会“有异常”和“没异常”的边界。如果异常样本实在难采集先调低模型的 confidence 阈值让报警倾向于更敏感宁多报不漏报。坑四PLC 读到的底盘号是旧的重复触发拍照。现象同一台车被拍了两次或者报警信息张冠李戴。原因read_area的读取时机和 RFID 写入时机存在竞争程序读到上一台车的残留数据。解决论文步骤 2 的做法是关键——从 PLC 拿到底盘号后先和识别数据库里已有的底盘号比对不一致才认为来新车才往下走一致就继续轮询不重复处理。坑五钉钉报警发太多责任人麻木了。现象每天几百条钉钉消息群里没人响应真正出问题时没人第一时间处理。原因所有不合格结果都推给同一个群没有分级也没有闭环确认机制。解决按论文的语音屏逻辑做双通道——语音屏负责现场同步确认钉钉只推给当班责任人并且要求收到后在钉钉里回复确认语音屏未确认时持续报警直到人工到场处理。提示以上五个坑里坑三和坑四最容易被人忽略因为它们不发生在训练阶段而是在系统联调和持续运行阶段。方案评审时就把这两条写进风险清单后面能省很多事。6. 模型月度迭代与横向推广把同一套系统复用到新工位的四个要点论文在结尾部分透露了一个很关键的运营细节系统运行后每隔一个月会重新训练一次模型使准确性达到 99.5% 以上。这个节奏不是随口说的它对应的是样本持续积累的周期——现场每跑一个月就能采集到更多新配置、新光线、新遮挡情况下的真实图片把这些并入训练集重训模型对现场工况的拟合程度会持续提升。如果你要把这套系统横向推广到其他工位或同类产线我建议按四个要点执行。第一样本采集计划先于模型训练新工位先挂一个普通网络摄像头跑两周数据采集攒够覆盖各车型、各配置、各时段的原始图再做标注和训练。第二先复用工位逻辑再换模型文件论文的 PLC 通信、数据库表结构、钉钉报警、语音屏确认流程都是标准件新工位只要改摄像头点位、PLC 地址和模型文件就能跑起来不要重写框架。第三节拍验证不能省上线前实测从车辆到位到报警弹出的完整耗时达不到节拍要求就优先优化预处理和推理串行逻辑。第四ROI 要算总账论文数据表明系统运行前车间漏检返修 240 次/年、经济损失 20 万元/年系统运行近 6 个月相关错漏检返修只有 1 次。省下的返修成本和停台损失足以覆盖普通摄像头、服务器和开发工时投入。对机器视觉应用工程师来说这套系统最值得学习的不是 YOLOv5s 本身而是它把算法、工业通信、数据库、消息推送串成完整闭环的方式。很多视觉项目死在“模型精度够了但没人用”因为它只做了识别没做处置闭环。从那以后我每次在产线上新开一个视觉检测位都会强制自己在方案阶段把三件事写进文档模型迭代节奏、新配置样本采集计划、报警确认闭环。很多返工和误报其实在图纸阶段就能避免。希望帮到你。本文还有配套的精品资源点击获取
返回列表