☰
YOLOv5/v8/v10工业装配缺件检测实战:从标注到部署全流程
2026/10/24 3:01:51 网站建设 项目流程

做工业视觉这几年,装配完整性检查算是我遇到的需求量最大、也最容易翻车的场景之一。PCB插件有没有插到位、密封圈有没有漏装、螺丝有没有少拧、连接器端子是否全部就位……这些需求字面上都是"在图像里找一个目标",但真正落地时才发现,难点根本不在"找到那个目标",而在于"确认本该出现的目标没有出现"。YOLOv5、YOLOv8、YOLOv10这三个版本的模型我都在这类项目里完整跑过一遍,从数据采集、标注、训练、调参到后端推理、UI界面部署,整个链路踩了不少坑,也沉淀出一套可以复用的方法论。这篇就把这套系统的完整搭建过程写出来,包含各版本模型的实际效果对比、缺件场景特有的训练技巧、部署环节的细节处理,以及界面层如何把"有没有缺件"这个结论做成可操作的告警闭环。适合正在做工业质检项目、或者准备用YOLO系列做检测类应用的同学参考。

1. 装配完整性检查的需求拆解:缺件到底在查什么

很多项目一开始就搞错了方向。甲方给的需求是"检测零件有没有装齐",拿到手的标注需求表里写的却是"请在图像中框出所有零件"。这两件事看起来很像,但建模逻辑完全不同。

1.1 视觉质检的常见装配场景

我实际接触过的装配完整性检查大致可以分成三类:

  • 数量型缺失:一排端子本该有12个,结果只有11个;某个线束卡扣本应有4处,实际少了1处。这类问题本质是"计数",传统图像处理做起来已经很吃力,光照一变、角度一变,阈值就崩。
  • 安装状态异常:螺丝装上了但没拧到位、密封圈装上了但没压入槽位、插件插入但卡扣没扣上。这类问题不仅要检测"有没有",还要判断"对不对",对图像细节的要求更高。
  • 错装漏装:把A型号的零件装成了B型号,或者在多个装配位中漏装了其中一个。这类问题往往需要结合装配工位的位置信息才能判断。

我碰到最多的其实是第一类和第三类的组合:一排螺丝本该全部在位,但某些位置是空的;或者多个装配位,其中一个位置什么都没装。这类场景在算法眼里有一个共同特征——你要检测的"缺件"本身在图像上没有任何像素支撑,因为它根本不存在。

1.2 检测"缺失状态"不等于检测"目标物体"

这是整个项目里最关键的一个认知转变。

常规目标检测的逻辑是:图像里有猫,就在图像里输出一个猫的框。但缺件检测的逻辑变成了:检测模型在图像里到处找"某个螺丝位的螺丝",如果整个画面都没有输出这个类别,系统才判定"缺件"。

所以我在设计标签的时候不会只标注"螺丝"这一个类别,而是会按装配位来设计标签体系。比如一个面板上有四个螺丝位,我就分别标成"screw_pos_1""screw_pos_2""screw_pos_3""screw_pos_4"。模型的任务不是笼统地找螺丝,而是精确回答"每个装配位上有没有属于它的那个螺丝"。这样做的好处是:当3号位缺螺丝时,模型对screw_pos_3这个类别的检出框数量为0,系统可以精确定位到是3号位出了问题,而不是只知道"少了一颗螺丝,但不知道少在哪"。

如果按零件类别标注,模型只会告诉你"图里有3个螺丝框",你还得自己写一堆几何逻辑去判断哪个装配位是空的,代码里全是坐标判断和阈值试探,既脆又难维护。

1.3 传统方案为什么会在装配缺件场景上失灵

在没上深度学习之前,这类项目通常用模板匹配、边缘检测加形态学处理来做。说实话,在光照恒定、工装固定、零件对比度高的理想条件下,传统方案也能跑出不错的准确率。但现场一换班次、换天气、换光源角度,同一套阈值就失效了。金属零件的反光、塑料件的弱纹理、零件之间的互相遮挡,都会让手工设计的特征彻底失效。

