导读

初见小程序码,犹如一朵盛开的菊花。
image.png

其实这种脑洞大开的异形码并非微信首创,Facebook、kik、snapchat 等公司都研发了自己体系的码。

菊花绽放?微信居然这样开发设计与识别小程序码的? - 图2

从设计的图形上,我们把上述方案简单分成:
• 平面类,如:qrcode,snapchart code
• 环状类,如:fb code,kik code

考虑到专利风险,又要兼顾优雅美观,我们最终选择放射状作为我们的 base 方案,也就是最后面世的 “菊花码”。

设计篇

小程序码的构成

小程序的 3 个 “牛眼” 用来定位,放射线条编码信息,这是一个大家都懂的原理。但”麻雀虽小,五脏俱全“,小程序码与 QRCode 类似,同样包含了定位区,编码信息区,元信息区等部分,除此以外,我们还加入了自定义 Logo 区,下面让我们来解剖一下小程序码。

如何生成一个小程序

” 万丈高楼平地起 “,那小程序码是如何一砖一瓦构建起来的呢?我们以一个实例来演示小程序码的生成 。

1 . 定位点

定位点主要用于标记小程序码的大小及在图中的位置,与 QRCode 类似, 我们采用了 3+1 的方案,3 个主定位点加一个辅助定位点。可以发现,定位点的对角连线交点刚好是码的圆心,3 个主定位点又刚好组成一个等腰直角三角形。以上的特征,非常有利于定位识别。
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图3

2 . 信息编码区

我们会把原始编码的字符串,转换成 01 的序列,再加入纠错码,得到最终 01 序列。我们只需要把 01 序列按一定的编码路径,填充到信息编码区的方格中即可 (0 为白,1 为黑)。小程序在图案编码阶段,也是按点编码的的,并没有线的概念。
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图4

3 . 掩码图案

填充好编码区之后,我们发现图案与设计稿大相径庭,并没有发射状线条的感觉。究其原因,是因为黑色点过于稀疏。所以我们还要做 mask, 加上掩码图案。
mask 的原理其实就是拿一个掩码图案与原图做 XOR 操作,在解码阶段,再做一次 XOR 操作,两次 XOR 操作,我们得到了原始的数据区。
我们按照一定的规则,预先设定了 32 种 mask 模板。在码生成阶段,会寻找一个最佳的 mask, 让我们的黑白分布更具线条感。mask 完成后,我们得到了下面的效果图。
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图5

4 . 元信息区

前面我们提到,小程序码分为多个版本,每个版本有 4 个纠错 Level, 同时 mask 阶段又有一个独特的 mask id。这些信息,我们称之为元信息,需要独立编码到图案中,并且本身具备纠错能力。

菊花绽放?微信居然这样开发设计与识别小程序码的? - 图6

至此,我们已经把所有必不可少的信息写入到图案中,码本身已经是可识别的了。为了让整体更加美观,需要对内外圈再进行一些处理。

5 . 轮廓填充区

为了凸显 logo 的形状,我们在内圈留了一些区域作为轮廓填充区。

菊花绽放?微信居然这样开发设计与识别小程序码的? - 图7

6 . 边缘补全区

最外圈也不带有编码信息,用于勾勒图案的轮廓,总体上我们有以下两种方案

菊花绽放?微信居然这样开发设计与识别小程序码的? - 图8

方案一更突出图案更加圆的特点,但方案二可以让线条显得更加错落有致,也是我们的最终选择。

可拓展

为了让小程序码在编码容量上的需求,我们设计了 36 线,54 线,72 线三种版本,每个版本支持由低到高 L,M,Q,H 四种纠错等级,分别能纠错 10%,15%,25%,35% 的信息。
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图9

不同的版本,在不同的纠错 Level 下,采用不同的字符集,其最大编码容量如下
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图10

编后语

