引言
随着智能手机处理能力及手机摄像头分辨率的快速提高,手机二维条码的应用也越来越广。手机既可以作为二维条码的载体,比如用户可以接收到服务商发送来的二维条码,再到实际消费场所以此作为凭证,进行消费;也可以作为二维条码的解码设备,对印刷在商品包装上的二维条码进行解码识别,得到商品相应的信息。目前,二维条码在国外一些发达国家已经有了很广泛的应用,在我国还处于发展阶段。中国移动已经正式推出了二维条码的业务,可以预见,手机二维条码必将在我国发展成为重要的移动增值业务。
DM码(DataMatrix Code),原名Datacode,是由美国国际资料公司(International Data Matrix)于1989年发明的。DataMatrix二维条码是一种矩阵式二维条码,其发展构想是希望在较小的条码上存入更多的数据。DataMatrix二维条码的最小尺寸是目前所有条码中最小的,特别适合于小零件的识别,以及直接印刷在实体上。
DataMatrix采用了复杂的纠错码技术,使得该编码具有超强的抗污染能力,即使编码部分破损,也不会影响读出全部信息。它有两种类型,即ECC 000140和ECC200。ECC 000140具有几种不同等级(ECC 050、ECC 080、ECC 100、ECC 140)的卷积错误纠正功能;而ECC 200是通过ReedSolomon纠错算法实现纠错功能。对于新的应用,推荐使用ECC 200,本文也以ECC 200为对象。
本文实现了基于Symbian平台的DM码的识别系统。测试表明,本系统可以正确、快速地识别DM码。
1DM码符号简介
每个DataMatrix二维条码符号由规则排列的方形模组构成的资料区组成,资料区的四周由定位图形(Finder Pattern)所包围,定位图形的四周则由空白区包围,资料区再以排位图形(alignment pattern)加以分隔。
定位图形是资料区域的一个边界,为一个模组宽度。其中两条邻边为暗实线,主要用于限定物理尺寸,定位和符号失真。另两条邻边由交替的深色和浅色模组组成,主要用于限定符号的单元结构,但也能帮助确定物理尺寸及失真,如图1所示。
图1Data Matrix图形结构
2DM码识别与解码的基本过程
识别过程是对DM码进行解码的前期步骤,其基本步骤如下:
① 图像灰度化。灰度化有两种常见的算法:第1种是标准灰度化计算公式W=0.30R+0.59G+0.11B,第2种是最大值灰度化公式W=max(R,G,B)。设某像素的 RGB的彩色各分量值为(R,G,B),其中0≤R,G,B≤255,W为灰度转换结果,max用于求取最大值。考虑到嵌入式设备得到的待解码图像多为黑白颜色,为了能够以更快的速度进行灰度化,并减少系统的运算量,这里采用第2种方法的改进公式W=G来进行灰度化。
② 图像滤波。条码图像的噪声一般来自于嵌入式设备的光学采集系统。这种噪声是满足泊松分布的椒盐噪声,可以用适当大小的中值滤波来进行处理。
③ 图像增强。由于图像可能存在高光区、阴影等缺陷,可以在二值化之前进行同态滤波,以此将图像亮度范围压缩,并将图像对比度增强,可以得到比较满意的图像增强效果,有利于二值化操作。
④ 灰度图像二值化处理。这里使用Ostu算法[1]计算出一个全局阈值T1,以此作为二值化的阈值。
⑤ 在得到的二值图像上进行对DM码定位图形的检测,定位图形就是左边与下边的直线连在一起形成的“L”边。关键是对直线的检测。
首先通过Sobel算子,将二维条码图像进行边缘提取。然后根据Freeman准则进行直线检测。
Freeman直线检测的3条准则如下:
a. 一条数字直线的8邻域链码中最多包括两个方向,其中一个为主方向。它是决定直线方向的主要因素。
b. 这两个方向的链码值相差1(mod8)。
c. 主方向上链码值相同的连续像素组成一个线段子元,除去第一个和最后一个线段子元,其余各线段子元的长度至多相差一个像素。
对检测到的直线段,采用以下准则判断是否是条码的“L”定位图形:
a. 两直线段夹角在90°附近时判断两线段夹角准则如下:设线段1中起始像素坐标为(X1,Y1),终止像素坐标为(X2,Y2);线段2中起始像素坐标为(X3,Y3),终止像素坐标为(X4,Y4),则线段1的斜率K1=(Y2-Y1)/(X2-X1),线段2的斜率K2=(Y4-Y3)/(X4-X3),两线段之间的偏转角度θ=arctg (|(K2-K1)/(1+K2K1)|)。
由于存在透视效果,若|90°-θ|≤α(α为阈值,一般α∈[0,20°])成立,则两线段近似认为是垂直线段。
b. DataMatrix条码的“L”定位图像有交点,因此判断两直线是否具有相同或相近交点。
c. 由于DataMatrix条码的特点,一般长宽比不超过3,因此判断两直线段长度比在1~3之间。
将符合以上准则的直线段作为候选“L”边,过滤其他不符合条件的直线段。
⑥ 通过得到DM码定位图形,可以将DM码旋转至水平位置,并将DM码分割出来。
通过以上步骤完成DM码的识别。
DM码解码基本步骤如下:
a. 识别格式信息,完成对格式信息模块的纠错和识别。
b. 识别版本信息,确定DM码的版本。
c. 消除掩膜。
d. 根据模块排列规则,识别符号字符,得到信息和纠错码字。
e. 用得到的纠错码字对识别得到的信息进行错误检测,如发现错误则进行纠错。
f. 按照所使用的模式译码得出数据字符,并输出结果。
3DM码识别系统在Symbian平台上的实现
3.1Symbian操作系统介绍
目前,主流的智能手机操作系统有3种:Symbian、Windows Mobile和Linux。其中Symbian以其平台的开放性、较低的授权费用、众多厂商的支持、对硬件要求低、第三方软件丰富等优势,成为智能手机市场上应用最为广泛的产品。Symbian是一个实时、多任务的纯32位操作系统,具有功耗低、内存占用少等特点,非常适合手机等移动设备使用,经过不断完善,可以支持GPRS、蓝牙、SyncML以及3G技术。最重要的是,它是一个标准化的开放式平台,任何人都可以为支持Symbian的设备开发软件。Symbian操作系统融合了许多功能强大、成熟稳定的技术,其中包括丰富的应用引擎、移动电话技术、安全性、多媒体、支持多种应用界面、通信协议、软件开发(Java和C++)等。
根据不同的终端产品在屏幕尺寸、用户输入方式等方面的差异,Symbian给出了用户界面风格的3种参考设计——Pearl、Crystal和Quartz,最终演变为Symbian上的3种主要平台——Series 60、Series 80和UIQ。Series 60是智能手机中应用最广泛的系统版本,拥有最多第三方软件或游戏的界面。Series 80针对屏幕分辨率为640×200像素、采用标准键盘输入的高端智能手机。UIQ针对采用笔式输入(触摸屏)的智能手机。本系统是在基于Symbian Series 60 3rd FP2(第3版Features Pack 2)平台的手机上实现的。
3.2图像采集
在手机移动平台上进行DM码解码处理,图像采集获取是重要的第一步。在Symbian Serial 60平台上,使用CCamera类对摄像头的操作进行了封装,提供了与摄像头操作有关的API,并提供了一个MCameraObserver的类来通知系统摄像头操作的各种关键事件的完成,必须实现这个类的所有纯虚方法,以供系统在一个事件完成的时候进行回调。McameraObserver类与CCamera类是观察者设计模式(observer designed Pattern)在Symbian中的具体体现。具体启动摄像头取景器步骤如下:
首先,创建一个CCamera类的实例:
iCamera = CCamera::NewL(aOberver,0)这样以后就可以通过iCamera来实现对摄像头的操作了。然后,取得摄像头的使用权,这可以通过函数 iCamera﹥Reserve()来实现。这是个异步函数,在取得摄像头使用权成功后,系统会自动调用MCameraObserver::ReserveComplete()方法。在这个回调函数中,就可以进行下一步操作,对摄像头进行上电启动,通过函数iCamera﹥PowerOn()来实现,同样这也是一个异步函数。在对摄像头上电完成后,系统接着就会自动调用MCameraObserver:: PowerOnComplete() 这个回调函数,这时在这个函数中就可以启动取景器了,具体函数为iCamera﹥StartViewFinderBitmapL( )。当取景器得到一帧图像的时候,系统就会自动的周期性的调用MCameraObserver::ViewFinderFrameReady (CFbsBitmap aFrame),而放在aFrame这个参数中的图像就是得到的要进行处理的图像,在这个函数中完成图像的解码。这样就完成了图像的采集工作。
3.3自动对焦
一般的DM码是印刷在商品的包装上的,这就决定了DM码的面积不能太大。另外手机在取景的过程中,操作者可能会有抖动的现象,这两点原因就给DM码的图像采集造成了麻烦,可能导致摄像头得到的图像很不清楚,不利于后期的解码。对于这一问题,如果摄像头支持自动对焦(auto focus),那就可以用自动对焦来使摄像头得到的图像自动变得清晰。
自动对焦是作为Symbian开发平台SDK的扩展库(extension library)中的一个功能,可由开发者自行将相应的头文件和库文件添加到SDK中。具体使用如下:
首先包含头文件#include <CCamAutoFocus.h>和在Symbian工程的MMP文件中链接库文件LIBRARY CamAutoFocus.lib。然后构造一个CCamAutoFocus类的实例,iAutoFocus = CCamAutoFocus::NewL( iCamera ),这样就可以用iAutoFocus来进行自动对焦的相应操作。
对自动对焦进行操作需通过以下步骤:
① 初始化:iAutoFocus﹥InitL(*this)。
② 开始自动对焦:iAutoFocus﹥AttemptOptimisedFocusL()。
③ 取消自动对焦:iAutoFocus﹥Cancel()。
④ 关闭:iAutoFocus﹥Close()。
对于初始化和开始自动对焦这两个步骤,都有相应的回调函数,CCamEngine ::InitComplete ()和CCamEngine::OptimisedFocusComplete(),以便在完成相应动作的时候,开发者作一些相关操作。
通过自动对焦,当用户将手机摄像头在一定距离内对准DM码时,可以看到摄像头的取景器自动变得清晰了,而这对于解码来说非常重要。
在本项目中,为了方便用户,还采用了定时器的功能,即通过设定时间间隔,每隔一段时间就自动对焦一次,这样更能保证采集图像的清晰程度。
3.4清除栈和两阶段构造
Symbian平台是专门为嵌入式移动设备而设计的操作系统,而手机这一移动嵌入式设备的内存资源非常有限,而且通常要连续运行很长时间却很少重启。这两个特点就使得内存泄漏在Symbian系统上变成了非常重要的问题。对于这个问题,Symbian系统采用清除栈和两阶段构造来解决[2]。
清除栈(在e32base.h中定义CleanupStack)是一个特殊栈,它对于Symbian OS资源管理至关重要。它在本质上是一种用于保护在异常退出发生时清除所有资源,从而不会产生任何内存泄漏的方式。
其基本思想是,在调用可能异常退出的函数前,使用PushL()将可能泄露的内存指针推入清除栈。如果真的发生异常,就自动删除推入栈上的指针所指向的内存空间;如果没有发生异常,就使用Pop()方法从栈上移除指针。这样就可以避免因为发生异常而导致的内存泄露。
两阶段构造就是建立在清除栈基础上的一种安全的构造对象的方法。
一般PC平台的程序通过new方法来进行构造的对象,会自动调用相应的构造函数,但如果在构造函数中发生了异常退出,那么这个对象前期所申请的内存就会产生泄露。两阶段构造就是用于解决这一问题的。
3.5版本兼容
本项目基于Symbian Serial 60 3rd FP1平台,而目前已经有了Symbian Serial 60 3rd FP2和Symbian Serial 60 5th(第5版)。这2个版本和本项目的平台版本的一个重要区别,就是对摄像头的操作。为了与这两个版本保持兼容,需要将对摄像头操作的CCamera类换成CCameraEngine类。这个类同样也是一个SDK扩展功能,使用时要包含头文件(#include "CamEngine.h")和链接库(LIBRARY camerawrapper.lib)。
本系统在NOKIA N82和NOKIA N95上进行了测试,可以正确、快速地进行解码;在NOKIA 5800(Symbian S60第五版)上进行了兼容性测试,也得到了很好的效果。
4结论
本文通过介绍DataMatrix二维条码的基本原理和识别解码的基本步骤,设计并实现了一个基于Symbian平台的DataMatrix的识别系统。详细介绍了Symbian平台摄像头的应用和自动对焦的特点,并对不同的Symbian平台版本之间的代码兼容作了说明。
本系统可以准确、快速地识别二维条码。还可以加入验证功能,即通过网络连接或发送短信的方式,将识别所得的二维条码所包含的真伪信息发送的服务器,在服务器端进行防伪验证工作,并将验证结果返回给用户。此功能目前已经实现,这也是本系统的一项扩展应用。可以预见,通过使用手机识别二维条码来获取信息的应用前景将会非常广泛。