做工业上位机这些年,接触最多的产线痛点就是外观质检。
汽车零部件、3C外壳、五金冲压件,很多产品外观缺陷靠人工目检:工人盯着流水线看,一天看几千件,眼睛花了漏检率就飙升;不良品流到下游,整批返工,一次损失就是几万块。招新人上手慢,老员工视力下降快,用工成本年年涨,质量却稳不下来。
前两年很多工厂尝试上AI视觉,但大多卡在落地环节:算法团队用Python训好模型,封装成服务,上位机发HTTP请求调用。现场一跑问题全出来了:工控机装Python环境踩坑无数、网络波动检测就断、出了问题两边团队甩锅、现场维护人员根本看不懂Python代码,改个阈值都要找算法团队。
我们团队在某汽车零部件产线落地的方案,完全绕开了这些问题:原生C#上位机直接集成YOLOv12,单机离线运行,不用额外部署算法服务,不用装Python环境。上线半年,外观缺陷导致的下游返工率从8.7%降到0.7%,下降幅度92%,产线节拍稳定在60件/分钟,完全不用人工盯守。
这篇文章就把完整方案、核心实现、优化技巧和踩坑经验全部分享出来,传统工控团队照着做,也能自己落地深度学习视觉检测。
一、为什么选C# + YOLOv12,而不是Python方案
工业场景和实验室不一样,不是精度高就完事,稳定、好部署、易维护才是第一位的。对比下来,C#原生集成方案的落地成本远低于跨语言方案。
1.1 技术栈完全统一,不用跨团队扯皮
传统上位机团队本来就熟C#,懂PLC通信、懂产线逻辑、懂现场维护。之前上AI要单独拉算法团队,联调、排障、改需求两边配合,效率极低。
现在方案里,算法只需要负责训好模型导出ONNX,剩下的集成、逻辑、部署、维护全由上位机团队搞定,不用跨语言,不用写接口,沟通成本砍掉80%。
1.2 部署零依赖,拷到工控机直接跑
Python方案最头疼的就是环境:不同版本Python依赖冲突、CUDA版本不匹配、工控机是Windows Server老系统装不上依赖、离线环境没法pip安装。
C#方案只需要两个NuGet包:OpenCvSharp4+Microsoft.ML.OnnxRuntime,编译完整个文件夹拷过去就能运行,不用装任何额外运行时,Win7、Win10、工控机嵌入式系统全兼容。
1.3 性能完全满足工业节拍
很多人担心C#推理慢,实际上YOLOv12n版本,640×640分辨率,普通i5工控机CPU推理单图2535ms,完全满足大部分产线60120件/分钟的节拍。
如果带入门级GPU,推理速度能压到10ms以内,高速线也能扛。对比HTTP调用方案,少了网络传输和序列化开销,延迟更稳定,不会忽快忽慢。
1.4 工业级稳定性可控
上位机程序要求连续跑几个月不重启,异常必须能捕获、能自愈。
C#托管代码异常机制完善,推理失败、相机掉线、PLC断连都能优雅降级,自动重试,不会直接崩程序。还能方便地加看门狗、日志、权限管控,完全符合工业软件的要求。
二、全流程落地:从数据采集到产线闭环
整个落地过程分四步,算法和工控各司其职,边界非常清晰。
2.1 第一步:现场数据采集与数据集构建
算法效果的上限由数据决定,工业数据和公开数据集不一样,难点在缺陷样本少、场景单一、光照干扰大。
- 采集阶段:对接产线连续拍3~7天,覆盖不同批次、不同光照、不同班次的产品,正常样本和缺陷样本都要拍,不要只拍缺陷图。
- 标注阶段:用LabelImg标注,严格统一标注规范,比如划痕要标全、毛刺边缘要对齐,标注质量差的话,模型再强也没用。
- 增强阶段:工业样本少很正常,用翻转、旋转、亮度扰动、加噪声、小缺陷复制等手段扩充数据集,正负样本比例控制在1:3左右,不要太失衡。
我们当时的项目,缺陷样本只有三百多张,加上数据增强,最终训练集两千多张,训出来的模型完全满足产线要求。
2.2 第二步:模型训练与ONNX导出
训练放在Python端做,用YOLOv12官方代码,基于预训练模型微调,不用从零训。
几个针对工业场景的训练技巧:
- 优先用nano/small版本,工业场景类别少(一般就几类缺陷),小模型足够用,速度快很多。
- 小缺陷多就把输入尺寸调到960或者1280,不要硬怼640。
- 损失函数给小缺陷类别加权重,重点优化漏检。
- 训练完导出ONNX格式,指定opset=12,开启simplify简化计算图,去掉训练相关的冗余算子。
关键原则:训练怎么预处理,推理就怎么预处理。比如训练时用的是letterbox缩放、均值归一化,C#端必须完全对齐,不然精度会掉一大截,这是新手最容易踩的坑。
2.3 第三步:C#端核心推理实现
整个推理链路分三步:图像预处理 → ONNX推理 → 后处理解析结果。
核心依赖安装
NuGet搜索安装:
OpenCvSharp4:负责图像读取、预处理、画框Microsoft.ML.OnnxRuntime:ONNX模型推理引擎,CPU版直接装,有GPU装对应GPU包
模型加载与推理核心代码
usingMicrosoft.ML.OnnxRuntime;usingMicrosoft.ML.OnnxRuntime.Tensors;usingOpenCvSharp;publicclassYoloDetector{privatereadonlyInferenceSession_session;privatereadonlyint_inputSize=640;privatereadonlystring[]_classNames={"划痕","毛刺","压伤","污渍"};publicYoloDetector(stringmodelPath){// 加载模型,CPU推理开启优化varoptions=newSessionOptions{GraphOptimizationLevel=GraphOptimizationLevel.ORT_ENABLE_ALL,ExecutionMode=ExecutionMode.ORT_SEQUENTIAL};_session=newInferenceSession(modelPath,options);}publicDetectionResult[]Detect(Matimage){// 1. 图像预处理:letterbox缩放 + 归一化 + 转张量Matresized=Preprocess(image,outfloatratio,outintpadX,outintpadY);// 转NCHW格式张量float[]inputData=ConvertToTensor(resized);varinputTensor=newDenseTensor<float>(inputData,new[]{1,3,_inputSize,_inputSize});// 2. 执行推理varinputs=newList<NamedOnnxValue>{NamedOnnxValue.CreateFromTensor("images",inputTensor)};usingvaroutputs=_session.Run(inputs);varoutput=outputs.First().AsTensor<float>();// 3. 后处理:解析输出 + NMS非极大值抑制varboxes=ParseOutput(output,ratio,padX,padY);returnNms(boxes,0.45f,0.25f);}}两个最容易出错的细节
- 坐标还原:模型输出的是缩放后图片的坐标,必须根据padding和缩放比例,还原回原图的真实坐标,不然框会偏移。
- 通道顺序:OpenCv读出来是BGR格式,如果训练时用的是RGB,预处理要转通道,顺序反了颜色就乱了,精度直接崩。
2.4 第四步:产线逻辑闭环
检测不是目的,拦截不良品、减少返工才是。整个业务流程要和产线深度绑定:
- 产品流到工位,光电传感器触发信号,PLC发给上位机。
- 上位机控制相机拍照,同步调用YOLO检测。
- 判定结果:有缺陷就发NG信号给PLC,触发剔除机构把产品吹到不良品盒;正常就放行。
- 所有检测结果、缺陷图片、时间戳都存本地数据库,定时同步到MES系统,方便追溯。
整个过程全自动化,不用工人操作,只需要定期清理不良品、复核疑似缺陷就行。
三、工业级优化:既要快,也要稳
Demo跑通很简单,放到产线连续跑不出问题,才叫落地。我们做了几层优化,保证程序连续跑三个月不重启。
3.1 多线程解耦,卡界面、漏拍全解决
绝对不要在UI线程里做推理和采集!很多新手图省事,按钮点击直接拍照+推理,界面直接卡死,产线快了还漏拍。
我们用四级线程解耦:
- 采集线程:相机触发回调,只负责取图,放进有界队列,立刻返回,不阻塞相机。
- 推理线程:后台循环从队列取图,调用检测,结果放进结果队列。
- 控制线程:处理结果,和PLC通信,发剔除信号,记录数据。
- UI线程:定时200ms刷新一次画面和统计数据,不参与业务逻辑。
用System.Threading.Channels做有界队列,容量设50,满了就丢最老的图,保证内存不会爆。哪怕推理卡一下,也不会漏拍后续产品。
3.2 推理性能压榨,低配工控机也能跑
现场很多工控机都是低功耗CPU,性能一般,必须做优化才能满足节拍。
- INT8量化:用ONNX Runtime的量化工具把模型从FP32转成INT8,体积减75%,速度提2~3倍,工业场景精度损失不到1%,完全可接受。
- ROI裁剪:产品只在画面中间区域,把周围背景裁掉,输入尺寸从640×640缩到384×640,推理速度直接翻倍。
- 数组复用:每次推理不要new新的数组,用ArrayPool租用,用完归还,大幅减少GC卡顿。
- 硬件加速:有GPU就用CUDA提供程序,没GPU用DirectML加速,比纯CPU快一倍左右。
优化完,赛扬J4125这种入门级工控机CPU,单图推理也能控制在80ms以内,满足30件/分钟的节拍完全没问题。
3.3 容错降级,出问题也不影响产线
工业现场什么情况都可能发生,程序必须有自愈能力。
- 相机掉线:自动重连,重连失败触发声光报警,产线切换到人工检测模式,不会停线。
- 推理异常:捕获所有异常,失败的图片判为疑似,流转到人工复核工位,不会误判也不会卡线。
- 看门狗机制:独立线程监控核心模块,超过5秒没心跳就自动重启对应模块,极端情况重启整个程序,同时记录崩溃日志。
- 模型热更新:换产品、换模型直接替换ONNX文件,不用重启程序,版本不对一键回滚,现场维护人员就能操作。
四、落地效果:数据说话
这条产线上线半年,实际运行数据非常可观:
- 返工率:之前人工目检漏检导致的下游返工率8.7%,上线后降到0.7%,下降幅度92%,每月减少返工损失约12万元。
- 检测效率:单工位检测速度60件/分钟,是人工的2.5倍,不用再安排三班倒目检。
- 质量指标:漏检率0.3%,远低于人工的5.2%;误检率1.2%,控制在产线可接受范围内,疑似缺陷人工复核即可。
- 成本回收:整套方案硬件+软件开发成本不到20万,减去节省的3名目检工人工成本,5个月收回投入。
- 数据价值:所有缺陷数据可追溯,能统计哪类缺陷最多、哪个班次缺陷率高,反推冲压、注塑工艺优化,从根源减少缺陷产生。
五、踩过的6个坑,每个都是花钱买的教训
工业视觉落地,一半问题在算法,一半问题在现场。这些坑我们都踩过,提前避开能省很多事。
1. 光照波动是精度头号杀手
白天晚上光线不一样、光源用久了亮度衰减、窗户反光,都会导致模型误检漏检。
解决办法:用恒流光源,加遮光罩隔绝环境光;图像预处理做灰度归一化、直方图均衡;训练数据加入不同光照的样本。
2. 小缺陷不要硬怼小模型
0.1mm的细微划痕,640分辨率下只有两三个像素,再强的模型也检测不到。
解决办法:要么提高输入分辨率到1280,要么用相机放大倍率,只拍局部区域;不要为了速度硬上小模型,最后效果不达标白忙活。
3. 误检太高,产线工人会直接不用
很多方案漏检很低,但误检很高,100件里挑出5件不良,结果3件是好的。时间久了工人就不信机器了,直接跳过复核。
解决办法:设置分级阈值,高置信度直接判NG剔除,中置信度转人工复核,低置信度放行;结合传统视觉算法做二次校验,过滤掉明显的伪缺陷。宁可漏检多一点,也不要一开始误检太高把用户信心搞没了。
4. 不要追求全类别检测一步到位
刚上线就想检测所有缺陷类型,很容易哪类都做不好。
解决办法:先挑1~2类最常见、返工成本最高的缺陷做,跑稳定了再逐步加类别。小步快跑,快速迭代,产线接受度也高。
5. 现场维护一定要简单
不要指望现场电工、操作工懂深度学习。程序界面要简单,状态要明确,出问题有提示。模型更新、参数调整要做可视化界面,点几下鼠标就能完成,不要改代码、改配置文件。
6. 数据回流持续优化
模型不是上线就完事了。产线换批次、换材料、换工艺,模型效果都会下降。
解决办法:建立数据回流机制,把误检漏检的图片定期加入数据集,每月重新训一版模型,持续迭代,效果会越来越好。
写在最后
工业AI落地,从来不是比拼谁的算法更前沿,而是比拼谁的方案更稳定、更易用、维护成本更低。
C#上位机+YOLOv12这套方案,最大的价值就是降低了深度学习的落地门槛:传统工控团队不用学Python,不用招算法工程师,依托现有的技术栈,就能把AI视觉能力落地到产线上,成本低、周期短、好维护。
对于大量的中小制造企业来说,这种轻量级、可落地的方案,比动辄几十万的大型视觉系统实用得多。制造业升级不是要搞多么高大上的概念,能实实在在降低返工率、减少人工、稳定质量,就是好方案。