史上最全的支付宝二维码扫码优化技术方案

二维码又称二维条码,常见的二维码为QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。

设备扫描二维条码,通过识别条码的长度和宽度中所记载的二进制数据,可获取其中所包含的信息。

一、背景

随着支付宝的线下场景不断扩大,收钱码、口碑、共享单车、充电宝、停车缴费等产品让我们的生活越来越便利。二维码因为成本低、兼容性好成为了线上线上最主要的连接工具,也因此面临更多新的挑战。因为二维码是一种点阵式信息编码方式,任何视觉上的缺损、弯曲以及光线作用都会极大的影响识别成功率,如果识别困难也就意味着用户可能选择放弃,影响支付体验也影响用户心智。

用户扫码体验的最关键的主要有以下几个因素:

1. 识别率:这是扫码服务的基础指标,识别率能直接体现识别能力,识别率如果无法提高意味着大量的用户将无法使用更便捷的服务;

2. 识别耗时:包括 app 启动耗时以及图像识别耗时,这是衡量一个用户从点击 app 到正确识别到内容耗时,每增加 1s,将有相当大量的用户放弃等待并离开;

3. 精准反馈:识别结果不仅需要及时反馈给用户,还需要非常精准,特别是在目前线下有多个二维码的场景下,需要避免用户二次操作;

本文将从以上三个方面,分享支付宝扫码技术团队是如何为用户打造一个又准又快又稳的极致扫码体验。

二、提高识别率

我们对用户反馈进行了大量统计分析,发现绝大部分识别失败都是因为二维码并不标准,并且很遗憾的是在使用我们早期的扫码版本进行识别率测试时发现识别率只有 60%;

策略1:优化桩点查找算法长宽比耐受

以往的扫码算法,检查长宽比例时允许差异 40%,但是由于使用前向误差,判断结果跟长宽的先后顺序相关,这会导致有些长宽比失调的码,横着扫不出来,但是旋转 90 度竖着却能扫出来了(^OMG^)。

优化策略

  • 通过修改长宽比的判定规则,长宽比将不再受先后顺序影响;
  • 对于已知长度,修改规则将可接受的宽度范围扩大,增强长宽比的耐受;

在我们对比测试集中,识别率提高了 1% 左右。

策略2:新增1:5:1桩点识别模式模式

在一张图片中,要找到二维码,关键在找二维码特征定位点:

 

2.jpg

三个角的回字型图案,这就是二维码特征定位点。中间区域的黑白色块比例是1:1:3:1:1

 

3.jpg

以往的扫码算法,桩点识别是通过状态机 查找11311模式后 取中间位置确定x位置(此时扫描线在第一行11311比例处)在x位置纵向搜索11311模式, 确定y位置再以(x,y)位置横向搜索11311比例,修正x位置。这种模式在桩点污损的情况下,识别能力较差只要在任何一次11311模式搜索中遇到干扰点,哪怕是一个像素的椒盐噪声也能使桩点查找失败。(支付宝蓝的桩点,会在蓝色区域产生大量噪点,导致识别率低下)

 

4.jpg

为此,我们新增了一种桩点识别方式。在状态机达到151模式的时候,开始尝试确认桩点。(此时扫描线在第一行151比例处)。

 

5.jpg

优化效果

  • 新的查找方法将不再受桩点中心或边缘部分被污损的影响,支付宝蓝色桩点码识别率明显提升;
  • 修改后识别率整体提升了接近 1%,但识别失败的耗时有所提升;

策略3:添加一种对角线过滤规则

在枚举所有可能桩点组合 O(N^3) 之前,对所有可疑桩点进行一次对角线检查过滤。由于桩点对角线也应该满足 11311模式 ,用这个规则做一次过滤可疑有效减少运算量,也就有效降低了识别成功和失败的耗时。

 

6.jpg

策略4:基于 Logistic Regression 的二维码分类器

在以往的扫码算法中在拿到三个桩点后,基于夹角,长度偏差,单位长度查三个数值,用简单公式计算得到阈值,判断是否为可能的二维码,误判概率较大。

