《电子技术应用》
您所在的位置:首页 > 嵌入式技术 > 业界动态 > 基于Symbian智能手机的QR码识别系统

基于Symbian智能手机的QR码识别系统

2008-07-16
作者:温 明1,李 颢2,卓 晴

    摘 要: 介绍了QR码识别的基本原理,并设计了一个基于Symbian智能手机的QR码识别系统" title="识别系统">识别系统,重点说明了系统在Symbian平台上实现时,图像采集、异常处理" title="异常处理">异常处理和代码移植等方面的问题。测试表明,该系统可以快速、准确地识别QR码,并有效地处理图像倾斜和投影形变等问题。
    关键词: QR码  智能手机  Symbian操作系统  Series 60平台

 

    由于内置高分辨率摄像头手机的逐渐普及,催生了一种新的二维码应用模式——手机二维码。手机二维码是指将相关信息使用二维码编码,并以各类业务的形式在手机里存储、阅读和传播[1]。手机既是二维码信息的载体,也是二维码的识读设备。目前,手机二维码在欧美、日韩等发达国家和地区已有较成熟的市场应用。2006年9月,中国移动也正式推出了手机二维码业务,并表示手机二维码将会成为移动增值服务的重要内容之一。
    QR码(Quick Response Code)是由日本Denso公司于1994年9月研制的一种矩阵式二维码,它除具有其他二维码所具有的信息容量大、可靠性高、可表示汉字及图像有多种文字信息、保密防伪性强等优点外,还具有如下主要特点:超高速识读,全方位识读,能够有效地表示中国汉字和日本汉字[2]。本文设计了一个基于Symbian智能手机的QR码识别系统,重点介绍了系统在Symbian平台上实现时需要注意的关键问题。测试表明,该系统可以快速、准确地识别QR码,并能有效地处理图像倾斜和投影形变等问题。
1 QR码符号简介
    QR码符号是由正方形模块构成的正方形阵列,它由编码区域和功能图形构成。其中,编码区域包含格式信息、版本信息、数据和纠错码字;功能图形由寻像图形、分隔符、定位图形和校正图形组成。QR码符号共有40种规格。版本1的规格为21×21模块,每一版本的符号比前一版本每边增加4个模块,直到版本40,规格为177×177模块。QR码符号的示例见图1。

 

 

2 QR码的识别
    这一过程的基本思路是将摄像头采集到的彩色图像I(x,y)进行灰度化;然后用适当的阈值T对灰度图像进行二值化处理,从而得到二值图像B(x,y);接着在二值图像中扫描位置探测图形,通过3个位置探测图形,求出QR码的4个顶点坐标和旋转角度,然后将QR码旋转至水平位置,并把QR码从图像I(x,y)分割出来。
2.1 图像的二值化
    图像二值化的关键在于阈值的选取。二值化阈值计算方法主要有直方图双峰法、微分直方图法和最大类间方差法。在基于手机的QR码识别系统中,由于人在拍摄过程中会有意识地“瞄准”QR码符号,并使其尽量充满取景器的主要区域,因此采集到的QR码图像一般都比较简单,浅色的背景与条码基本模块构成的正方形阵列形成了较大的反差,其直方图经过平滑之后,呈现出明显的“双峰”特性。这样,使用简单的直方图双峰法就可以快速地确定图像的二值化阈值。
2.2 QR码的定位
    QR码符号的寻像图形包括3个相同的位置探测图形,分别位于左上角、右上角和左下角。每个位置探测图形可以看作是由3个重叠的同心正方形组成,它们分别为7×7个深色模块、5×5个浅色模块和3×3个深色模块。位置探测图形的模块宽度比为1:1:3:1:1。符号中其他地方遇到类似图形的可能性极小,因此可通过识别这三个位置探测图形来确定视场中符号的位置和方向,从而使迅速识读QR码符号成为可能。在图2中,a、b、c为QR码符号旋转不同角度时穿过位置探测图形中心的扫描线。可以看出,旋转的角度不影响扫描线上的模块宽度之比。实际中,由于噪声、投影形变等因素的影响,应该允许这个比例有一定的偏差。

 

 

