基于熔池图像对与深度学习网络的焊接熔透状态在线识别方法

📅 发布时间:2026/10/19 4:16:00
基于熔池图像对与深度学习网络的焊接熔透状态在线识别方法
我参与过不少焊接质量自动化的项目接触最多的一个场景就是“熔透状态怎么在线看出来”。老师傅焊薄板时靠电流声音和熔池形态判断是否烧穿但这个手感很难量化年轻焊工学三年也不敢说稳。传统的离线X射线抽检只能事后补救焊坏了重新返修成本直接翻倍。后来我们开始尝试用深度学习直接识别熔池图像这一路走过来最大的体会是模型的分类能力其实早不是瓶颈真正决定成败的反而是数据怎么采集、标签怎么定、模型怎么融合。这篇文章就围绕“熔池图像对”这个方案把熔透状态识别的完整链路梳理一遍包括我踩过的坑和测试中的真实表现代码部分也整理在文里可以直接照着跑。1. 熔透状态为什么难识别在线质量感知的工程困局1.1 熔透状态的工程定义与三类结果的后果对比熔透状态通俗讲就是焊缝是否把母材“焊透了”。焊接过程里热源把两块母材的接缝处加热到熔化状态形成液态金属熔池冷却后结晶成焊缝。熔透状态一般分成三类未熔透、完全熔透、过熔透。未熔透意味着焊缝根部和母材之间还有未融合的缝隙受力时是应力集中点结构强度直接不达标过熔透则是热量输入太大熔池塌陷背面形成焊漏或者烧穿表面成型也往往难看。只有完全熔透才是理想状态既保证根部熔化又保持焊缝背面有均匀的余高。这三类状态对结构件的影响差异很大。我拿做过的一组钢制对接试板举例未熔透的试板做拉伸试验断裂位置几乎都集中在根部未融合区域强度只有母材的百分之六十左右过熔透的试板虽然强度不差但背面焊瘤过多配合面装不上同样得返修。所以熔透识别不是锦上添花的质检而是决定产品能不能用的硬指标。1.2 传统的熔透检测手段到底差在哪工厂里最常见的做法是工艺参数保证——焊前定好电流、电压、焊接速度理论上参数不变熔透状态就稳定。但现实是坡口装配间隙有误差母材表面有油污氧化皮散热条件随工件位置变化这些因素都会让实际热输入偏离设定值。等焊接完了再抽检可以用超声或者射线但一面只能拍一小段漏检率高而且结果滞后焊错了只能切掉重来。还有一类在线方法是监测焊接电流和电弧电压的波动信号。这个方法在短路过渡的CO2气体保护焊里比较有效因为熔滴过渡的电气特征和熔透关系比较密切。但换成脉冲MIG/MAG焊或者氩弧焊电气信号和熔透状态的耦合就没那么强了经常出现电压电流都很稳定、实际已经过熔透的情况。真正可靠的直接信号其实是背面焊缝成型——如果背面有连续均匀的焊漏痕迹说明完全熔透。但很多结构件背面空间狭小操作员根本看不到传感器也不容易布置。于是就有了“图像对”这个思路正面相机拍熔池的形态侧面或者背后如果有条件就拍背面成型用两路图像的信息互补来推断熔透状态。这个方案的核心逻辑很简单正面熔池形态反应热输入和熔池流动趋势背面成型反应熔透的最终结果两者一结合比单看任何一方都可靠得多。2. 比模型更费工夫的熔池图像对数据链路2.1 双视角采集系统的硬件搭建与视角设计图像对方案听起来简单真正搭采集系统的时候才发现需要考虑的点非常多。焊接时电弧光强非常大包含很强的紫外和红外成分普通工业相机直接对着熔池拍画面几乎全白根本看不到熔池边界。我们最终选型的方案是在镜头前加窄带滤光片配合相机的极短曝光时间。窄带滤光片的光谱通常选在可见光偏蓝或者偏绿的波段避开了电弧光谱里能量最强的连续谱同时保留熔池和母材的区域对比度。第一路相机从正面斜上方拍摄熔池区域视角大概在45度左右。这个角度能看到熔池的前端、尾部和两侧热影响区亮度变化信息量最丰富。要注意的是保护气体喷嘴和送丝机构会遮挡部分视野所以相机支架的设计也很关键尽量让镜头中轴线避开这些障碍物。第二路相机拍摄背面焊缝成型。这个位置实际上很难布置因为工件底下有支撑梁空间通常很局促。我们当时的做法是把相机安装在一个特制的夹持座上用磁力底座吸在工件下方的横梁上镜头从侧面斜向对准背面焊接轨迹。说实话这个视角拍出来的画面会随着坡口位置变化焊缝并不总在画面正中央所以后续图像预处理里还得加一个中心对齐的校正逻辑。两路视频是同步录制的帧率统一设置为50帧每秒保证熔池变形和背面成型的时间对应。同步触发用硬件方式实现让两路相机接受同一个外部信号发生器然后各自按内部时钟采集时间戳对齐误差控制在两个帧间隔以内。项目初期我试过直接用软件命令同时启动两台相机结果发现两台机器开机时间本身就有几十毫秒的偏差对帧率50fps的采集来说这个误差已经足以让熔池状态和背面图像错开好几帧标签就乱了。2.2 熔池图像对的样本结构与标注流程采集回来的原始素材是两段时长为几十秒的视频一个焊接试验段可能采集到上千帧画面。熔池图像对就是同一时刻的正面熔池图和背面成型图组成一个样本对。两个图的分辨率不必完全一致因为网络输入的时候统一resize即可但镜头标定好之后两路画面的物理尺寸比例要记录下来后面做数据分析和几何特征提取时用得上。样本标注是所有环节里最耗时、最依赖人工经验的步骤。我们建立了一个标注规范每一帧的标签由该帧对应的背面焊缝形态决定同时参考正面熔池的形态。完全熔透的帧背面会看到一条均匀连续的焊漏轨迹宽度和正面熔池宽度在合理范围未熔透的帧背面几乎看不到明显的焊漏形态或者只有断续的痕跡过熔透的帧背面出现明显的下榻、烧穿口或者大面积的焊瘤。这个标注过程听起来清晰实际操作时有几个争议点很难避免。比如完全熔透和过熔透之间的边界并没有一个客观的定义不同标注员在不同批次里可能有偏差。为了解决这个问题我们让两位有经验的焊接工程师分别独立标注然后再开会讨论有分歧的帧最后只保留意见一致的样本。另外焊接过程中存在过渡状态比如这一秒还是完全熔透下一秒因为装配间隙变大变成过熔透那中间那十几帧的标签就非常模糊这些帧会直接剔除避免给模型传递矛盾信号。数据规模方面我们最终积累了大约五万个有效的图像对三类标签的比例大概为完全熔透占六成未熔透占两成过熔透占两成。这个分布基本符合实际产线的情况——正常焊接参数下完全熔透本来就应该是大多数状态但模型训练时这种天然的不均衡会影响分类器倾向后面讲损失函数的时候我会专门说。3. 双流网络结构设计为什么拆成两路而不是单张图硬分类3.1 单图分类方案的短板一开始我们也走过弯路尝试过直接把正面熔池图像单独输入一个分类网络因为心里想着背面如果拍不清楚模型能靠正面信号判断多少算多少。实验做下来发现一个问题正面熔池图像在不同熔透状态下确实存在规律性差异比如过熔透时熔池尾部会拉长整体亮度分布更靠后但这些差异并不像想象中那么稳定。一旦换了焊接参数电流大了或者速度慢了熔池形态的变化甚至比熔透状态变化带来的差异还要显着模型很容易“过拟合到参数上”。背后的道理不复杂熔池正面图像是热输入、保护气流量、母材散热条件等多因素耦合后的综合表现熔透状态只是其中一个因素。纯粹从正面图像反推熔透状态本质上是要从一幅灰度图像里分离出多因子的耦合效应这个信息学难度相当大。而背面成型图像则是熔透结果的直接物理表现虽然信息“更晚”但因果链路短信号干净。所以双流方案的核心动机就是用正面图像提取热输入相关的“状态特征”用背面图像提取熔透结果的“事实特征”两路特征互补之后再分类。在真实产线上背面相机有时被遮挡或者污染这时候可以在推理阶段把背面分支的输入替换为上一时刻的有效帧或者干脆回退到正面单分支模式系统的可用性更强。3.2 网络结构与融合层设计的实际取舍双流网络的具体设计上我推荐的做法是两个分支各使用一个轻量主干网络分别提取特征。正面分支和背面分支不必共用参数因为这两路图像的空间特征差异很大——正面图里熔池的高亮形态是核心信息背面图里焊漏的轮廓和灰度对比是核心信息共用参数量反而不利于各自特征的学习。主干网络可以选用ResNet18或者MobileNetV2输入分辨率我们设置为224像素。在全连接层之前从两个分支各取出特征向量然后做一个融合。最简单的做法是直接拼接Concatenate然后接一个Dropout层和分类头。实测这个基础方案的效果已经不错分类准确率能到93%左右。但要进一步提升就不只是拼接那么简单了。我们对比过下面几种融合方式分别记录了三分类准确率的差异见下表融合方式结构描述三分类准确率验证集备注特征拼接两分支特征向量直接拼接Dropout后分类93.2%基线方案简单可靠注意力加权两路特征经过SENet风格注意力加权求和后分类94.1%参数量增加约8%收益有限差分融合拼接后另接一层差分特征正面特征减背面特征93.5%差分特征帮助有限门控融合用一个门控网络学习融合权重再加权求和94.0%和注意力方案差距不大但训练更慢可以看到注意力加权的提升幅度并不大但参数量和训练难度都有一定上升。这说明对这个任务而言两分支特征的互补性信息已经比较充分融合层做简单的拼接就足够过度设计融合结构反而容易过拟合。值得再提一下的是主干网络轻量化。产线部署时图像分类的推理延迟要控制在几十毫秒以内同时还要留给其他检测算法一部分算力。ResNet18在GPU上推理一张224分辨率的图像大约要十几毫秒MobileNetV2则更快但精度会下降一到两个百分点。考虑到熔透识别对误报的容忍度很低我们最终选择ResNet18作为训练和验证的主网络部署时再通过模型量化压缩。如果你跑完代码想看效果把backbone替换成MobileNetV2一行参数就能切换。3.3 从单帧到多帧时序特征的引入熔透状态本身是连续演化的当前时刻的状态几乎总是和前一秒、后一秒的状态高度相关。单帧分类的另一个问题是会偶尔出现“抖动”——某一帧因为飞溅遮挡或者弧光闪烁模型给出一个明显错误的分类下一帧又恢复了。我们加了多帧滑动窗口的改进策略。具体来说不再只看当前这一个图像对而是取当前帧前后各几帧的图像对分别过模型得到分类概率序列然后对序列做均值投票或中位数滤波用平滑后的结果作为最终预测。这个策略把单帧噪声摊薄到了时间维度分类稳定性明显提升。后面的推理章节我会再展开滑动窗口的参数设置。4. 训练实战类别不均衡、增强策略与核心代码4.1 损失函数的选择思路前面提到完全熔透的样本占了六成未熔透和过熔透加起来才四成而且这两类恰恰是需要精确识别的缺陷状态。如果直接用普通交叉熵损失模型很容易倾向于把所有样本都判成完全熔透因为这样也能拿到比较高的整体准确率但完全没有实用价值。解决类别不均衡我试过几种方案。最简单的重采样少数类多取几遍确实能提升少数类的召回率但会让模型对少数类过拟合泛化能力变差。加权交叉熵——给少数类分配更高的损失权重——也有类似问题不过相对温和一些是多数项目里不错的起点。我们最终采用的是Focal Loss。这个损失函数的特点是会自动降低那些已经分类正确的样本的梯度贡献让模型把训练重点放在难分类的样本上。它有两个超参数需要调gamma控制难易样本的权重衰减强度alpha控制类别权重。第一时间跑基线时用alpha取各类别样本比例的倒数归一化gamma设为2.0后面做了几组对比实验发现gamma在1.5到2.5之间差异不大真正影响大的是alpha如果让完全熔透类的alpha太低精度会明显下降。4.2 数据增强策略与训练细节数据增强方面熔池图像不同于自然图像只能用单通道灰度图或者换算成伪RGB图输入所以不能直接套用常见的ImageNet增强管线。正面熔池图像的核心特征是高亮熔池区域和暗背景之间的对比所以亮度扰动是必要的——模拟不同焊接电流下的熔池亮度差异。随机裁剪和水平翻转也可以用但要小心翻转之后熔池的前端和尾端位置会互换如果项目里后续要加时序特征翻转增强就得慎重。背面图像的处理策略不同。背面焊缝成型的形态相对固定焊缝轨迹基本是沿着焊接方向的直线或弧线所以水平翻转会破坏“前进方向”的语义垂直翻转更安全一些。此外背面图像经常包含相机支架、夹具边缘等背景干扰我们还用了随机擦除增强模拟镜头上的飞溅遮挡。训练配置上初始学习率设为1e-4使用AdamW优化器配合余弦退火调度batch size是32训练约40个epoch。同时在验证集上监控每个类别的F1分数而不是整体准确率因为整体准确率在类别不均衡时参考意义不大。为了防止早停和过拟合保存验证集F1最优的模型权重。4.3 核心代码双流网络结构、数据加载与训练循环下面给一段简洁的PyTorch实现包含双流网络主体结构。backbone部分用现成的ResNet18去掉最后的分类头替换成可学习的融合层。代码里我注释得比较细方便你根据自己的数据集调整。import torch import torch.nn as nn import torchvision.models as models class DualStreamNet(nn.Module): def __init__(self, num_classes3, backboneresnet18): super().__init__() # 正面熔池分支 self.front_branch models.resnet18(weightsNone) # 背面成型分支 self.back_branch models.resnet18(weightsNone) # 去掉两个分支的全连接分类头 feat_dim self.front_branch.fc.in_features self.front_branch.fc nn.Identity() self.back_branch.fc nn.Identity() # 融合层拼接两路特征后接全连接分类器 self.classifier nn.Sequential( nn.Dropout(0.3), nn.Linear(feat_dim * 2, 256), nn.ReLU(inplaceTrue), nn.Dropout(0.2), nn.Linear(256, num_classes) ) def forward(self, front_img, back_img, return_featFalse): feat_front self.front_branch(front_img) feat_back self.back_branch(back_img) feat_cat torch.cat([feat_front, feat_back], dim1) logits self.classifier(feat_cat) if return_feat: return logits, feat_cat return logits训练循环中最需要注意的一点是两个backbone应该分别独立通过数据增强后的图像对进行前向和反向传播。这里我写了一个简化的训练step片段criterion torch.hub.load(ultralytics/yolov5, custom, pathNone) # 占位实际请使用FocalLoss不过上面那行是占位实际项目里我用的是自定义的FocalLoss完整实现如下class FocalLoss(nn.Module): def __init__(self, alphaNone, gamma2.0, num_classes3): super().__init__() self.gamma gamma self.num_classes num_classes if alpha is not None: self.log_alpha torch.log(torch.tensor(alpha, dtypetorch.float32)) else: self.log_alpha torch.zeros(num_classes) def forward(self, logits, targets): ce_loss nn.functional.cross_entropy(logits, targets, reductionnone) pt torch.exp(-ce_loss) focal_loss (1 - pt) ** self.gamma * ce_loss # 按类别加权 target_onehot nn.functional.one_hot(targets, num_classesself.num_classes).float() class_weights (torch.exp(self.log_alpha) * target_onehot).sum(dim1) focal_loss focal_loss * class_weights return focal_loss.mean()关于alpha的取法项目初期我们从样本比例倒数起步也就是完全熔透类的权重小一些未熔透和过熔透类的权重大一些。后面微调时发现把过熔透类的权重单独再调高一点对“漏报过熔透”这个代价最高的错误类型有明显改善。5. 精度之外混淆矩阵、时序投票与失败案例5.1 验证集上的混淆矩阵与分类边界训练完成后评价不能只看一个平均准确率。我们按三类分别统计了精确率和召回率下面是验证集上的典型结果类别精确率召回率F1未熔透91.5%89.2%90.3%完全熔透96.8%97.5%97.1%过熔透92.3%90.1%91.2%整体看起来不错但混淆矩阵暴露了一个细节未熔透被误判为完全熔透的样本绝大多数发生在焊接刚开始或者收尾阶段。开头阶段工件温度低熔池尚未充分铺开但背面可能已经呈现一定温度痕迹模型容易被误导。收尾阶段则是热量积累后的滞后效应正面熔池已经明显变小背面还有持续的焊漏两路信号的“时间错位”造成了分类困难。这一类问题本质上不是分类器不够强而是单帧图像对不含时间维度的上下文信息。后面加的滑动窗口投票对这类问题有改善但并不能完全消除。要想彻底解决需要引入时序网络结构例如在双流特征之后接一层LSTM或者Transformer这也是后面计划演进的方向。5.2 滑动窗口投票与置信度阈值滑动窗口的处理逻辑很直接保存最近N帧的分类概率向量取平均值作为当前状态的最终预测。N的取值要平衡响应速度和稳定性N太小达不到平滑效果N太大会让报警延迟太久。我们对比了N取5、11、21时的表现最终选了11对应0.22秒的决策延迟实际产线上是可以接受的。除了时间平滑置信度阈值控制同样重要。我们额外设置了一个“不确定区”如果模型对某一类的最大预测概率低于某个阈值比如0.7系统不输出明确的分类而是标记为“待人工复核”。这个设计的理由是过熔透漏报的代价远大于误报与其让模型硬猜不如把低置信度的样本交给人工判断。产线实际运行下来大约有8%的帧会落入不确定区但保留下来的明确判断结果可靠度非常高。5.3 实测中的失败案例与针对性改进说实话这个方案并不是万能的我们遇到过几个比较典型的失败场景。最典型的是背面相机镜片污染焊渣飞溅附着在镜头上画面逐渐变模糊模型把越来越多的帧判为“未熔透”——因为在它看来背面的焊漏信号消失了。这种问题不能在模型层面彻底解决只能靠软件监测画面清晰度指标比如拉普拉斯方差低于阈值就提示清灰系统强制进入人工复核模式。另一个失败场景是工件装配间隙异常偏大。原本正常的坡口间隙是1到2毫米有一批工件因为下料误差间隙达到了3毫米热输入明显不足导致整条焊缝都处于未熔透边缘。模型确实识别出了异常但它给出的判断在未熔透和完全熔透之间来回跳动因为有些帧背面恰好出现了微弱的焊漏痕迹。这种“边缘状态”本来就是物理上难以清晰定义的所以后来我们主动在训练集里增加了这类边界样本并配合人工标注时的讨论结果让模型学会对这类模糊情况输出低置信度而不是强分。6. 从实验室到产线部署的坑与后续演进6.1 模型导出与推理性能训练阶段用的PyTorch模型部署时一般要导出为ONNX格式再做TensorRT加速或者直接加载到生产环境的推理框架里。导出时最容易忽略的点是输入张量尺寸固定问题因为PyTorch模型在导出ONNX时动态轴如果不声明后续部署框架大概率会绑死输入分辨率导致推理报错。我们当时踩过一次导出的动态batch轴没配好生产环境和测试环境batch大小不一样部署框架直接抛异常。所以导出的时候一定要显式指定dynamic_axes参数给batch和长宽维度都留出动态空间。量化方面FP16精度下分类结果和FP32几乎无异。更激进的INT8量化精度有约一个百分点的下降主要掉在未熔透类别上。考虑到未熔透漏报的代价大我们最终保留FP16部署单路推理延迟约为8到12毫秒完全满足产线要求。6.2 模型换工件后的微调策略换一种板厚、换一批焊接材料熔池图像的光学特征都会变化模型是否还能用这是产线最关心的问题。我们的测试表明直接用旧模型识别新工件的样本准确率掉到75%左右几乎不可用。但好消息是在新工件数据集上只需要做少量微调——冻结两个backbone的前几层只微调后面几层和分类头数据量有几百个图像对就够微调后准确率能回升到90%以上。这个结果说明模型的底层特征提取能力是可迁移的真正变化的是高层的领域特征分布。所以建议新工件上线时先花半天采几十秒焊接视频人工标注两三百帧做一次快速微调这个成本远远低于重新训练整个模型。6.3 这个方案的演进方向现在做的还是静态帧分类加上时序滑动窗口本质上是对时间信息做了一次很粗糙的平滑。接下来的方向有几个一是把两路图像输入给时序模型用Temporal Shift Module或者Transformer的序列建模来捕捉熔池的演化过程二是不满足于三分类而是直接回归预测背面熔宽——如果能连续估计熔宽就能更精细地判断熔透程度因为熔宽和熔透率是强相关的三是加入焊缝跟踪的几何信息把坡口间隙、焊缝离边距离这些外部状态拼进特征向量模型的可解释性和鲁棒性都会更好。我的个人体会是熔透状态识别这个课题表面上是深度学习图像分类问题实际上更像一个系统工程问题数据采集的同步性、标注标准的一致性、模型感知与物理规律的匹配程度每一项都比调网络结构更影响最终效果。项目初期我们花在调参上的时间少花在采集设备和标注对齐上的时间多回头看这个时间分配是完全正确的。如果你正在做类似的焊接过程感知项目我建议把注意力先放在数据链路上模型选型只要不过于激进基本都能收到一个不错的下限。最后分享一个小技巧所有熔池图像在采集后先做一次简单的背景差分或者对比度拉伸把熔池区域从背景里粗略分离出来再送入网络训练。这一步看似朴素但能显著减少模型对光照和背景变化的敏感度也能让可视化分析时更方便判断模型关注区域是否合理。我在多个项目里试过这个预处理带来的收益经常比换一个更强的主干网络还要明显。