为此,我们引入机器学习中的逻辑回归算法模型。基于支付宝丰富的二维码数据集,训练出逻辑回归模型,作为二维码分类器,明显降低了误判概率,也将明显降低无二维码时识别失败的耗时。

策略5:修改跳行扫描的间隔数

由于输入的相机帧分辨率高,像素点多,运算量大,以往的扫码算法在水平跟垂直方向跳行采样进行计算。但在实际运算中,由于跳过了太多列,错过了11311模式中某些1位置的点,导致桩点查找失败。

我们通过将跳行计算行数修改为可配置项,通过线上 AB 灰度测试得到最合适的跳行策略,整体配置此跳行策略后,识别率得到明显提升。

上述优化在测试集的表现

 

7.jpg

综上优化,扫码核心识别能力,在7744张图片测试集上提高了6.95个百分点。

特殊策略优化

除此上述通用扫码优化之外,我们还对特殊场景扫码能力进行提高。

1.畸变?不怕不怕!

线下场景复杂多变。饮料瓶身上变形的二维码、超市小票卷起边角弯曲的二维码、路边小贩凹凸不平甚至折叠的二维码......这些畸变的二维码容易增加识别难度,甚至导致识别失败。

以往的扫码算法抗畸变策略中,先用透视变换关系建立映射关系。优点是:适应性好,满足大多数应用场景。不足也明显:对 Version 1 的码,因为映射关系退化为仿射变换,效果较差,手机必须和码平面平行才能方便识别。当物料表面不是平面的时候,效果较差。

优化策略

  • 假设采样坐标系到二维码坐标系遵守一个更复杂的映射关系,并且假设物料表面的卷曲较小,通过使用二次函数可以较好的拟合这个映射关系;
  • 实际发票上的二维码版本普遍大于等于 7,高版本二维码具有多个辅助定位点,更利于构造二次映射表;
  • 基于以上推论,使用新的映射代替旧的透视变换,进行更精准的采样;

用新的策略,发票码这个场景的二维码识别能力提升明显。

 

8.jpg

 

▲注意:由于采用了增强算法,请对准二维码稍作等待。

 

9.jpg

2.容错识别能力提升

商户或者供应商生成二维码后,通常会在二维码的中间部分贴上 Logo,这部分有可能会使二维码 Decode 时出错。

优化策略:

对于采样后拿到的 BitMatrix,对于中间部分一块矩形区域内的点,采用某些策略来改变中间点的值,使它能够通过容错边界的检查。目前采用两种策略,第一种是反转,第二种是每一个点随机取值。目前所取的矩形区域是长、宽的四分之一。

通过此项优化后,扫码的容错能力也得到明显提升。

 

10.jpg

三、更小的识别耗时

GPU计算二值化,降低识别单帧耗时

所谓图像二值化就是将图像上的像素点的灰度值设置为 0 或 255,也就是将整个图像呈现出明显的只有黑和白的视觉效果。下图左边为原图,右边是二值化处理过的图。

 

11.jpg

在扫码算法解码前,有二值化计算,图像的二值化计算能使图像中数据量大为减少,并弱化图像模糊、颜色对比度不强、光线过强/太弱、图像污损等情况下其他信息的干扰,更利于检测识别。

传统算法是在 CPU 上进行二值化运算,非常消耗 CPU 资源,但其实 GPU 更擅长大规模并行计算,所以我们选择使用 GPU 来做二值化计算。在安卓平台上使用 RenderScript,iOS 平台上使用 Metal,都是很底层的框架。

优化结果

1.iOS: 统一电池、角度、光线等环境变量, 在iPhone6 上测试扫码核心5种摄像头二值化算法。表现如下:

 

12.jpg

 

13.jpg

 

14.jpg

可以看出,在图像二值化方面 Metal 有相当高的优势,相比原来的单纯 CPU 处理快了接近 150%, 同时降低了近50个百分点的CPU资源。

2.Android机型众多,我们抽取了线上数据,可以看到GPU 在二值化处理中显著降低了单帧耗时30%以上。

二值化类型单帧耗时
传统二值化65ms
RS二值化44ms

 

15.jpg

四、调度维稳