YOLO系列模型在这类场景的核心价值,在于它直接学习"装配位+零件外观"的高维特征,对光照变化、微小形变、部分遮挡都有更好的鲁棒性。这也是为什么现在越来越多的质检项目直接跳过传统算法、一步到位上深度检测。

2. 数据集构建:从现场采集到标注规范的完整流程

数据集是整个系统里投入产出比最高的环节。模型结构可以复现、训练参数可以抄,但数据集是你项目现场独有的,也直接决定最终准确率的天花板。

2.1 采集策略:环境、角度、光照与负样本

很多团队采集数据时只想着"多拍零件",忽略了环境变量的覆盖,导致训练出来的模型在实验室里跑得很好,一到产线就崩。我的经验是,采集阶段就要把现场所有会出现的变量记录下来:

  • 光照变化:产线不同时段的光照差异、不同工位的光源角度差异、甚至不同批次的工件表面反光程度差异,都要覆盖。如果现场有强反光,不要刻意避开,反而要多拍反光样本,让模型学会视而不见。
  • 工作距离与角度:固定工装下相机的高度和角度是可控的,但实际生产难免有工件偏移、料架倾斜。采集时在允许范围内尽量模拟这些偏移,给模型一点"容错空间"。
  • 负样本:缺件状态下的图像是重中之重。这个最容易被忽略,因为正常生产线上缺件本身就是异常状态,不会大量出现。我常用的做法是:在实验室里人工拆掉零件后拍摄缺件样本,或者找产线调试阶段的故障品来拍。

采集数量的参考标准:每个装配位、每种状态至少500到1000张,正负样本比例控制在3:1到5:1之间。负样本太少,模型会对"缺件"这个状态不敏感。

2.2 标签设计思路:按零件类别还是按装配位状态

我前面提过,按装配位设计标签是缺件检测的核心技巧。具体操作上,我会在标注规范里这样定义:

标签名含义判定标准
pos1_screw1号装配位的螺丝螺丝完整可见且已拧入到位
pos2_screw2号装配位的螺丝螺丝完整可见且已拧入到位
pos_missing空装配位装配位可见但无零件

这里有一个关键细节:空装配位也要标一个类别,叫"pos_missing"。为什么要这么干?因为单纯依靠"没检出"来判定缺件,会带来一个麻烦——如果工件整体偏移了、或者某个装配位被其他物体遮挡了,模型会误判为缺件。但如果模型能明确识别"装配位存在且为空",系统就可以区分"装配位被遮挡(不确定)"和"装配位可见但无零件(确定缺件)"两种情况。

这个标签策略让我在后续做告警逻辑时省了很多事,也让模型的输出信息更丰富,不只是0和1的二元判断。

2.3 标注工具与格式转换

标注阶段我用的是一款轻量的开源标注工具,矩形框标注完全够用,支持VOC格式和YOLO格式导出。实际工作中建议直接导出YOLO txt格式,省一次转换。如果团队内部已经习惯用COCO格式管理数据,再单独做一次格式转换脚本也很方便。

但有几个点需要特别注意:

  • 不要用自动标注工具直接生成标签然后不校验。装配完整性场景里,零件的边界往往模糊、遮挡多,自动标注的框很容易偏移,后期训练时会产生大量错误监督信号。
  • 标注时强制要求"模糊不清就跳过"。一张图里如果某个装配位因为反光完全看不清,不要强行标注。标注错误比不标注危害更大。
  • 每个类别的框尺寸分布要提前统计。如果所有螺丝框都只有15×15像素,后面训练时的anchor参数、输入分辨率都要对应调整。

2.4 数据增强的关键取舍

YOLO系列自带Mosaic、HSV扰动、随机翻转等增强策略,但这些增强并不都适合装配场景。有一个典型教训:某次我在一个电路板检测项目里开启了默认的随机翻转增强,结果模型训练结束后,对镜像的电路板图像检测效果很好,但对正常方向的电路板反而出现了一堆误检。原因很简单——装配体是有方向性的,芯片的方向、排针的顺序都是确定的,你让模型学会看"镜像的电路板",反而干扰了它对真实方向的特征记忆。