2.3 图像的旋转
检测到3个位置探测图形之后,就可以计算出QR码的4个顶点坐标和旋转角度。根据这些参数即可将QR码旋转至水平位置并从图像中分割出来。在对图像做旋转时,变换之后的坐标不一定是整数,因此要对变换之后整数坐标的像素值进行估计。这里采用的是双线形插值算法。假设输出图像某像素的位置坐标通过反向变换得到的浮点坐标为(i+u,j+v),其中i,j为非负整数,u,v为[0,1)区域的浮点数,则该像素的值f(i+u,j+v)可由原图像中坐标为(i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)的4个像素的值决定,即[3]
    f(i+u,j+v)=(1-u)(1-v)f(i,j)+(1-u)vf(i,j+1)+u(1-v)f(i+1,j)+uvf(i+1,j+1)
    将QR码从图像中分割出来之后,建立采样网格,对网格的每一交点上的图像像素取样,即可得出QR码符号的位图矩阵。
3 QR码的解码
    这一过程将QR码符号数据按照QR码标准进行解码,从而得到存储在其中的用户信息。解码的流程如下[2]

    (1)识读格式信息,按需要去除掩模" title="掩模">掩模图形并完成对格式信息模块的纠错,识别纠错等级与掩模图形参考。
    (2)识读版本信息,确定符号的版本。
    (3)用掩模图形(掩模图形参考已从格式信息中得出)对编码区域的位图进行异或处理,消除掩模。
    (4)根据模块排列规则,识读符号字符,恢复信息的数据与纠错码字。
    (5)用与纠错级别信息相对应的纠错码字检测错误,如果发现错误,立即纠错。
    (6)根据模式指示符和字符计数指示符将数据码字划分成多个部分。
    (7)按照使用的模式译码得出数据字符并输出结果。
4 QR码识别系统在Symbian平台上的实现
4.1 Symbian操作系统
    智能手机是一种拥有开放型操作系统的手机,用户可以在这个平台上安装各种各样的应用程序" title="应用程序">应用程序,从而使手机的功能得到无限扩充。目前,主流的智能手机操作系统有三种" title="三种">三种:Symbian、Windows Mobile和Linux。其中Symbian以其平台的开放性、较低的授权费用、众多厂商的支持、对硬件要求低、第三方软件丰富等优势,成为智能手机市场上应用最为广泛的产品。Symbian由Psion公司的EPOC(Electronic Piece of Cheese)操作系统发展而来,是一个32位的多任务操作系统,其内核由基础组件(微核、设备驱动程序和用户库)、中间件(系统服务、安全和应用程序框架)和通信组件(电话、消息和个人区域网络)构成[4]。由于不同的终端产品在屏幕尺寸、用户输入方式等方面的差异,Symbian给出了用户界面风格的三种参考设计:Pearl、Crystal和Quartz,最终演变为Symbian上的三种主要平台:Series 60、Series 80和UIQ。Series 60针对屏幕分辨率为176×208像素、单手操作的智能手机;Series 80针对屏幕分辨率为640×200像素、采用标准键盘输入的高端智能手机;UIQ针对采用笔式输入(触摸屏)的智能手机。其中Series 60是应用最为广泛的平台。本系统就是在基于Symbian Series 60平台的手机上实现的。