线下物料千奇百怪,扫码算法为了解决一些不理想的场景,如二维码有遮挡、污损、模糊或角度很不好的特殊情况,需要使用一些比较耗时但比较强大的算法,但普通情况不需要这些算法。所以,我们对识码算法定了优先级,通过时间推移、跳帧触发等方式调度:

优先级:暂定高中低三个优先级。

  • 高优先级 每帧执行
  • 中优先级 降帧率执行
  • 低优先级 低帧率执行
  • 不同优先级的功能执行时机可配置。不同功能属于哪个优先级可配置

特殊场景算法——为码核心的一种特定能力,如:

  • 反色码识别能力
  • 容错边界码识别能力
  • 污损桩点识别能力等
  • 条码识别能力

看完以上这些,你get了吗?

 

原文链接
本文为阿里云原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/515299.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

抖音实战~取关博主

文章目录一、需求分析1. 取关流程图2. 取关流程简述二、源码实战2.1. 取关~前端2.2. 取关~后端三、5217取关实战3.1. 取关前资料分析3.2. 账号5217取关四、账号0009取关实战4.1. 账号0009取关4.2. 数据变化一、需求分析 1. 取关流程图 2. 取关流程简述 1.前端携带用户ID和短视…

终于有人把Python讲清楚了!

Python入门从哪开始,90%以上的书上都是这样讲的:先介绍 Python 的基本语法规则、list、dict、tuple 等数据结构,然后再介绍字符串处理和正则表达式,介绍文件等IO操作.... 就这样一点一点往下说。然而这种按部就班的学习方法&#…

MaxCompute 实现增量数据推送(全量比对增量逻辑)

ODPS 2.0 支持了很多新的集合命令(专有云升级到3版本后陆续支持),简化了日常工作中求集合操作的繁琐程度。增加的SQL语法包括:UNOIN ALL、UNION DISTINCT并集,INTERSECT ALL、INTERSECT DISTINCT交集,EXCEPT ALL、EXCEPT DISTINCT…

uniapp 引入iconfont的方法

文章目录1. 加入购物车2. 下载代码3. 创建静态目录4. 样式字体复制5. 字体转码6. 转码内容替换7. 样式引入7. 使用8. 个性化使用阿里图标库:https://www.iconfont.cn/ 1. 加入购物车 选中自己需要的图标依次加入购物车 2. 下载代码 打开购物车-下载代码到本地 …

独家下载 |《领军行业大数据及AI实战》解锁九大行业领军企业云上大数据及AI实战

飞天大数据平台不仅是阿里经济体大数据生产的基石,更为各行业客户提供大数据整体解决方案和强劲算力。上一册介绍阿里巴巴内部大数据实战的电子书《阿里巴巴大数据及AI实战》推出后,受到了广大开发者的认可。本次带来不同行业下企业的大数据&AI案例和…

从日志入手,保障 Kubernetes 稳定性

作者 | 悟鹏、沉醉来源 | 阿里巴巴云原生头图 | 下载于视觉中国不论对于软件的用户还是开发者,日志都是很重要的信息源。日志可以用来表征软件的运行状态,在软件运行不符合预期时提供丰富的信息,也可以用在开发阶段调试软件,方便定…

抖音实战~我关注的博主列表、关注、取关

文章目录一、关注模块1. 关注流程图2. 关注流程简述二、前端关注相关2.1. 查询我关注博主列表2.2. 取消关注2.2. 关注我2.4. 上滑分页粉丝列表2.5. 状态刷新三、后端关注相关3.1. 查询我关注的博主列表3.2. 取关3.3. 关注一、关注模块 1. 关注流程图 暂未上,敬请期…

灵魂拷问,上 Kubernetes 有什么业务价值?

上 Kubernetes 有什么业务价值? 今天要演讲的主题是跟应用管理或者说是云原生应用交付是相关的。首先我们想要先回答这么一个问题:为什么我们要基于 Kubernetes 去构建一个应用管理平台? 上图是一个本质的问题,我们在落地 K8s 经…

近7万新冠域名一半是钓鱼网站?以色列老牌安全厂商Check Point推出全端保护新战略

