视觉算法与成像

条码二维码识别:低对比度、遮挡与变形

读码失败的原因九成在图像和码本身,不在解码算法。这篇按四类典型成因分开讲:对比度不够、局部被挡、载体变形、运动模糊——处理手段完全不同,混着调只会越调越乱。

工业读码是什么问题,用在哪些工况

消费场景的码印在纸上,高对比度、正对、静止。工业场合常见的是 激光打标在金属或塑胶表面(无颜色差,靠微观形貌成像)、 点阵喷码、直接部件标识 DPM, 以及起翘、褶皱、被油污覆盖的标签。用途主要是追溯与防错, 读不出来就意味着流程中断。 敏洽 机器视觉检测软件 内置条码与二维码识别,支持一维码与 DataMatrix、QR; 有刻印字符时配合 OCR(PaddleOCR 引擎)。

实际会遇到的几个坑

1. 低对比度:先改打光,不是先换解码器

激光打在不锈钢或铝件上的码,明暗来自表面微观形貌,不是颜色差, 环形光正打会一片反光。有效手段是利用形貌差异: 低角度掠射让粗糙区散射、光滑区不反射,或用暗场。 深色阳极氧化件有时要反向思路——同轴光让平滑基面全亮、刻痕区变暗。

2. 分辨率不够,模块只占一两个像素

每个最小模块要有足够像素数,经验上不少于三到四个,低质量码更多。 常见错误是为兼顾大视野把码拍得很小,解码本质上不可能。 应按最小模块尺寸反推分辨率与视野再选相机镜头; 一个视野兼顾不了就分工位或加一路读码相机。

3. 遮挡:纠错能力不能当设计余量

DataMatrix 与 QR 都有纠错,但定位结构不受纠错保护—— DataMatrix 的 L 形定位边与交替边界、QR 的定位图形与定时图形, 是解码器找码并建立网格的前提,被油污或划伤盖住整个码就找不到。 某个位置总被夹具压到,就改打码位置或读码角度。

4. 变形:曲面与倾斜的处理不同

倾斜的透视变形好办:解码器的透视校正通常能处理, 不行就调相机角度或用图像校正算子对齐。 曲面的非线性变形麻烦:圆柱面上模块间距沿弧长被压缩, 压缩率随位置变化,规则栅格不存在了。手段有取曲率小的中间一段、 用远心或长焦减小透视、多角度取能读通的一张、或做柱面展开校正。

5. 运动模糊与触发时机

曝光期内工件位移超过一个模块尺寸,模块边界就被抹平。 对策是缩短曝光并用频闪光源补亮度,同时用触发保证每次拍照落在同一相位。 敏洽软件支持硬件 IO、编码器、通讯软触发、连续采集四种, 运动读码优先编码器位置触发,并允许同一件多次重拍。

6. 读不出来的处理流程没定

读不出来之后是停线报警、打「无码」标记继续走、还是自动剔除? 这影响追溯体系的完整性,必须在方案阶段定清楚并写进接口文档。 同时要设计人工补录通道,补录数据与自动读到的要区分开。 失败图片必须留存。

方案与硬件条件

问题类型主要手段注意事项
低对比度(金属码)低角度掠射或暗场;必要时同轴光反向利用先看放大图能否分清模块
低对比度(膜下 / 油污)交叉偏振压反光;特定波长照明偏振有光损,需补光
模块像素不足按最小模块反推分辨率与视野;必要时单设读码相机每模块不少于 3~4 像素
部分遮挡保证定位结构清洁完整;调整视角避开遮挡物纠错留给意外
倾斜变形图像校正对齐 + 解码器透视校正相对容易
曲面变形取小段视野、远心 / 长焦、多角度拍摄、柱面展开曲率过大时改打码位置
运动模糊短曝光 + 频闪;编码器位置触发;允许重拍曝光内位移不超一个模块
字符与码并存条码二维码识别 + OCR(PaddleOCR)双路校验不一致时报警
项目要求与说明
码制支持一维码与 DataMatrix、QR;支持低对比度与部分遮挡
相机USB/UVC、大华、海康、度申已适配;Mock 虚拟相机可用失败图片离线复现
触发硬件 IO、编码器、通讯软触发、连续采集;运动读码优先编码器
工位并发单机 4 工位并发,可同时承担读码与其他检测
结果输出C++ 侧输出解码内容与原始数据,是否与工单匹配由 C# 侧判定
失败留存失败图片必须留存,用于分析是打码质量还是成像问题
运行环境Qt 6.9.2 + C++17 + OpenCV 4.x + ONNX Runtime;Windows 10/11 x64 与 Ubuntu 22.04 x64
客户准备真实带码样品(含质量差的)、打码工艺参数、失败处理流程定义

要来的样品必须包含质量差的那批。 只用打得最好的样品定方案,上线后遇到批次波动就会大面积失败。

相关交付情况

交付顺序:先拿真实样品试拍,按几种打光各拍一组看能否稳定成像; 再确认分辨率与视野满足最小模块的像素要求;然后才是软件实现与失败流程。 某类样品在任何打光下都读不出,结论应反馈到打码工艺环节。

交付包括成像方案、硬件选型建议清单、读码软件与配方管理、失败图片与结果留存、 接口文档(触发方式、IO 定义、通讯点表、解码结果格式、失败处理约定)。 算法按模块授权;已有上位机的客户可只要跨语言 SDK (mqvision.dll / libmqvision.so, 支持 C、C++、C#、Java JNI、Python,另有 Qt-free 版本)。

金属件成像问题见 高反光工件怎么打光; 更多算法说明见 内置算法库。

常见问题

手机与屏幕上的码是理想条件:高对比度、正对、静止、光照均匀。产线上的码通常是激光打在金属上、点阵喷在曲面上、或者印在半透明膜下,对比度可能只有十几个灰阶;还有运动模糊、镜面反光、油污遮挡。解码器需要先能从图像里稳定分辨出模块的明暗,这一步过不去,什么解码库都读不出来。所以排查要从成像开始,先看图上人眼能不能分清每个模块。
DataMatrix 与 QR 都有纠错能力,理论上可以容忍一定比例的模块损坏,但这个能力不能当作设计余量来用。关键区域一旦损坏就直接读不出——DataMatrix 的 L 形定位边与交替边界、QR 的三个定位图形和定时图形,这些是找码和确定网格的基础,不受纠错保护。工程上正确的做法是保证定位结构完整、清洁,把纠错留给意外情况,而不是靠纠错去补一个本来就打不好的码。
曲面(管件、瓶身、圆柱电池、轴类)上的码在图像里会被透视与曲率拉伸,模块网格不再是均匀方阵,解码器找不到规则栅格。可行的办法有几种:把视野限制在曲率影响小的中间一小段(配合更高分辨率);用远心或长焦镜头减小透视;从多个角度分别拍再取能读通的一张;或者在软件里做柱面展开校正后再解码。如果曲率太大,更根本的解法是改打码位置或改用平面区域。
在打码环节,不在读码环节。激光打码的功率、速度、离焦量,喷码的墨量与距离,标签的印刷分辨率与贴附平整度,这些决定了码的先天质量。读码工位只能在给定质量下尽力而为。所以有读码需求的产线应该在打码后紧跟一个校验读码(打完立刻读一次,读不出就报警重打),这比在下游反复调参数有效得多,也避免不可追溯的产品流到后面。

有具体设备清单或工件样品,可以直接给判断

提供设备型号、PLC 品牌与需要采集的数据项,或提供被检工件照片与精度要求,敏洽可先给出可行性判断与硬件前置条件,再谈软件工作量与报价。