4.2 图像采集
    系统在手机上实现时, 待识别图像的采集是一个比较关键的问题。在Series 60平台上,CCamera类包装了摄像头相关的API。为了使用这些API,应用程序必须实现一个MCameraObserver(或MCameraObserver2)的派生类。MCameraObserver类与CCamera类之间的关系是观测者设计模式(Observer Design Pattern)在Symbian系统中的具体体现。图像采集可通过以下三种方式实现:
    (1)用CCamera∷CaptureImage()启动静态图像的捕获。当其调用完成之后,MCameraObserver∷ImageReady()会被异步调用。用户可在该函数中访问刚刚捕获的图像。此方式一般用来实现手机的照相功能。
    (2)用CCamera∷StartVideoCapture()启动视频捕获。当视频缓冲区被预置数目的视频帧填充之后,MCameraObserver∷FrameBufferReady()会被异步调用。用户可在该函数中访问视频缓冲区。此方式一般用来实现手机的摄像功能。
    (3)用CCamera∷StartViewFinderBitmapsL()启动取景器(View Finder)数据的传输。当其调用完成之后,MCameraObserver∷ViewFinderFrameReady()会被周期性地调用。用户可在该函数中访问刚刚获取的视景帧(View Finder Frame)。此方式一般用来实现手机照相或摄像过程中的取景器功能。
    第一种方式采用非连续模式采集图像,效率较低且不利于人在识别过程中的主动参与。第二种方式虽是连续模式,但在视频采集过程中,摄像头的闪光灯会一直亮着,不符合低功耗原则。第三种方式采集图像的分辨率高,有利于识别精度的提高,但会增加处理时间。最终采用第三种方式并折中处理,选择400×300的分辨率。
    ViewFinderFrameReady()函数的处理流程如图3所示。视景帧是一个CFbsBitmap类型的位图对象。可以通过CFbsBitmap::DataAddress()函数获得位图中第一个像素(位于位图的左上角)的地址,从而实现对位图数据的直接访问。视景帧根据手机类型的不同,具有不同的颜色格式。所以需要首先通过CFbsBitmap∷DisplayMode()函数获得图像的颜色格式,然后采用相应的方式获取各像素的R、G、B分量,以便将彩色图像转换为灰度图像。

 


4.3 异常处理
    对手机而言,内存泄漏是十分严重的问题。因为手机的内存资源非常有限,而它又通常会连续运行很长时间不重启,这样,异常处理就显得尤为重要。Symbian系统采用了一套不同于标准C++的异常处理机制。
    Symbian对异常处理的基本支持包括:(1)TRAP和TRAPD宏,用作捕获异常,类似于标准C++中的try和catch。(2)异常退出(Leave)机制,其作用类似于标准C++中的throw。
    清理栈(Cleanup Stack)是Symbian避免内存泄漏的主要手段之一。请看如下示例代码:
void DoExampleL(){
CSomeObject*myObject=new(ELeave) CSomeObject;
CallLeavingMethodL();
delete myObject;}
    代码使用重载的操作符new(ELeave)为CSomeObject类的新实例分配动态内存。在Symbian中,为简单对象在堆内存上分配空间基本都采用这种方式。ELeave参数表明内存分配失败时会发生异常退出。传统的new操作符无法利用异常退出机制,只是在极少数情况下才被使用。CallLeavingMethodL()是一个调用时可能会发生异常退出的函数。当CallLeavingMethodL()发生异常退出时,DoExampleL()的函数栈会被释放。这就意味着,局部指针变量myObject会被销毁,但它指向的堆内存却没有被释放,从而发生了内存泄漏。Symbian使用清理栈(CleanupStack类在e32base.h中定义)来解决这个问题。基本用法是:在调用可能会发生异常退出的代码之前,使用PushL()方法将任何指向堆内存的局部指针压入清理栈内。若发生异常退出,清理栈确保所有相关的资源都被释放。如果没有发生异常,则使用Pop()方法将那些指针弹出。这样,DoExampleL()函数可以修改为:
void DoExampleL(){
CSomeObject*myObject=new(ELeave) CSomeObject;
CleanupStack∷PushL(myObject);
CallLeavingMethodL();
CleanupStack∷Pop(myObject);
delete myObject;}
    可以使用“CleanupStack∷PopAndDestroy(myObject);”代替上述代码的最后两句。有三种情况可能会使代码发生异常退出:
    (1)使用了退出函数:User∷Leave(),User∷LeaveIfError(),User∷LeaveNoMemory(),或User∷LeaveIfNull()。
    (2)使用了重载的new(ELeave)操作符。
    (3)调用了一个可能会异常退出的函数。
    构造过程中需要分配资源的对象被称为复杂对象,其所属类通常为CBase类的派生类。在堆内存上构造复杂对象时,若其构造函数发生异常退出,则会发生内存泄漏。所以复杂对象采用两阶段构造过程,这是Symbian避免内存泄漏的另一主要手段。例如,使用CText类表征解码之后的文本,它的一个私有成员变量textBuf8为指向HBuf8类描述符(Symbian主要使用描述符来处理字符串)的指针。下面为两阶段构造过程的示例代码:
//第一阶段构造
CText∷CText(){}
//第二阶段构造
void CText∷ConstructL(TUint aMaxTextLength)
{ textBuf8=HBufC8∷NewL(aMaxTextLength);}
    这样,每次构造复杂对象都需要两行代码。为了避免这个麻烦,通常会提供两个静态成员函数:
//不将指向函数返回对象的指针留在清理栈内
CText*CText∷NewL(TUint aMaxTextLength){ 
CText*self=CText∷NewLC(aMaxTextLength);
CleanupStack∷Pop(self);
return self;}
//将指向函数返回对象的指针留在清理栈内
CText*CText∷NewLC(TUint aMaxTextLength){
CText*self=new(ELeave) CText;
CleanupStack∷PushL(self);
self->ConstructL(aMaxTextLength);
return self;}
4.4 代码移植
    系统开发并不需要从零开始编写所有程序,有很多地方(例如直方图双峰法、双线性插值和RS码纠错算法等)可将现成的Windows平台的代码移植到Symbian平台上来。在移植过程中,除了异常处理方式需要改变之外,还需要注意以下几点:
    (1)将标准C++的内建数据类型替换为对应的或者合适的Symbian C++的基本数据类型,以保持平台的独立性。例如,用TInt类型替换int类型。
    (2)在Symbian系统中,由于GUI应用程序(后缀为.app的程序)的栈的默认尺寸只有8KB,所以不要在这类程序中使用尺寸较大的局部变量。遇有需要的情况(例如大数组),将对象分配在堆内存上。
    (3)在Symbian 8.1a及以前版本的操作系统中,DLL(Dynamic Link Library)程序不能使用可写的静态数据(例如全局变量);在Symbian 8.1b及以后版本的操作系统中,尽管DLL程序支持可写的静态数据,但不推荐使用。Symbian的GUI应用程序实际上是apprun.exe程序启动的DLL程序,所以在这类程序中不可以使用全局变量。代码移植时,应将这些变量封装到类中。另一种解决方案是将原代码移植为Symbian服务器程序(后缀为.exe的程序,支持可写的静态数据),并向客户程序提供API接口。
    (4)Symbian不支持标准模板库(STL),但提供了一些集合类来支持数组、链表等数据结构。
    系统基于S60 2nd Edition SDK(FP3)开发,采用的开发环境为Metrowerks公司的CodeWarrior。系统在Nokia N70上做了性能测试,可以达到平均约0.6s的识别速度。在没有微距模式支持的情况下,可以识别的QR码符号的最高版本为10。测试还表明,系统可以有效地处理QR码图像倾斜和投影失真等问题。系统在Nokia 3230和Nokia 6680上做了兼容性测试,也取得了比较好的效果。
参考文献
[1] 梁鹏.手机二维码业务研究[J].电信科学,2006;(12):36-39.
[2] 张成海,郭卫华,罗秋科.QR Code二维码——一种新型的矩阵符号[M].北京:中国标准出版社,2000.
[3] 刘宏伟,严妍.快速响应码的识别和解码[J].计算机工程与设计,2005;26(6):1560-1562.
[4] Digia Inc.Programming for the series 60 platform and symbian OS[M].Chichester:John Wiley & Sons Ltd,2003.

本站内容除特别声明的原创文章之外,转载内容只为传递更多信息,并不代表本网站赞同其观点。转载的所有的文章、图片、音/视频文件等资料的版权归版权所有权人所有。本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如涉及作品内容、版权和其它问题,请及时通过电子邮件或电话通知我们,以便迅速采取适当措施,避免给双方造成不必要的经济损失。联系电话:010-82306118;邮箱:aet@chinaaet.com。