资讯动态

基于YOLOv26改进的机械零件毛毡与指示器检测方案

发布时间:2026/10/17 12:12:12 来源:尧图企业网站定制
机械零件的毛毡位置检测加上指示器状态判别这几个词放到一起很多做视觉的朋友第一反应是这不就是目标检测里的常规任务吗其实真到产线上跑一遍就会发现事情远没有想象中那么简单。毛毡在零件上贴没贴正、有没有偏移、是不是漏贴指示器指针指向是否到位这些问题用传统视觉做光照一变就崩用普通检测模型做小目标漏检又压不下去。我在某精密零件产线上做过一套YOLOv26改进方案整个过程从取图、标注、改网络到部署踩了不少坑这里整理成一篇完整的实操记录给做工业质检的朋友一个参考。这套方案的核心逻辑很简单用YOLO系列做两步事第一步把毛毡和指示器都检测出来第二步在检测框的基础上加一个角度/位置判定头判断装配是否合格。整个过程既要保证产线节拍内的实时性又要应对零件表面反光、毛毡低对比度、指示器目标小这几类典型困难。下面我把完整的技术路线、改网络细节和工程落地经验都展开讲。1. 项目背景与需求拆解毛毡和指示器到底要检什么1.1 产线里的真实场景先还原一下现场。某自动化装配线上机械零件壳体在完成加工后需要在指定凹槽内贴装一块毛毡垫片用于减震和密封同时在壳体侧面的装配孔位装一个指示器用来标识安装方向或工作状态。质检环节要求在两到三秒内判断两个问题毛毡是否贴装到位、有没有偏移或翘边指示器是否安装正确、方向是否指向规定的角度区间。这种场景在很多工厂里都靠人工目检。问题是毛毡是柔性的边缘容易翘起深色毛毡贴在深色金属件上对比度很低看久了眼睛非常容易疲劳。指示器本身很小在外观上只是一个带箭头或指针的塑料件方向差个十几度人工不仔细看根本发现不了。我接过需求的时候产线反馈的漏检率大概在千分之几听起来不高但放到年产量几十万的规模上就是几百个不良品流到下游客户投诉一多整个批次都要排查。1.2 两类目标的检测难点我把难点拆成两部分。毛毡侧的难点首先是低对比度很多毛毡是深灰或黑色零件壳体也是深色金属两者亮度和纹理都很接近其次是边缘不规则毛毡是柔性材料切割边缘会有细微毛刺加上贴装时可能受力不均轮廓和标准模板对不齐再次是反光和油污零件在加工后表面会残留切削液形成不规则反光毛毡区域也可能被油污污染变成深色斑块。指示器侧的难点更偏向小目标和角度连续性。指示器在画面里通常只有二三十个像素的大小常规目标检测模型的浅层特征还没融合到全局信息时小目标的响应很容易被背景淹没。另外指示器指针的朝向是连续角度不是离散类别直接用分类思路做角度差一两度很难用类别区分必须额外设计回归分支。1.3 为什么我选了YOLO路线而不是传统视觉一开始也考虑过传统机器视觉方案阈值分割加模板匹配或者找轮廓算重心。毛毡检测上如果现场光照稳定用固定阈值分割毛毡区域然后和标准位置对比偏移量确实能跑通。但问题在于光照不可能永远稳定零件的来料批次也有色差阈值稍微调不准误检率就直线上升。指示器方向检测如果用模板匹配零件在工装上有轻微旋转模板就要跟着转计算量成倍增长而且小尺寸指示器的纹理信息少匹配得分极度不稳定。所以最终选择了YOLO系列做基础框架。原因有几个第一它本身是工业落地最成熟的检测器之一导出部署的链路很顺畅第二它的多尺度特征融合结构天然适合同时处理毛毡这种较大目标和指示器这种极小目标第三YOLO的检测头是解耦的分类和回归分开改造成本低方便我额外加角度分支。说明一下标题里的YOLOv26并不是某个官方版本而是我在项目里针对这个产线做的定制版本代号主干、颈部、检测头都做了模块级改动训练和推理流程还是沿用了YOLO系列的成熟体系。这样既享受社区生态的便利又不被原版结构绑死想加什么模块都方便。2. 数据准备与标注规范决定上限的第一道工序2.1 取图方案与光照处理数据是所有检测方案的上限。我先说取图这一步很多项目会草率处理觉得装个相机能拍到就行结果后面模型再怎么调都救不回来。现场我用了面阵工业相机加定焦工业镜头分辨率五百万像素搭配环形低角度光源。选低角度光源的原因很直接低角度光能让毛毡表面的纤维纹理显现出来而平行于表面的光又不会在金属壳体上形成大面积镜面反射。实测下来低角度光下毛毡边缘比高角度光要清晰不少这对后续低对比度目标检测帮助非常明显。镜头光圈我放在了F8左右景深覆盖零件表面高度差同时避免光圈太大导致的边缘模糊。取图覆盖度上我建议至少满足这几类不同来料批次的零件、不同光照亮度下的图、零件在工装内轻微偏移和旋转的图、毛毡翘边和偏移的异常图、指示器不同装配角度的图。数量上不要盲目追求多我这边初期采集了两千多张有效图覆盖了七种异常形态比直接丢一万张重复姿势的图效果要好得多。这里有个参数计算可以参考。视场范围大概120毫米相机分辨率五百万像素水平方向约2500像素算下来每毫米大约20像素。最小的指示器目标实际尺寸约2毫米在图中约40像素经过模型下采样后深层特征图上的响应其实非常小这也是后面要加小目标检测层的直接依据。2.2 标注体系设计类别怎么分、角度怎么标标注是很容易拍脑袋决定后期返工最痛苦的一步。毛毡检测我建议不要按正常、偏移、翘边去分多个类别因为这几种形态之间没有明确边界分类模型很容易被边界样本搞迷糊。更好的做法是毛毡统一标成一类只把毛毡主体区域框出来偏移和翘边交给后处理逻辑判断。检测模型负责稳定地找到毛毡在哪位置是否合格由代码用框中心坐标和标准位置偏差来判断。指示器侧就复杂一些。指示器本体要标成单独类别另外因为要判断方向我在标注时额外记录一个角度属性。具体做法是标注工具里先画指示器的外接框再单独点两个点一个在指示器旋转中心一个在指针尖端两点连线方向作为角度真值。这样标注信息包含两部分检测框交给模型回归角度信息单独存成一份JSON或者合并进TXT文件。同步做一份代码示例方便批量转换import json import math def compute_angle(center, tip): dx tip[0] - center[0] dy tip[1] - center[1] angle math.degrees(math.atan2(dy, dx)) if angle 0: angle 360.0 return angle # 标注文件示例读取检测框和两个关键点计算角度 with open(annotation.json, r) as f: ann json.load(f) box ann[indicator_box] center ann[rotate_center] tip ann[pointer_tip] angle_value compute_angle(center, tip) print(box, angle_value)2.3 数据增强与难例挖掘工业场景的数据增强和公开数据集不太一样。公开数据集常用的大幅旋转、裁剪、翻转在工业场景里要谨慎。零件在产线上有相对固定的摆放姿态模型如果学了太多大幅旋转推理时反而会对真实小角度扰动不够敏感。我这边用的增强策略是随机亮度对比度扰动、HSV色域微调、高斯噪声、轻微仿射变换幅度都控制在小范围。重点放在模拟光照波动和表面反光上比如随机在局部区域叠加一个高光斑块。难例挖掘这块我把现场跑测出现过的典型漏检和误检图都单独归档人工复核后逐步补充到训练集里。常见难例有三类边缘破损的毛毡、被油污污染导致纹理缺失的毛毡、指示器处于逆光或阴影下的图。这些图在初期模型里基本都是错检补充后再训练提升非常明显。我的原则是难例优先于数量十张精选难例对模型的提升可能超过一百张普通重复图。3. YOLOv26改进设计从主干、颈部到检测头的改动3.1 改进思路与模块选型模型改进我给自己定了几条红线不引入计算量过大的通用模块、不破坏YOLO系列原有的训练稳定性、所有改动要有可解释的动机。基于这三点我在主干和颈部做了针对性调整而不是堆叠一堆注意力模块。主干部分保留了YOLO系列的CSP风格结构但在每个关键阶段后端接了一个轻量注意力模块我实测用SimAM这一类无参数注意力效果稳定且完全不影响推理速度。为什么不用SE或者CBAM因为这两个模块会增加少量参数和计算量在毛毡这种低对比度场景下收益并不明显SimAM基于神经科学能量函数的思路直接对特征图的空间关系建模在深色零件背景上的响应更干净。颈部部分我把特征融合改成了带权重的双向融合方式。标准的FPN加PAN在多数场景够用但毛毡和指示器这两个目标的尺度差异太大普通等权相加会把小目标信号稀释掉。我给浅层特征在融合时加了更高的权重让指示器的小目标信息在网络前向传播过程中保留更充分。这个改动在计算量上几乎可以忽略却让小目标召回率提升了几个点。3.2 小目标检测层与注意力增强指示器目标小是这次项目最头疼的问题。原版YOLO默认从P3层开始做检测也就是特征图分辨率是输入图像的八分之一。输入640分辨率的图最小检测层特征图是80乘80每个像素对应原图8像素指示器40像素大小的目标在特征图上只有5个像素左右特征信息非常有限。解决思路是增加一个P2检测层也就是从骨干网络中提前引出浅层特征用四倍下采样的特征图来检测小目标。增加之后输入640分辨率时特征图变成160乘160小目标的特征响应从5像素变成10像素信息量翻倍。代价是计算量增加一部分后面部署时用TensorRT做加速就可以对冲掉。我在实验里做了对比是否加注意力模块、是否加P2层结果差别很大配置毛毡mAP0.5指示器mAP0.5指示器小目标AR基础版YOLO96.882.468.5基础版P2层97.188.279.3基础版P2层SimAM97.589.681.8完整改进版YOLOv2698.291.384.6可以看到P2层对小目标的提升是决定性的注意力模块在低对比度毛毡上也有贡献。3.3 指示器角度分支的实现角度分支是这套改进里最核心的定制部分。检测头原本输出的是分类概率和边界框坐标我在这之外增加了一个角度回归分支输出两个值角度的正弦和余弦。为什么不直接输出角度值因为角度在0度到360度之间有周期跳变比如直观的350度和10度其实只差20度但如果让模型直接回归角度值数值上差了340度损失函数会认为这是非常大的误差训练很难收敛。用正弦余弦编码后角度相似的目标在数值空间里也相似回归就稳定很多。实现上可以用一段简单的网络定义来说明import torch import torch.nn as nn class AngleHead(nn.Module): def __init__(self, in_channels256): super().__init__() self.fc nn.Sequential( nn.Linear(in_channels, 128), nn.ReLU(inplaceTrue), nn.Linear(128, 2) # 输出 sin(theta), cos(theta) ) def forward(self, x): # x: [batch, anchors, in_channels] out self.fc(x) # 归一化到单位向量保证 sin^2cos^2 约等于 1 norm torch.norm(out, dim-1, keepdimTrue).clamp(min1e-6) return out / norm这里归一化非常关键。如果不归一化sin和cos的平方和不是1推理时用atan2还原角度会引入偏差。训练时损失函数用Smooth L1或者MSE都行我在实践中发现Smooth L1更稳因为sin和cos的值域在-1到1之间不会出现极端梯度。推理时角度还原def decode_angle(sin_val, cos_val): import math angle math.degrees(math.atan2(sin_val, cos_val)) if angle 0: angle 360.0 return angle3.4 轻量化约束下的取舍工业部署最现实的问题就是算力。这套改进版在加了P2层和注意力模块后参数量相比基础版增加不多但每秒浮点运算次数会上升一截。我测过在嵌入式GPU上输入640分辨率基础版推理约8毫秒完整改进版约12毫秒对两到三秒节拍的产线来说完全够用。如果后续要换更小算力的设备可以走两条路一条是把输入分辨率降到448推理能快一半代价是小目标精度下降几个点另一条是把P2层只在指示器类别权重高的场景下保留蒸发出一个轻量子模型。项目初期建议先跑完整版确认精度达标后再考虑裁剪不要一上来就为了部署难度牺牲精度后面排查问题会非常痛苦。4. 训练配置与调参实战4.1 环境搭建与依赖训练环境基于PyTorch搭建。我用的版本组合是Python 3.10、PyTorch 2.1、CUDA 12.1依赖安装直接用requirements管理。训练脚本的启动方式参考YOLO系开源代码整体迁移成本很低。pip install torch2.1.0 torchvision0.16.0 --index-url https://download.pytorch.org/whl/cu121 pip install opencv-python pyyaml tqdm onnx onnxruntime训练前一定要下载backbone的预训练权重。工业数据量远小于公开数据集几百万张的量级随机初始化从头训练很难收敛到好结果。预训练权重相当于帮模型先学会了通用特征再来学毛毡和指示器就只需要微调高层语义训练速度快得多最终精度也更高。4.2 训练参数与实验配置参数配置上我记录一份实际跑通的配置供参考。输入分辨率640乘640批大小16初始学习率0.01使用Warmup策略前三个epoch把学习率从0.001线性提到0.01然后余弦退火降到最终0.0001。训练两百个epochEMA指数移动平均开启权重衰减设为0.0005。train_params: img_size: [640, 640] batch_size: 16 epochs: 200 lr0: 0.01 warmup_epochs: 3 weight_decay: 0.0005 ema: True workers: 8批大小这个参数要看显存来定。我的卡是24G显存16的批大小加上640输入刚好跑满训练稳定。如果显存只有12G批大小降到8同时学习率按比例缩小到0.005。这是一条我在多个项目里验证过的经验学习率跟随批大小等比例缩放能避免收敛波动。4.3 训练曲线怎么看、怎么调训练过程中我会同时盯两个东西训练损失和验证集上的mAP曲线。工业场景数据量不大模型通常跑不到两百个epoch就开始有过拟合迹象。判断方法很直接训练损失还在降但验证mAP不再上升或者验证损失反弹说明模型开始死记训练集了。我一般不会等到过拟合发生再处理而是用早停策略记录验证mAP最高的epoch连续二十个epoch没有刷新纪录就停止训练。在毛毡这个项目上大概一百五十个epoch左右指标稳定后续继续训练只会让指标在小范围内震荡不如尽早停止去跑部署验证。还有个容易踩的坑是类别不均衡。毛毡类别的样本数量远多于指示器训练时损失会被毛毡主导指示器学不好。解决办法是给指示器类别加更高的损失权重或者做类别采样让每个batch里两类样本比例接近。我实际用了损失权重方案指示器权重设为毛毡的两倍几分钟就能改完效果立竿见影。5. 评估与迭代mAP、误检与漏检的平衡5.1 指标选型与实验对比模型的评估指标不能只看一个mAP工业质检要分精查查全和误检率两个维度。我用的是mAP0.5作为主指标因为它对框位置的敏感度适中更贴合毛毡位置判定需求同时额外关注小目标的召回率用AR平均召回率来评估指示器这类小目标是否容易漏。在最终完整改进版上毛毡mAP0.5到了98.2指示器到了91.3。误差主要是小尺寸指针在极端反光下丢失特征。评估集要独立于训练集和验证集最好是直接从产线上新采的一批图上评估。我一开始吃了亏用同一次采集的数据切分训练和验证指标虚高换了一批新批次零件后精度掉了很多。后来改为每次从新批次收集图专门追加到独立评估集里这才得到能真实反映产线表现的指标。5.2 典型失败案例复盘第一类失败是浅色毛毡漏检。某批次毛毡颜色偏浅和铝制零件表面灰度接近模型直接漏框。排查后确认是训练集里浅色毛毡数量不足补充几百张浅色毛毡图后解决。第二类失败是金属反光导致毛毡误检。零件表面切削液残留形成不规则高光高光区域的纹理和毛毡纤维在灰度上有相似性模型把高光误判为毛毡。处理方式是采集更多反光样本作为负样本训练同时在数据增强里加入局部高光模拟让模型学会区分镜面高光和柔性纤维。第三类失败是指示器角度误判。指针尖端和背景对比度低时角度分支输出的sin和cos整体偏小还原出的角度偏差超过正负十五度。解决方案是提高指示器类别样本的输入分辨率在小目标检测层上对角度分支单独加深了一层卷积提升指针方向特征的抽象程度。5.3 迭代优化手段迭代优化我走的是半自动标注加难例循环。第一步用当前模型批量推理新采集的产线图把检测框结果存下来第二步用脚本把置信度低、框位置和标准位置偏差大于阈值的图单独筛出来第三步人工复核这些图剔除误标后加入训练集第四步重新训练并评估。整个流程迭代三轮后模型精度提升越来越慢说明数据多样性已经基本到位。角度误差的评估也需要量化。我在评估集里专门标了一份角度真值推理后用预测角度和真值做差统计绝对误差在正负五度和正负十度内的比例。这个指标比单纯看mAP更能反映指示器判定逻辑的实际表现。最终项目要求的正负十度合格率达到了98.6满足产线标准。6. 部署落地从模型到产线6.1 模型导出与加速训练完成后第一步是把PyTorch模型导出为ONNX。推理时直接用PyTorch很难保证稳定性和速度工业现场更习惯用推理引擎。我用的是ONNX导出加TensorRT加速FP16精度。导出时有个坑要注意角度分支输出的sin和cos归一化操作在导出ONNX时如果用了in-place的clamp或者norm某些推理引擎会不支持。我的做法是把归一化放到后处理代码里做模型只输出原始的两个数值这样导出的计算图更简单兼容性也更好。import torch import onnx model MY_YOLOv26() model.load_state_dict(torch.load(best.pt, map_locationcpu)) model.eval() x torch.randn(1, 3, 640, 640) torch.onnx.export( model, x, yolov26.onnx, input_names[images], output_names[boxes, scores, classes, angles], opset_version17, dynamic_axes{images: {0: batch}} )TensorRT的FP16推理相比FP32在毛毡检测上精度几乎无损指示器角度误差平均增加了不到一度完全在可接受范围。如果现场没有GPU只有CPU工控机可以改用OpenVINO导出精度保留同样很好速度上六百毫秒以内也能完成单帧推理。6.2 推理与判定流程部署NMS和后处理我单独写了一个脚本判定逻辑分三步第一步用检测结果找出毛毡框和指示器框第二步毛毡框中心坐标与标准坐标系原点做差偏移量超过阈值判为偏移第三步指示器的角度分支输出还原成角度值落在规定区间判为合格否则判为不合格。核心的一段推理和判定逻辑可以参考import numpy as np def judge(cx, cy, std_cx, std_cy, max_offset8): offset np.hypot(cx - std_cx, cy - std_cy) return offset max_offset, offset def judge_angle(pred_angle, valid_range(45.0, 135.0)): return valid_range[0] pred_angle valid_range[1], pred_angle这里的判定阈值要结合产线允许的公差去定。偏移量阈值我定的是8像素换算到实际尺寸约0.4毫米比机械装配的公差要求要严格一些防止判断边界产品。角度阈值则根据产品图纸上的装配指标来现场工程师会给一个区间。6.3 与产线通讯的细节检测结果最终要传给PLC。常用方式有TCP/IP和串口。我推荐用TCP传输JSON结构简单可靠。要注意的是通讯模块要设计超时重连机制产线环境下的网络偶尔会闪断如果没有重连逻辑视觉系统会在无人值守的情况下罢工。帧率达到什么水平算合格要看节拍。产线节拍如果是三秒一个零件那相机触发拍照、推理、结果发送总耗时小于一秒就行。我这套方案在嵌入式GPU上单帧总耗时约十五毫秒大量余量可以用来做多角度拍照或者多次采样取稳定结果。另外给产线调试留一个可视化界面很重要现场工程师能看到每张图的检测框和角度数值否则模型一旦出错短时间很难定位原因。7. 常见问题排查速查表问题现象可能原因排查方法解决建议浅色毛毡频繁漏检训练集中浅色毛毡样本不足统计训练图片中毛毡灰度分布补充浅色毛毡图增加亮度扰动增强金属反光区域误检为毛毡高光纹理与毛毡相似查看误检框对应的图像特征增加反光负样本增强局部高光模拟指示器小目标漏检严重没有小目标检测层检查特征图分辨率增加P2层输入分辨率提高到640指示器角度判断整体偏移角度标注有系统偏差对比角度真值分布统一标注规则复核关键点位置训练loss下降但mAP不涨过拟合或数据分布问题观察验证集指标变化早停或增加数据多样性部署后推理速度不够模型计算量过大查看GPU利用率使用TensorRT FP16或降输入分辨率毛毡框偏移抖动大框回归对边缘不敏感查看同一批样本多次检测结果提高光照均匀度增加约束损失实际排查过程中最花时间的往往不是模型本身而是数据的标注一致性问题。同一个指示器不同标注员画的旋转中心可能差几个像素这个误差传导到角度真值上就是好几度的偏差。我的应对方案是让一位经验最丰富的工程师统一复核所有关键点标注等标注标准稳定后再开始训练。还有一个容易被忽略的细节毛毡检测的框中心在推理时是模型回归出来的但产线判定偏移量最好用毛毡边缘和装配槽边缘的位置差而不是单纯依赖检测框中心。因为检测框包含毛毡边缘的预测误差经常有出现模型框位置轻微抖动的情况。如果想要更稳定可以在检测框内做一次边缘分割找到毛毡真实边缘坐标再和标准边缘做差。这个方案在当前项目里属于二期优化一期用检测框中心加偏移补偿已经能满足产线需求。最后再分享一个小技巧现场跑测试时把模型的中间层特征图输出出来做成热力图叠加在原图上。如果毛毡位置和指示器位置在热力图上有清晰响应说明模型学到了有效特征如果热力图杂乱无章那多半是训练数据或标注出了问题。这个可视化排查手段在整个项目周期里帮了我很多次比光看数值指标直观得多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