正确的做法是:先确定装配体在产线上是否有方向约束,再决定是否开启翻转增强。螺丝这类旋转对称件可以做90度旋转增强,但字母序列、方向性结构绝对不能做镜像翻转。

另外,针对金属反光场景,我会额外加上随机亮度对比度扰动、高斯噪声和轻度模糊。这些操作能模拟产线光源衰减、镜头脏污等实际状况,对提升模型鲁棒性效果明显。

3. YOLOv5/v8/v10选型:架构演进与实际效果对比

在同一个数据集上,我把YOLOv5、YOLOv8、YOLOv10三个版本都完整训练了一遍,分别测了精度、速度和部署便利性。选型这事不能只看某个榜单数据,要结合你自己的硬件条件和推理框架来综合判断。

3.1 三个版本的架构差异速览

特性YOLOv5YOLOv8YOLOv10
主干网络CSPDarknetCSPDarknet改进版(C2f模块)CSPDarknet改进版 + 轻量化设计
Anchor策略Anchor-BasedAnchor-FreeAnchor-Free
检测头Coupled HeadDecoupled Head双头结构(one-to-many + one-to-one)
NMS后处理需要需要不需要(推理端)
官方模型规模n/s/m/l/xn/s/m/l/xn/s/m/l/x
部署生态成熟成熟相对较新

YOLOv5的Anchor-Based机制在训练时需要预先聚类锚框尺寸,检测头耦合在一起也会让分类和回归任务共享参数,性能上稍弱。YOLOv8把检测头解耦成两个分支,分类和回归各算各的,收敛更容易,效果也有提升。

YOLOv10最有意思的变化是去掉了NMS后处理,通过双头结构在训练阶段同时优化一对多和一对一分配,推理时只需取一对一分支的输出。这个设计在理论上有两个好处:一是省掉了NMS的耗时,二是避免了NMS参数调整带来的精度损失,部署代码也能简化。

3.2 同数据集下的实测对比

我在同一个装配面板数据集上做过一次横向对比实验,数据集包含12个类别、约8000张训练图、正负样本都有。硬件环境是一张桌面级独立显卡,推理时关闭了所有数据增强,输入分辨率统一为640×640,测试集共1200张图。

模型版本模型大小mAP@0.5mAP@0.5:0.95单张推理耗时(ms)
YOLOv5s14MB0.9320.7814.8
YOLOv8s22MB0.9470.8135.2
YOLOv10s25MB0.9410.8064.6
YOLOv8n12MB0.9210.7623.4
YOLOv10n14MB0.9180.7543.1

需要说明的是,这组数据是某个具体数据集上的参考值,不同场景下结论可能会有变化。但从整体趋势看,YOLOv8s在精度上略优于同尺度的YOLOv5s和YOLOv10s;在推理速度上YOLOv10确实有优势,因为少了一个NMS步骤,在CPU或边缘设备上的差距更明显。模型越小,YOLOv10的速度优势越突出。

3.3 选型建议:别只盯着mAP

我的实际建议是分场景来选:

  • 如果GPU资源紧张、产线节拍要求高,优先选YOLOv10n或YOLOv8n。n系列模型参数量小、速度快,适合部署在边缘工控机上。实测中只要数据集标注质量过硬,n系列也能达到可用精度。
  • 如果检测对象是小零件、对精度要求极高,YOLOv8s或YOLOv8m是更稳妥的选择。s系列在速度和精度之间比较均衡,我多数项目最终采用的是v8s。
  • 如果已有生产系统基于YOLOv5构建、团队对其API和部署栈非常熟悉,不必强行升级到v8/v10。YOLOv5在工业落地场景里依然很能打,尤其是它的官方生态里有大量现成的部署样例和问题解决方案。
  • YOLOv10虽然去掉了NMS,但它转换成Open Neural Network Exchange格式后,输出头里多了一个分支,对于习惯处理传统检测头输出结构的工程团队来说,前期集成会增加一点学习成本。

选型还有一个容易被忽略的因素:推理引擎的支持程度。YOLOv8和YOLOv5的导出对接最顺滑,YOLOv10在国外某边缘设备和国内主流推理框架上的适配就相对慢半拍。部署前先在目标硬件上跑通一个小样,再决定正式版本。

