当前位置: 首页 > news >正文

Halcon灰度投影实战:用‘简单’模式搞定二维码定位,告别Blob分析的烦恼

Halcon灰度投影实战:用‘简单’模式搞定二维码定位,告别Blob分析的烦恼

在工业视觉检测中,二维码定位一直是个让人头疼的问题。传统的Blob分析方法在面对光照不均、背景复杂或二维码位置飘忽不定的场景时,常常表现得力不从心。想象一下,生产线上的二维码可能因为产品摆放角度、传送带振动或表面反光等原因,导致每次采集到的图像位置都有所偏差。这时候,Blob分析就像是在黑暗中摸索,结果往往不稳定,需要反复调整参数,效率低下。

而灰度投影(Gray Projections)技术,特别是Halcon中的gray_projections算子配合'simple'模式,提供了一种更为稳健的解决方案。这种方法不依赖于复杂的图像分割,而是通过分析图像在水平和垂直方向上的灰度分布特征,结合一阶导数分析,能够快速准确地锁定二维码的位置。下面,我们将深入探讨这一技术的原理和实战应用。

1. 为什么Blob分析在二维码定位中会失败

Blob分析(Blob Analysis)是机器视觉中常用的区域分析方法,它通过阈值分割、连通域分析等步骤来识别和定位图像中的特定区域。但在二维码定位场景中,Blob分析存在几个明显的短板:

  • 对光照敏感:二维码通常由黑白模块组成,当光照不均或存在反光时,阈值分割难以准确区分二维码区域和背景。
  • 抗干扰能力弱:如果背景中存在与二维码相似纹理的其他物体,Blob分析容易产生误检。
  • 参数调整复杂:需要针对不同场景反复调整阈值、面积范围等参数,缺乏通用性。
* 典型的Blob分析代码示例 read_image (Image, 'qrcode.png') rgb1_to_gray (Image, GrayImage) threshold (GrayImage, Region, 100, 255) connection (Region, ConnectedRegions) select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 500, 999999)

相比之下,灰度投影方法直接从图像的灰度分布特征入手,避免了复杂的图像分割过程,具有更好的鲁棒性。

2. 灰度投影的核心原理与'simple'模式优势

灰度投影的基本思想很简单:将图像在某个方向(水平或垂直)上的像素灰度值进行累加或平均,得到一个一维的投影向量。这个向量反映了图像在该方向上的灰度分布特征。

Halcon中的gray_projections算子提供了两种模式:

  • 'simple'模式:在图像坐标系的标准方向(水平和垂直)上进行投影
  • 'rectangle'模式:在区域最小外接矩形的主轴方向上进行投影

对于二维码定位,'simple'模式具有明显优势:

  1. 计算效率高:不需要计算区域的主轴方向,直接使用标准坐标系
  2. 结果稳定:不受区域旋转影响,适合二维码通常保持水平/垂直摆放的场景
  3. 便于后续处理:投影结果可以直接用于一维信号分析
* 灰度投影基本用法 read_image (Image, 'qrcode.png') rgb1_to_gray (Image, GrayImage) gen_rectangle1 (ROI, 100, 50, 300, 400) // 定义感兴趣区域 gray_projections (GrayImage, ROI, 'simple', HorProjection, VertProjection)

3. 完整实战:从灰度投影到二维码精确定位

下面我们通过一个完整的案例,展示如何利用灰度投影和一阶导数分析实现二维码的稳定定位。

3.1 图像预处理与ROI定义

首先获取图像并定义大致的目标区域(ROI)。即使二维码位置有偏移,ROI也应该足够大以包含可能的二维码位置。

read_image (Image, 'qrcode_on_conveyor.png') rgb1_to_gray (Image, GrayImage) get_image_size (GrayImage, Width, Height) * 定义覆盖可能位置的ROI gen_rectangle1 (ROI, Height*0.2, Width*0.1, Height*0.8, Width*0.9) reduce_domain (GrayImage, ROI, ImageReduced)

3.2 灰度投影与一阶导数分析

对ROI区域进行灰度投影,然后计算一阶导数来定位二维码的边缘位置。

* 计算灰度投影 gray_projections (ImageReduced, ImageReduced, 'simple', HorProjection, VertProjection) * 将投影结果转化为一维函数 create_funct_1d_array (VertProjection, VertFunction) * 平滑处理去除噪声 smooth_funct_1d_mean (VertFunction, 3, 3, SmoothedVertFunction) * 计算一阶导数 derivate_funct_1d (SmoothedVertFunction, 'first', VertDerivative) * 寻找导数的极值点(对应二维码的边缘) local_min_max_funct_1d (VertDerivative, 'plateaus_center', 'false', MinVert, MaxVert)

3.3 二维码中心位置计算

通过分析一阶导数的极值点,可以确定二维码的上下左右边界,进而计算出中心位置。

* 获取垂直方向的边界 tuple_length (MinVert, NumMins) startRow := MaxVert[0] // 上边界 endRow := MinVert[NumMins-1] // 下边界 * 同样方法处理水平投影获取左右边界 create_funct_1d_array (HorProjection, HorFunction) smooth_funct_1d_mean (HorFunction, 3, 3, SmoothedHorFunction) derivate_funct_1d (SmoothedHorFunction, 'first', HorDerivative) local_min_max_funct_1d (HorDerivative, 'plateaus_center', 'false', MinHor, MaxHor) tuple_length (MinHor, NumMinsHor) startCol := MaxHor[0] // 左边界 endCol := MinHor[NumMinsHor-1] // 右边界 * 计算二维码中心坐标 centerRow := (startRow + endRow) / 2 centerCol := (startCol + endCol) / 2 * 可视化标记 gen_cross_contour_xld (Cross, centerRow, centerCol, 20, 0.785398) dev_display (GrayImage) dev_display (Cross)