编辑 | 宋 慧 出品 | CSDN云计算 头图 | 付费下载于视觉中国 疫情肆虐的2020注定会被长久铭记。在这一年中,人们的工作、生活方式发生了巨变。在以色列老牌安全厂商Check Point全球进行的调查中显示,87%的工作人口采用了居家办公模式,74%的企…

掌门教育微服务体系Solar第3弹:Nacos企业级落地下篇

前言 在高速发展的时候,公司规模越来越大,老师人数越来越多,这时候公司不能铺太多人去做运营与服务,必须提高每个人效,这就需要技术驱动。因此掌门教育转变成一家技术驱动型的公司,如果被迫成为一家靠资金驱…

jdk 1.8 安装

步骤 B:配置 JAVA_HOME 系统变量区域,点击【新建】,在弹出的窗口中,分别输入变量名和值 变量名:JAVA_HOME 变量值:你的安装路径 JAVA_HOMEpath %JAVA_HOME%\bin步骤 C:配置 Path Path环境变量…

【漫画】最近,老王又双叒get了CDN的新技能—可编程化敏捷开发

原文链接 本文为阿里云原创内容,未经允许不得转载。

抖音实战~点赞数量弹框

组件 在components下面新建ge-popup.vue <template><view><view class"mask"></view><!--绑定微信--><view class"wxbox"><view class"weixin"><image src"../static/dz.jpg"></…

阿里张磊:如何构建以应用为中心的“Kubernetes”?(内含 QA 整理)

如何构建“以应用为中心”的 Kubernetes&#xff1f; 构建这么一个以用户为中心的 Kubernetes&#xff0c;需要做几个层级的事情。 应用层驱动 首先来看最核心的部分&#xff0c;上图中蓝色部分&#xff0c;也就是 Kubernetes。可以在 Kubernetes 之上定义一组 CRD 和 Contro…

Trie 树是什么样的数据结构?有哪些应用场景?

作者 | 神奕来源 | 前端应届生头图 | 下载于视觉中国出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;在计算机科学中&#xff0c;trie&#xff0c;又称前缀树或字典树&#xff0c;是一种有序树&#xff0c;用于保存关联数组&#xff0c;其中的键通常是字符串…

iOS Abort问题系统性解决方案

一、背景 崩溃(Crash)&#xff0c;即闪退&#xff0c;多指移动设备&#xff08;如iOS、Android设备&#xff09;在打开/使用应用程序的过程中&#xff0c;突然出现意外退出/中断的情况。如果App线上版本频繁发生崩溃&#xff0c;会极大地影响用户体验&#xff0c;甚至导致用户…

uniapp 处理过去时间对比现在时间的时间差 如刚刚、几分钟前,几小时前,几个月前

文章目录1. 返回的报文2. 时间格式化方法3. 使用1. 返回的报文 格式化时间&#xff1a;createTime [{"id": "62c11d3435b7c4007a8e650e","fromUserId": "21100598TZ9XG6RP","fromNickname": "小美女","fro…

云原生全景图之五:应用程序定义和开发层

作者 | Catherine Paganini、Jason Morgan来源 | K8sMeetup头图 | 下载于视觉中国前文介绍了如何将所有应用程序组件作为整体来编排和管理&#xff08;编排和管理层&#xff09;。本文将介绍云原生全景图的最上层&#xff1a;应用程序定义和开发层。现在我们来到了云原生全景图…

Flink 1.11 SQL 十余项革新大揭秘,哪些演变在便捷你的使用体验?

简介&#xff1a; SQL 作为 Flink 中公认的核心模块之一&#xff0c;对推动 Flink 流批一体功能的完善至关重要。在 1.11 中&#xff0c;Flink SQL 也进行了大量的增强与完善&#xff0c;开发大功能 10 余项&#xff0c;不仅扩大了应用场景&#xff0c;还简化了流程&#xff0c…

uniapp 小于1000 按原数字显示 超过1000 数字换算成10w+ 1.3k+ 显示

文章目录1. 公共方法2. 使用1. 公共方法 methods: {// 数字换算graceNumber(number) {if (number 0) {return "0";} else if (number > 999 && number < 9999) {return (number / 1000).toFixed(1) k;} else if (number > 9999 && numbe…