4. 训练与调参:面向缺件检测的专项处理

模型结构定下来之后,训练阶段才是最考验功力的部分。缺件检测场景和通用检测场景在训练上有一批独有难点:数据不均衡、类别语义重叠、推理时"无检出"带来的系统级误判。

4.1 数据不均衡的处理

每条产线里,正常装配位的正样本数量总是碾压缺件负样本的。我遇到过一个项目,一个装配位有4000张正常样本,缺件样本只有120张,模型训练出来之后对缺件状态的召回率只有不到40%。

这个问题的处理要分两层:

  • 数据层面:欠采样正样本,把每个装配位的正负样本比例压到4:1以内;同时用裁剪、旋转、缩放生成缺件区域的局部样本,让模型多看"空位"长什么样。
  • 损失函数层面:在YOLOv8的训练配置里,可以对不同类别设置不同的损失权重,把缺件相关类别的权重提到1.5到2倍。我常用做法是先跑一版基线,统计混淆矩阵,找出那些"容易把空位看成有零件"的装配位,再单独提高对应类别的权重。

另外,Warm-Up阶段不要开太强的时间增强,等到模型基本收敛后再把Mosaic强度拉高,效果会更稳定。

4.2 置信度阈值与区域判定逻辑

训练完成后,推理端的置信度阈值设定是一个精细活。通用检测场景里,阈值一般设0.5左右就行;但在缺件检测里,阈值设太高会让小螺丝框被过滤掉,直接触发"缺件"误报;设太低又会产生大量幽灵框,把正常的装配位判成异常。

我的做法是分两步:

第一步,按类别单独设定阈值。尺寸大、特征明显的零件(如连接器壳体)阈值可以设到0.6以上;尺寸小、容易模糊的零件(如细长螺丝、卡扣)阈值降到0.3到0.4。这个可以通过YOLO推理时的class-specific阈值参数实现。

第二步,结合装配位坐标做区域判定逻辑。我在标签体系里已经定义了每个装配位的标签,推理时直接检查每个装配位标签在当前帧的检出框数量。如果该装配位检测框数量为0且背景区域没有遮挡物,系统判定缺件;如果检测框数量为0但检测到遮挡物类别(比如人手或者工具残留),系统判定"复检",而不是直接报缺件。

这个区域判定逻辑写在后端,200行代码就能搞定,但能把系统的误报率降低一个量级。

4.3 训练参数与验证策略

训练超参我通常以官方预训练权重作为起点,输入分辨率320×320或640×640,批大小根据显存动态调整到显存占用90%左右,初始学习率0.01,余弦退火调度,全训练周期300轮。

验证策略上,要注意不能简单随机划分训练集和测试集。装配场景中,同一批工件的多张图像相关性很强,如果随机划分,模型很容易通过记忆背景纹理而不是零件特征来实现高准确率。我把数据按"工件批次"划分,同一批次的图全部进训练集或全部进测试集,这样验证结果才接近真实产线的表现。

训练结束后不要只看mAP。在缺件场景里,mAP高不代表"缺件报警"准确率高。关键是看每个装配位类别的召回率,尤其是低置信度区间下的召回率分布。我会输出每个类别的F1与置信度关系曲线,找出每个类别在F1最高点的阈值,再导出到推理配置里。

5. 推理部署:模型导出、量化与实时性能测算

训练完成后,模型从PyTorch权重到真正能在产线跑的推理程序,中间还有一段路要走。这一步最容易出现"训练精度高、部署精度暴跌"的问题。

5.1 导出与转换流程

我的标准流程是这样:

  • 用官方仓库的export脚本把PyTorch权重转换为Open Neural Network Exchange格式文件。导出时要固定输入尺寸,避免动态尺寸导致的推理引擎兼容问题。
  • 用ONNX Runtime直接做CPU/GPU推理测试,确保输出的检测框、类别、置信度与PyTorch推理结果一致。这里有个经验:由于不同推理引擎实现浮点运算的顺序有差异,框坐标会有毫米级的偏差,只要不超过两个像素,就属于正常范围。
  • 需要极致性能时再做量化:GPU上做FP16半精度量化,CPU或边缘设备上做INT8量化。INT8量化需要用校准集来统计每个激活层的数值范围,校准集要包含反光、缺件、遮挡等典型困难样本,否则量化后检测精度会掉得很厉害。

