免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

踩坑三周:食品包装产线C#上位机+AI视觉落地,包装缺陷与生产日期识别完整工程方案

踩坑三周:食品包装产线C#上位机+AI视觉落地,包装缺陷与生产日期识别完整工程方案 今年上半年给一家休闲食品厂做后端包装线的视觉检测改造整条线是枕式包装机出成品要求在线检测包装破损、封口密封不良、胀气三类外观缺陷同时识别生产日期喷码缺码、错码、模糊都算不合格最终对接现有的C# WPF上位机系统驱动剔除器把不合格品打下来还要做到每包数据可追溯。一开始评估的时候觉得不难不就是YOLO检测缺陷再加个OCR认日期C#调用ONNX跑推理接个PLC发剔除信号嘛。实验室搭原型跑了两天效果看着不错就拉去现场联调了。结果这一调就是三周各种现场问题接踵而至食品包装膜反光严重拍出来的图一片亮斑封口的小破损根本看不见喷码位置前后飘固定ROI经常切不到文字识别率忽高忽低产线开到300包/分钟就运动模糊照片拖成虚影剔除信号时早时晚要么打不准要么漏打品控那边意见很大车间湿度大早高峰镜头起雾半小时就得擦一次从头到尾从光源、相机、算法、上位机逻辑到PLC同步全部整改了一遍才最终稳定跑起来各项指标都达到了品控要求。今天把这套完整的落地方案整理出来从架构设计、模型部署、上位机开发到现场踩坑全是工程化干货做食品包装、快消品视觉检测的朋友可以参考至少能省大半现场调试时间。一、项目需求与整体设计思路工业项目从来都是先定指标再做方案这次的需求边界非常明确检测对象枕式塑料包装食品规格覆盖5-15cm长度检测项外观缺陷包装破损、封口褶皱/密封不良、包装胀气日期检测生产日期喷码存在性、清晰度、格式正确性性能指标最高300包/分钟单帧全流程处理时间≤200ms准确率要求缺陷检出率≥99.5%日期识别准确率≥99%对接要求兼容现有C# WPF上位机对接西门子S7-200 SMART PLC输出剔除信号环境要求常温高湿车间满足食品级卫生规范设备支持水洗整体采用分层解耦设计把采集、推理、业务、展示完全拆开核心推理层全部基于ONNX Runtime实现纯C#运行不依赖Python环境部署和维护都足够简单。核心设计思路有两个第一缺陷检测和日期识别串行联动用YOLO同时做缺陷检测和日期区域定位定位到日期区域后再裁剪送OCR比直接全图OCR速度快、准确率高还能从根本上解决喷码位置漂移的问题。第二硬触发编码器跟踪拍照和剔除都用硬件信号同步比软件定时稳定得多能自适应产线速度波动。二、AI模型选型与C#端ONNX部署算法选型的核心原则是够用、好部署、成本低。工业场景不是刷榜稳定和易维护比精度高零点几个百分点重要得多。2.1 模型选型缺陷检测选用YOLOv12n小模型速度快工业小目标检测效果足够转ONNX后普通工控机CPU就能跑不用额外加显卡大幅降低现场硬件成本。日期识别选用PaddleOCR轻量化模型专门优化过工业喷码场景支持竖排、模糊、倾斜文字同样转ONNX部署C#直接调用。为什么都转ONNX因为C#端调用无缝不用装Python运行时和一大堆依赖。食品厂的工控机管控很严装软件要走流程纯.NET部署最省心。2.2 模型训练与导出的工程化优化食品包装场景有自己的特殊性通用模型直接拿来用大概率翻车训练和导出阶段就要做针对性优化数据增强向现场对齐训练时加入大量反光、局部过曝、水汽模糊、位置偏移的样本不然实验室效果再好到现场也直接打对折。单模型多任务YOLO同时训练4类目标——破损、密封不良、胀气、日期区域一个模型同时输出缺陷和日期位置不用跑两个独立模型推理时间几乎减半。ONNX导出规范沿用工业部署标准配置opset17、静态尺寸640×640、关闭动态输入、FP16半精度保证C#端的兼容性和推理速度。OCR模型微调用现场采集的几百张真实喷码样本微调OCR模型尤其是喷码不全、墨迹扩散、打印歪斜的样本通用模型在工业喷码上很容易翻车。2.3 C#端推理封装核心封装VisionDetector类内部调度两个模型对外只暴露统一的检测接口业务层不用关心底层细节public class VisionDetector : IDisposable { private readonly YoloDetector _yoloDetector; private readonly DateOcrRecognizer _ocrRecognizer; private readonly Mat _sharedMat; // 复用Mat对象减少GC public DetectResult Detect(Mat rawImage) { var result new DetectResult(); // 第一步YOLO同时检测缺陷和日期区域 var yoloResults _yoloDetector.Detect(rawImage); // 拆分缺陷结果和日期区域 result.Defects yoloResults.Where(r r.ClassId 3).ToList(); var dateRegion yoloResults.FirstOrDefault(r r.ClassId 3); // 第二步定位到日期区域后裁剪送OCR识别 if (dateRegion ! null) { using var dateCrop rawImage[new Rect( (int)dateRegion.X, (int)dateRegion.Y, (int)dateRegion.Width, (int)dateRegion.Height)]; result.DateText _ocrRecognizer.Recognize(dateCrop); result.DateValid ValidateDateFormat(result.DateText); } else { result.DateValid false; } result.IsQualified !result.Defects.Any() result.DateValid; return result; } // 日期格式规则校验过滤明显的识别错误 private bool ValidateDateFormat(string text) { // 匹配YYYY-MM-DD格式结合生产日历进一步校验 return Regex.IsMatch(text, ^20\d{2}-\d{2}-\d{2}$); } public void Dispose() { _yoloDetector?.Dispose(); _ocrRecognizer?.Dispose(); _sharedMat?.Dispose(); } }性能优化上推理用的输入数组、中间Mat对象全部复用池化避免循环里频繁创建销毁正常单帧推理控制在100ms以内给后续业务逻辑留足时间。三、图像采集现场效果的核心90%的问题出在这里很多人做视觉项目只盯着算法优化其实现场80%-90%的检测效果问题根源都在采集和光源。食品包装场景尤其突出塑料膜反光、水汽、运动模糊每一个都能让算法直接失效。3.1 相机必须全局快门拒绝运动模糊一开始图便宜用了卷帘快门的相机产线开到200包/分钟以上包装就出现横向拖影封口的细纹全糊了小破损根本检测不出来。换成全局快门工业相机配合硬触发300包/分钟也没有运动模糊细节清晰。3.2 光源解决反光是第一要务塑料包装膜的反光是头号难题正面打光直接一片亮斑封口缺陷和喷码都被淹没。最终采用两侧条形漫射光源镜头偏振镜的方案光源从两侧45°斜打相机镜头加装偏振片最大程度消除膜面的镜面反光封口纹理和喷码笔画都清晰很多。现场调试的时候注意每换一种包装膜材质、颜色都要微调光源角度和亮度。反光控制不好误检率会非常高。3.3 触发光电硬触发不要软触发绝对不要用软件判断画面里有没有产品一定要用光电传感器接相机的硬触发输入产品到位置自动触发拍照时机准、抖动小还能减少相机的无效采集。传感器安装位置要精准校准保证每个产品都在相对一致的位置成像减少后续算法的处理难度。3.4 环境适配防雾防尘食品车间湿度大尤其是早班开机的时候镜头温差大很容易起雾前半小时基本没法用人工擦镜头又不符合卫生要求。我们选用了带恒温加热功能的工业镜头镜头前加一层防雾保护片配合定期自动气吹清洁基本不用人工维护全天成像稳定。四、C#上位机核心同步、剔除、追溯算法跑通只是基础上位机的业务逻辑才是能不能用的关键尤其是剔除同步差几十毫秒就打不准。4.1 产线跟踪与剔除同步这是现场最容易出问题的地方。很多新手就是写个固定延时拍照后等多少毫秒发剔除信号结果产线一加速减速就打不准要么打空要么打在相邻产品上。正确的做法是编码器位置跟踪PLC实时读取编码器脉冲拍照触发时把当前编码器值传给上位机上位机计算从拍照位置到剔除工位的固定脉冲数得到目标位置把“是否剔除”和“目标位置”一起下发给PLCPLC做运动控制编码器计数到目标位置自动输出剔除信号时序由硬件保证产线速度波动的时候脉冲位置是固定的自动同步完全不用管速度变化。最终剔除精度控制在±5mm以内全速运行也不会打偏。public class PlcSyncService { private readonly S7Client _plcClient; private const long DistancePulses 1250; // 拍照位到剔除位的编码器脉冲数 public void SendRejectCommand(bool isDefective, long triggerEncoderPos) { long targetPos triggerEncoderPos DistancePulses; // 下发目标位置和剔除指令 _plcClient.Write(DB1.DBD0, targetPos); _plcClient.Write(DB1.DBX4.0, isDefective); } }4.2 多线程调度与流量控制单线程处理的话采集、推理、IO很容易互相卡住。我们用生产者消费者模式做了解耦采集线程只负责接收触发、传输图像放进处理队列推理线程固定1-2个工作线程从队列取图做AI检测业务线程处理结果、发PLC、存数据、更界面队列设置最大长度满了就丢弃最旧的帧。工业场景实时性第一堆积的旧帧没有任何意义丢了比堆着强。正常工况下单帧从拍照到出结果平均120ms完全满足300包/分钟的速度要求。4.3 检测数据追溯食品行业对质量追溯要求很高每一包的检测结果都要完整记录检测时间、生产批次、班组、产线号缺陷类型、日期识别结果、是否合格原始图片缩略图本地存储数据库存路径支持按时间、批次、缺陷类型多维度查询出质量问题能快速定位到具体班次和设备。五、现场踩坑的7个工程化细节这些都是教科书和教程不会讲的东西每一个都是现场实打实踩出来的坑。坑1反光导致误检与漏检现象包装膜反光形成亮斑亮斑处的破损看不见同时亮斑本身容易被误判为缺陷。解决硬件算法双管齐下。硬件上用偏振光源消除大部分反光算法上推理前做局部灰度均衡抑制过曝同时训练时加入大量反光样本让模型学会区分反光和真实缺陷。坑2喷码位置漂移固定ROI切不到现象包装机走膜有偏差喷码位置前后左右飘固定ROI经常切不到文字识别率时好时坏。解决不用固定ROI用YOLO同时检测日期区域自动定位再裁剪送OCR。不管位置飘到哪都能精准找到日期识别准确率直接从92%升到99.6%。坑3早高峰镜头起雾检测失效现象车间温差大早上开机镜头起雾前半小时基本没法用人工擦镜头不符合食品卫生规范。解决选用带恒温加热的工业镜头开机自动预热到环境温度镜头前加装防雾保护片配合定期自动压缩空气清洁全程不用人工干预。坑4连续运行内存上涨GC卡顿现象跑几个小时内存慢慢涨GC回收的时候还会卡顿导致偶发丢帧。解决建立Mat对象池和输入数组池推理循环里尽量不new新对象所有可复用资源全部池化。改造后内存稳定在固定值没有GC卡顿运行再久也不会涨。坑5喷码模糊OCR识别不准现象喷头老化、油墨不足的时候喷码会有扩散、缺笔画通用OCR很容易认错。解决采集现场几百张模糊喷码样本微调OCR模型同时加上日期格式规则校验不符合格式的直接判定不合格双重保障准确率。坑6误剔率太高生产不接受现象一开始只要模型判定不合格就剔除偶尔会有误判食品厂觉得浪费大不接受。解决做分级置信度策略。高置信度缺陷直接剔除中置信度的标记出来流到人工复检工位低置信度的判定合格。平衡检出率和误剔率最终误剔率控制在0.1%以内。坑7换产品型号参数调整麻烦现象换不同规格的产品要改ROI、光源亮度、阈值每次都要技术人员去现场调。解决上位机做产品配方管理每个型号对应一套参数换型的时候一键切换班组长就能操作不用工程师到场。六、落地效果与总结这套系统上线半年实际运行数据如下运行速度稳定支持320包/分钟单帧全流程处理平均120ms缺陷检出率99.8%封口大于0.5mm的破损都能稳定检出日期识别准确率99.6%兼容点阵喷码、油墨喷码等常见喷码方式误剔率≤0.1%符合生产损耗要求稳定性除了换型调试视觉系统连续运行零故障做食品行业的AI视觉落地算法其实只是很小的一部分光源、触发、同步、环境适应性这些工程化细节才是决定项目能不能成的关键。很多人拿实验室的理想效果去套现场最后都翻车就是忽略了这些因素。这套C#上位机ONNX推理的方案不用Python环境部署简单稳定性高不仅适用于食品包装快消品、医药、日化的包装检测都可以套用。工业视觉从来都是三分算法七分工程。把现场的问题考虑全了项目才能真正落地跑起来。
返回列表