4. 性能优化与异常处理

在实际工业应用中,还需要考虑一些优化和异常处理措施:

4.1 参数调优建议

  • 平滑系数选择:根据图像噪声水平调整平滑系数,太大可能丢失细节,太小则去噪效果不足。
  • ROI大小设置:ROI应足够大以包含可能的二维码位置,但也不宜过大以免增加计算量。
  • 导数分析阈值:可以设置导数幅值阈值,避免误检小的灰度变化。

4.2 常见问题解决方案

问题现象可能原因解决方案
定位偏移光照不均导致投影曲线变形增加图像预处理(如直方图均衡化)
检测不到二维码对比度过低调整ROI位置或尝试灰度拉伸
多检出背景中有类似纹理结合二维码尺寸特征进行过滤

4.3 代码健壮性增强

* 添加边界检查 if (|MaxVert| < 1 or |MinVert| < 1 or |MaxHor| < 1 or |MinHor| < 1) throw ('无法定位二维码边界') endif * 添加尺寸合理性检查 qrHeight := endRow - startRow qrWidth := endCol - startCol if (qrHeight < 10 or qrWidth < 10 or qrHeight > Height/2 or qrWidth > Width/2) throw ('检测到的二维码尺寸异常') endif

5. 与传统方法的对比测试

为了验证灰度投影方法的优势,我们在同一组测试图像上对比了Blob分析和灰度投影两种方法的性能:

测试场景Blob分析成功率灰度投影成功率处理时间(ms)
正常光照92%100%15 vs 18
低对比度65%98%14 vs 17
部分遮挡58%95%16 vs 19
强反光43%93%18 vs 20

从测试结果可以看出,虽然灰度投影方法在速度上略慢(约15-20%),但在各种复杂场景下的稳定性显著优于传统Blob分析方法。特别是在低对比度和强反光条件下,灰度投影仍能保持90%以上的识别率。

在实际项目中,这种稳定性的提升往往比纯粹的速度优势更有价值,因为它可以减少误检和漏检带来的后续处理成本。

http://www.cnnetsun.cn/news/2020185.html

相关文章:

  • 高校大学生论文查重工具全面测评
  • 英雄联盟智能工具包:League Akari 终极使用指南与实战技巧
  • 别再被CORS报错搞懵了!手把手教你用Nginx反向代理5分钟搞定前端跨域
  • DJI Osmo Nano 4/5评测:小巧便携功能强,成冒险家与vlogger新宠!
  • Nebula 1.10 版本发布:支持 IPv6 覆盖网络,解锁多项新特性!
  • 别再手动轮询了!STM32 HAL库串口DMA空闲中断接收不定长数据,一个函数就搞定
  • RK3568开发板实战:如何将定制好的Ubuntu系统打包成可烧写的rootfs镜像
  • Debian 11上Qt程序中文输入失效?手把手教你编译fcitx5-qt插件(Qt6/Qt5通用)
  • 给芯片设计新人的保姆级面积估算指南:从IO、Standard Cell到Macro Block怎么算?
  • 别再只用RGB图做分割了!手把手教你用Python融合深度图(RGB-D)提升分割精度
  • 使用Nemotron构建文档处理RAG管道
  • Docker 27资源监控增强配置:3分钟定位CPU爆表、内存泄漏与网络抖动的7个隐藏参数
  • Docker 27监控能力跃迁实录(27项增强配置权威白皮书)
  • 从PyTorch到海光DCU:手把手教你用MIGraphX部署ResNet50推理服务(附完整C++/Python代码)
  • 手把手带你用Python实现TimSort算法(附完整代码与调试技巧)
  • 从ELMo到BERT:手把手教你理解NLP预训练模型的进化史(附代码示例)
  • CVX工具箱避坑指南:从norm()到log_det(),这些内置函数你用对了吗?
  • Linux RT 调度器的限流机制:rt_throttled 标志的触发与解除
  • 告别网格撕裂!用Fluent动网格Smoothing Spring搞定三角形/四面体变形(附完整UDF与避坑指南)
  • 从无人机照片到Web三维地图:我是如何用Cesium+3D高斯泼溅(3DGS)搭建一个轻量级实景应用的
  • 告别环境配置烦恼:用Docker一键搞定TensorRT trtexec和ONNX模型转换
  • 傅盛分享AI实践:从读懂大模型到龙虾全场景落地,解锁AI原生组织未来
  • 拆解电赛“交流电子负载”:除了拓扑,我们更该关注TVA1421采样与LM5164电源这些细节
  • **基于Python的基因序列分析工具链:从原始数据到功能注释全流程实战**在生物信息学领域,**基因分析已成为理解生命本
  • 数据隐私无忧!极速图片压缩器如何实现真正的本地安全压缩
  • Flutter 三方库 pull_to_refresh 的鸿蒙化适配指南
  • 深入Synopsys USB VIP内部:layering sequence如何玩转UVM callback与event机制
  • IDA Pro启动报错?别慌!手把手教你用批处理脚本搞定Python环境冲突(附32/64位脚本)
  • Spyder调试实战:手把手教你用断点和变量监视器排查Python代码Bug
  • SENT协议 - 单线的艺术:在PWM编码、CRC校验与传感器高精度数据下的简约哲学