我碰过一次比较极端的例子:某边缘设备上直接用默认校准集做了INT8量化,模型文件从25MB缩到7MB,速度提升明显,但缺件状态的召回率从93%掉到71%,后来换成带缺件样本的校准集,召回率才回到88%。

5.2 推理性能测算与节拍匹配

部署前需要算清楚推理耗时的余量。我一般按产线节拍来倒推:

节拍是每秒检测1个工件,有效工作时间占80%,那单次检测的端到端耗时预算就是800毫秒。相机采集耗时约80毫秒,图像传输约50毫秒,UI刷新和逻辑判断约100毫秒,留给模型推理的时间大约570毫秒。YOLOv8s在桌面级显卡上单张640×640的推理耗时约5毫秒,余量非常充足。

但如果产线节拍是500毫秒,或者摄像头数量从1路增加到4路,模型推理时间预算就紧张了。这时候要么换更高性能的推理引擎,要么把输入分辨率降到480×480并用FP16推理。

5.3 边缘设备上的工程化处理

嵌入式工控机上的部署和小型GPU服务器完全不同。主要问题是显存小、CPU弱,不能直接套用桌面端的部署方案。

我通常的做法:

  • 先用FP16模型跑一轮测速,如果达不到节拍要求再考虑INT8。
  • 批量推理时开启动态批处理,把多路相机的图像拼成一个批次送进模型,可以显著提升吞吐量。
  • 使用独立推理进程,避免UI界面卡顿拖慢检测。检测进程和UI进程之间通过消息队列通信,检测结果带上时间戳,UI异步刷新,保证界面流畅性。
  • 模型热更新机制:产线换型时,通过配置文件切换到另一套模型。注意模型加载时需要锁定推理进程,不能让新老模型同时占用显存。

6. UI界面部署:从检测结果到可操作的告警闭环

很多项目死在最后一步:模型效果不错,但交付给现场人员的界面难用、信息不完整、告警逻辑不清晰,导致操作员根本不信任这套系统,最后还是靠人工目检。UI界面不是锦上添花,它直接决定系统能不能在产线真正用起来。

6.1 系统架构与后端设计

这套系统的软件架构我建议前后端分离,后端只做推理和数据管理,前端负责展示和交互。

后端我用的是Python的FastAPI + Uvicorn,单独开一个推理服务,接收前端传过来的图像或视频流地址,调用加载好的Open Neural Network Exchange格式模型完成检测,再把结果通过WebSocket实时推给前端。

核心接口就这么几个:

  • 单张检测:上传图片,返回检测框、类别、置信度、缺件判定结果。
  • 视频流检测:接受RTSP/本地视频流地址,持续输出每帧的检测结果。
  • 历史记录:按时间、工位、装配位查询历史检测记录和图像。
  • 系统配置:阈值、区域判定参数、告警开关的在线修改。

这里有一点要注意:单张检测接口的响应时间要控制在200毫秒以内,否则前端操作员会觉得系统"卡"。这个时间主要花在图像上传和推理上,图像压缩成JPEG传输、推理进程常驻,问题不大。

6.2 检测结果的可视化与数据存储

前端界面我用的是Vue3 + ECharts,检测结果展示设计成"三区一表":

  • 左侧实时图像区:显示当前检测图像和模型画出的检测框,缺件位置用红色框标记,正常装配位用绿色框标记。框的坐标、类别、置信度直接标注在框上,方便操作员核对。
  • 右侧状态面板区:每个装配位对应一个状态卡片,显示"通过""缺件""复检"三种状态,状态切换时卡片颜色联动变化。如果某个装配位连续多次触发缺件告警,状态卡片会进入"持续异常"高亮状态。
  • 底部趋势图区:按时间维度展示每个装配位的合格率变化曲线。这个功能虽然简单,但对产线管理者特别有用——可以看出某个工位的合格率在某个时间段内显著下降,提示可能是该工位夹具磨损或操作工状态波动。
  • 历史记录表:每条检测记录包含时间、工位、检测结果、图像缩略图、操作员确认状态。