从小程序码设计上,有以下几个特点:

  • 高识别度 保留最核心的中间区域给使用者自定义,让每个品牌商都有自己的专属码
  • 高容错 实际应用中,大部分 QRCode 由于中间部分被 logo 覆盖,有效编码区域丢失。而小程序码是无损的,在相同纠错等级的情况下,容错性更高。
  • 更安全 QRCode 由于其开放性,容易成为 “病毒” 的温床。而小程序码采用完全私有的协议,只有微信可以生成,也只有微信可以解码,用户可以放心的打开扫一扫。

最后我们再通过下图,感受一下小程序码这朵 “菊花” 绽放的过程。
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图11

识别篇

识别之前,我们需要对照片做什么处理

打开扫一扫,扫码引擎通常采集到的图片是这样子的。
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图12
引擎其实并不关心这朵菊花是什么颜色,因此,我们把图片简化,处理成灰度图。
二值化可以让引擎做的事情更简单,因此再将灰度图处理成位图。
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图13

如何在黑白图中快速找到菊花的位置

细心的朋友肯定注意到,每一朵菊花都有两个共同点:

  • 3 个圆形的 “牛眼”(定位点)
  • 右下角的 “小程序 LOGO”

以上是小程序码的定位信息,准确的定位是识别的第一步。

如何快速找出所以可能的定位点

在设计这个菊花码时,我们是按照 0.8:1.2:1:1.2:0.8 绘制定位点的。
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图14

为什么不采用 1:1:1:1:1 的比例?因为前者比例比较贴近黄金比例,更符合人类审美需求。(下图右为 1:1:1:1:1)
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图15
基于这个特性,使用水平,垂直,45 度角等三个方向的扫描线扫描全图。如果三个方向的黑白像素都接近这个比例,显然它极可能是一个定位点。
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图16

怎么定位 “小程序”LOGO

最简单的方法,根据 3 个定位点的位置,预估小程序 LOGO 的中心位置(平行四边形)
在很多扭曲的情况下,上述方法仍有较大偏差。因此我们提出了一种改进方法: 基于 LOGO 为圆形的特性,将预估的中心点修正到圆心位置
具体校正方法如下:
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图17

拍摄出来的码这么歪,能否摆正?

由于上文中,我们已经找到了码在图像中的位置,但由于这个码可能已经被旋转,扭曲,所以,我们需要再做一次矩阵变换(透视变换),将其变换到直角坐标系。变换后的码,已经比较易于被机器解读了。
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图18

怎么读码

二维码怎么读码

上述流程和传统二维码识别的核心思想并无二致,如果你坚持看到这里,说明你已经知道如何识别二维码了。
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图19
经过透视变换,二维码其实已经变成了单位矩阵(如上图,你可以理解一个小块为一个像素点,这里为了方便阅读,放大了),那么,我们顺着二维码的编码路径,就能完整地读出编码信息了。

小程序码怎么读码

其实,按照二维码的套路,我们可以把透视变换后的图,进行编码区域划分。值得注意的是,这里一个彩色小块并非一个像素点,而是一片区域。一个编码块是 0 还是 1,取决于该区域上的黑色像素(面积)的比例,我们称之为 “投票法”。
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图20

是否有其他读码方案请输入标题

但在实际应用中,我们发现该方法对于扭曲的场景,识别效率很低,鲁棒性不佳。经过各种尝试和思考,我们借鉴了一维码的识别思路 ——“采样法”。
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图21

举个例子,上图中,我们用红色扫描线采样一维码的信息,对于采样的一行像素,我们根据比例读出具体的编码。

菊花绽放?微信居然这样开发设计与识别小程序码的? - 图22

类比该方案,我们利用小程序码为 “放射线” 编码的特性,采样每一条放射线上的一个像素序列,根据黑白比例读出每一条线的编码信息。

目前扫码引擎的性能如何,能应对什么场景

在测试阶段,我们内部自行拍摄采集了各种场景下的大量测试样本,做了如下评测
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图23
包括如下场景
菊花绽放?微信居然这样开发设计与识别小程序码的? - 图24

链接