数据存储我用SQLite就能满足单机部署的需求。如果要做多工位、多产线的汇总分析,再升级到MySQL。存图像时注意控制大小,一般只保留缺件告警图像和最近一万条正常检测的缩略图,超出部分自动清理。

6.3 交互流程与告警策略

告警是整个界面的灵魂。单纯在界面上弹一个红框是不够的,还需要配声音提醒、状态灯联动和工位锁定机制。我的经验是这样设计:

  • 检测到缺件时,界面弹出模态框并播放提示音,显示缺件的装配位编号和图像证据。
  • 缺件告警超过设定次数(比如连续3次)后,系统自动进入"待复检"状态。此时产线该工位的自动化设备可以联动停机,不允许继续装配,等操作员确认处理后才恢复。
  • 操作员对告警结果进行"确认"或"误报"标记。这个反馈数据非常重要——我要求每个项目在试运行阶段必须保留所有误报记录,每周汇总误报类别和根因,用来迭代模型和数据。

我还遇到过一种特殊需求:装配线采用Andon系统,告警信号要直接推送给产线管理看板。实现也不复杂,后端在检测到缺件时向看板系统发送一条HTTP回调即可,前端只需要展示回调状态即可。

7. 实测踩坑记录与后续扩展方向

最后把我在多个装配完整性检查项目里踩过的坑集中梳理一遍,很多问题不是模型能力不够,而是工程化细节没做到位。

7.1 高频问题排查记录

第一个坑:反光让模型产生间歇性漏检。金属螺丝在特定光照角度下会形成高亮光斑,把螺丝十字槽完全淹没。解决方案是在采集阶段加入多光源角度的样本,同时训练时用强HSV扰动和随机亮度变化来模拟这种工况。

第二个坑:缺件样本太少导致模型"学不会空位"。遇到一个项目中5号装配位的缺件样本只有40张,模型对该装配位的召回率始终上不去。处理方式是采集阶段专门安排一次"批量拆卸拍摄",把所有装配位依次拆掉并各拍200张,数据量上来之后问题立刻缓解。

第三个坑:训练/测试集划分不严格导致模型"作弊"。一次项目现场测试时,测试集里混入了同一批工件的多张图像,模型对其中一张图"记住了"背景特征,导致误认为模型已经达到99%准确率。后来严格按工件批次划分数据集,准确率从虚高的99%回落到真实的94%,但这才是我可以放心交付的数字。

第四个坑:动态分辨率导致推理速度波动。前端视频流分辨率偶尔会变化,但模型输入尺寸是固定的,直接resize会导致检测精度下降。后来我固定视频帧,所有帧统一缩放到模型输入尺寸再推理,速度才稳定下来。

第五个坑:置信度阈值全局统一造成的误报。不同装配位的零件大小和背景复杂度不同,用同一个阈值会出现小零件处漏检、大零件处误报。改成按装配位独立设置阈值后,误报率下降了约70%。

7.2 可扩展方向

这套系统做完之后,至少有四个方向值得继续往深了做:

一是从"缺件检测"升级为"装配质量检测"。把安装角度、插入深度、扣合状态等维度也纳入检测范围,这对数据集和标签体系的挑战更大,但价值也更高。

二是引入多视角检测。某些复杂装配体的缺件在单一视角下无法判断,可以增加一个或多个辅助相机,把多视角推理结果融合后再下结论。

三是接入生产管理系统。检测结果自动关联工单、批次和员工工号,实现装配质量全流程追溯,这对汽车零部件、电子制造等行业很有吸引力。

四是用小样本学习或者半监督方案减少数据标注成本。产线换型时,老模型可以用少量新样本快速适配,减少每次换型时的数据采集周期。

我自己的感受是,装配完整性检查这类项目,真正决定成败的从来不是某个模型版本的选择,而是对业务场景的理解深度、数据集构建的认真程度,以及部署环节的工程化能力。先把这三个基础打牢,YOLOv5还是v8还是v10,更多只是一个顺手的选择。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询