何 鹏, 王连鹏, 楚艳红
(齐齐哈尔大学通信与电子工程学院,黑龙江齐齐哈尔161006)
作为移动通信终端产品的智能手机是实现三网融合业务的重要载体,在激烈的手机市场竞争中,融合了计算机视觉技术的智能手机是提升竞争力的主要途径之一[1]。本文在基于Linux操作系统的智能手机上[2],以Intel公司的开源计算机视觉库(opensourcecomputervision,OpenCV)为基础函数库,开发了智能手机手势识别控制应用系统。对于决策部分的实现,本文以手机中音乐播放应用程序为例,实现了通过手势开启音乐播放软件的功能。本系统的基础上还可以扩展很多功能,如自拍功能,即通过手势开启手机的自拍功能,使用户摆脱了限于规定时间启动拍摄的束缚等。本系统丰富智能手机的实用功能,将大大提高了在智能手机产品中的竞争力。
随着信号处理和计算机技术的发展,利用摄像机获取数字图像,再用计算机实现对视觉信息处理的过程就是计算机视觉[3]。机器视觉则是建立在计算机视觉的基础之上,偏重于计算机视觉技术的工程化,重点在于感知环境中物体的形状、位置、姿态和运动等几何信息。一个机器视觉系统应该能够自动获得数字图像,对图像中的特征量进行处理、分析和测量,从而得到对目标物体的某种认识并做出相应的决策[4]。
OpenCV,即开放源代码计算机视觉库,是英特尔公司资助的两大图像处理利器之一,它内嵌图像处理、模式识别、三维重建、物体跟踪、机器学习和线性代数,提供了各种各样的算法。OpenCV采用C/C++语言编写,可以运行在Linux/Windows/Mac等操作系统上,OpenCV还提供了 Python、Ruby、MATLAB以及其他语言的接口。OpenCV的一个目标是构建一个简单易用的计算机视觉框架,以帮助开发人员更便捷地设计更复杂的计算机视觉相关应用程序。基本结构主要由CXCore模块、CV模块、HighGUI模块和ML模块构成[5]。
由于OpenCV采用C/C++语言编写而且都是经过优化的,所以基于OpenCV开发的程序有很高的运行效率,将它应用于机器视觉系统的开发会大幅提高系统的性能,非常适合智能手机这类嵌入式设备的性能需求[6]。
为了宿主机编译出的程序能够在目标平台ARM(advanced RISCmachines)上运行,这里需要使用ARM的交叉编译器armlinux-gcc重新编译OpenCV源码。本系统宿主机使用的Linux版本是Ubuntu 9.10,交叉编译器版本为arm-linux-gcc 2.95.3。
(1)首先需要在Ubuntu系统中安装所需的依赖库
所需的依赖库有manpages-dev、pkg-config和zlib1g-dev。
另外,还需要到http://downloads.sourceforge.net分别下载libpng、libjpeg和libz源码包进行编译安装。
(2)配置OpenCV安装信息
在终端窗口进入解压后的OpenCV目录下,运行如下配置命令:
这里使用参数--enable-static--disable-shared来生成静态库。
(3)编译、安装
sudo make
sudo make install
本系统开发测试使用ARM 9开发板,它采用Samsung公司的S3C2410微处理器,SDRAM 64MB,NAND Flash 64MB,NOR Flash 2MB,10/100M以太网口,USB接口等,系统相关的主要外设为TFT液晶屏和基于OV511芯片的USB摄像头。系统软件部分,系统引导程序Bootloader使用采用由德国DENX小组开发的U-Boot 1.1.4,Linux内核版本为2.4.18,对于液晶屏和USB摄像头的驱动以动态模块方式加载。
系统上电后直接从0x00000000处开始执行,此处是Nor Flash的起始地址,装有Bootloader系统引导程序,由于Nor Flash具有芯片内执行(execute in place)的特点,所以U-Boot的第一阶段代码直接在NorFlash中执行,首先对SDRAM、Flash大小自动检测,SDRAM的故障检测,CPU型号检测等。然后引导它的第二阶段代码到SDRAM执行,它把Linux内核引导到SDRAM执行,Linux内核程序完成自解压与重定位,最后挂载根文件系统,执行手机服务程序。系统架构图如图1所示[7]。
利用OpenCV来训练一个Haar特征[8-10]的分类器,它是一个级联的boosted分类器[11-13]。每一级的子分类器则由积分图像计算得到许多Haar特征构成,并且每个特征带一个阈值和两个分支值,每级子分类器带一个总的阈值。训练一个Haar分类器分为准备正负样本、创建正样本集和训练分类器得到训练模型。
图1 系统架构
3.1.1 样本准备
首先要建立所需的工作目录,即在home/wlp/opencv/下建立hand-defect_control目录,进入此目录,再建立img和_img目录。
(1)正样本图片及其描述文件的建立
本次实验使用了100张不同人物的同一种手势的图片,将其用图像编辑软件剪裁成长宽各20个像素大小的图片,格式为JPEG,文件名分别为 img1.jpg、img2.jpg、…img100.jpg。将它们存于hand-defect_control/img目录里。
在hand-defect_control目录下建立文本格式的描述文件,命名为info.txt,并将100张样本图片的描述信息写入此文件。其中每一个文本行对应一个样本图片的信息,每行的第一个元素是图片文件名(带路径信息),第二个元素是对象实体的个数。后面紧跟着的是与之匹配的矩形框(x,y,宽度,高度)。例如img/img1.jpg 1 0 0 20 20。
(2)负样本图片及其描述文件的建立
这里使用了200张不含手势特征的风景照片,处理为长宽各400像素大小图片,负样本图片的尺寸大小只要大于等于正样本图片尺寸即可。格式为JPEG,文件名分别为bg1.jpg、bg2.jpg、… bg100.jpg。将它们存于hand-defect_control/_img目录里。负样本描述文件的创建方法同正样本描述文件,在handdefect_control目录下建立名为bg.txt文件,将200张负样本图片的描述信息写入此文件,这里仅描述文件名即可。如_img/bg1.jpg。
3.1.2 正样本创建
正样本由opencv-createsamples程序来创建。它是OpenCV自带的可执行文件,编译安装完OpenCV后可在安装路径下bin目录下找到它。在终端窗口进入hand-defect_control目录键入如下命令:
opencv-createsamples-vec hand.vec-info info.txt-bg bg.txtnum 8-w 20-h 20
在当前目录下便生成正样本文件hand.vec,这是HaarTraining训练时所需输入的vec文件。
3.1.3 训练分类器
样本创建之后,接下来要训练分类器,这是由opencv-haartraining程序来创建,该程序同opencv-createsamples程序一样也是由OpenCV给出,并且在相同的路径下可以找到。终端命令行进入hand-defect_control目录键入如下命令:
opencv-haartraining-data/home/wlp/opencv-workshop/handdefect_control/data-vec hand.vec-bg bg.txt-npos 8-nneg 10-w 20-h 20
执行完后分类器信息将保存到xml文件中,就是当前目录下生成的data.xml文件。下面的应用程序中将调用这个分类器对输入的图像信息进行识别。
当用户开启本手势识别控制应用程序后,此应用程序使用函数 cvLoad载入上节训练的分类器文件 data.xml,再用cvCaptureFromCAM函数获取摄像头来采集视频图像,cvGrab-Frame函数可以从输入的视频流中抓取一帧图像,由于Haar特征是基于灰度的,所以cvCvtColor函数将这帧图像转换为灰度图像,这时调用cvHaarDetectObjects函数来检测目标图像,此函数首先采用与训练时同样大小的搜索窗口去遍历整幅待检测图像,窗口每移动到一个位置处,便调用一次cvRun-HaarClassifierCascade函数进行检测,计算窗口内的Haar特征,加权后与分类器中的Haar特征的阀值进行比较,由比较结果来确定是左还是右分支值,再将得到的所有分支值累加后与当前级的阀值相比较,当大于该阀值时才可以进入下一级的筛选,当通过所有级的时候即可认为此目标手势以大概率情形被命中。然后,为了搜索待检测图像中不同大小的目标手势,还要按一定的比例扩大搜索窗口(如本例采用比例系数为1.1,每次将搜索窗口扩大10%)再对待检测图像进行遍历检测。最后,当检测到目标手势时分类器输出为1,启动音乐播放应用程序或其它操作,否则进行下一帧的图像检测。程序流程图如图2所示。
图2 程序流程
在shell下,用cd命令进入手势识别控制程序的源代码hand-defect_control.c所在的目录,键入如下交叉编译的命令:
arm-linux-gcc hand-defect_control.c-static-L/usr/local/armopencv/lib-I/usr/local/arm-opencv/include-o hand-defect_control
在当前目录下便生成了 hand-defect_control.out可执行文件。由于本系统的运行环境是在嵌入式设备上,所以这里要加参数-static,用静态库链接的方式是在程序编译时就将所需的库一同编译到目标代码中,这种方式在嵌入式设备上具有很多优点,如运行速度比动态加载要快,减少对环境的依赖,使用简单等。将hand-defect_control.out加入根文件系统中,再将根文件系统下载到开发板中就可以运行了[14]。
本程序运行后抓取帧数据进行识别,以当前帧的灰度图像为例,如图3所示。图3中人物的手势即为训练Haar特征的分类器所能识别的目标,所以此帧图像应该被本程序正确识别并执行相应的决策动作。图4中的Debug Message提示的内容是为方便结果分析而在源程序中加入的若干调试信息,对这帧图像处理后便在命令提示符下输出如图4所示的信息,可见已经成功识别并启动了音乐播放程序Madplay,调试的语句使用了getpid函数获取了hand_defect_control进程及其启动的Madplay进程的进程号,分别为1752和1753。
图3 抓取帧灰度图像
图4 调试信息输出
Linux中的系统管理命令ps可以显示当前系统中的进程列表,在列表中可以找到hand_defect_control和Madplay进程的详细信息如图5所示,图中第二列既为进程的进程号,可知这两个进程号分别为1752和1753,这也正是调试信息所显示的进程号。从而说明手势识别控制程序成功检测并执行了相应的决策。
在Linux系统中能使用摄像头,仅加载此外设的驱动程序是不够的,还需要V4L(video4linux)的支持,它是Linux内核里支持影像设备的一组APIs,配合视频采集设备的驱动程序,实现影像采集、AM/FM无线广播、影像CODEC、频道切换等功能。而本系统所用OpenCV的cvCaptureFromCAM函数正是把V4L作为接口,从摄像头读取视频流分配和初始化CvCapture结构。
图5 系统进程列表输出
V4L和OV511芯片的USB摄像头驱动都可以在进入Linux源码目录进行配置、编译得到。从Linux2.4版本开始OV511驱动程序就已经是内核代码的一部分了。首先在终端运行makemenuconfig命令打开MainMenu窗口,并进入“Multimedia devices”菜单选项,将Video For Linux配置为模块;返回Main Menu窗口,再进入“USB support”菜单选项,将 USB OV511Camera support设置为模块;保存退出后用使用 make modules命令编译链接模块。这样就可以分别在Linux内核源码目录/KernelCode/2410/drivers/media/video和/KernelCode/2410/drivers/usb/文件夹中生成videodev.o模块和ov511.o模块。可以用如下命令语句进行动态加载这两个模块:
这样程序中调用cvCaptureFromCAM函数便可以获取摄像头采集图像,其中OpenCV程序中默认设备为/dev/video0[15-16]。
一般是将程序的一次执行过程称为进程。通过处于运行态的手势识别控制进程来启动一个静态的音乐播放程序使其变为进程将涉及进程控制技术。在Linux中有6个以exec开头的函数提供了在一个进程中启动另一个进程的方法,它搜索文件系统中指定路径的文件,并用它来取代原调用进程的数据段、代码段和堆栈段,这意味着原进程已经消亡了。但本系统的手势识别控制程序在成功启动音乐播放程序后,需要返回并等待执行其它扩展功能的命令,所以它不能消亡,可以把exec函数与创建进程的fork函数相结合来解决这个问题。关键代码如下:
由于fork函数得到的子进程是父进程hand_defect_control的一个复制,它复制了父进程中的代码段、数据段和堆栈段里的大部分内容,对它的消亡不会影响到父进程,所以在这个新创建的子进程中使用exevp函数调用Madplay.out音乐播放程序取代这个子进程,就不会破坏原手势识别控制进程的继续执行了[17]。
本文介绍了机器视觉技术在智能手机中应用的方法并实现了手势识别控制功能模块。从性能角度来看,此模块是基于OpenCV开发的,具有运行效率高、算法成熟稳定等优点;从功能角度来看,此模块使用手势来控制手机,而且留有功能扩展接口,满足了用户对手机多功能的需求。在激烈的智能手机市场竞争中,这种既华丽又实用的非接触式控制使用手机的方式使嵌入式Linux操作系统的智能手机大大提高了市场竞争力,具有广阔的发展前景。
[1]徐连霞.浅谈智能手机(Smart Phone)的应用与开发[J].电脑知识与技术,2009,18(33):9304-9306.
[2]吴岳.Linux C程序设计大全[M].北京:清华大学出版社,2009:7-8.
[3]张梅,文静华.浅谈计算机视觉与数字摄影测量[J].地理空间信息,2010,8(2):15-17.
[4]张广军.机器视觉[M].北京:科学出版社,2005:1-3.
[5]刘瑞祯,于仕琪.OpenCV教程-基础篇[M].北京:北京航空航天大学出版社,2007.
[6]谭学科.基于ARM和OpenCV的增强现实平台研究[D].大连:大连理工大学,2009:46-60.
[7]邱毅凌.现代嵌入式系统开发专案实务[M].北京:电子工业出版社,2009:93-105.
[8]Andrzej Kasinski,Adam Schmidt.The architecture and performance of the face and eyes detection system based on the Haar cascade classifiers[J].Pattern Analysis&Applications,2010,13(2):197-211.
[9]Seemann E,Nickel K,Stiefelhagen R.Head pose estimation using stereo vision for human-robot interaction[C].Proc of IEEE International Conference on Automatic Face and Gesture Recognition,2004:626-631.
[10]Adam Schmidt,Andrzej Kasi ski.The performance of the Haar cascade classifiers applied to the face and eyes detection[J].Computer Recognition Systems 2,2007,45:816-823.
[11]李厚君,李玉鑑.基于AdaBoost的眉毛检测与定位[J].计算机与数字工程,2010,38(8):175-177.
[12]郭磊,王秋光.Adaboost人脸检测算法研究及OpenCV实现[J].哈尔滨理工大学学报,2009,14(5):123-126.
[13]Milos Stojmenovic.Real time machine learning based car detection in images with fast training[J].Machine Vision and Applications,2006,17(3):163-172.
[14]曹志刚.基于LINUX+ARM的视频系统的应用和开发[D].北京:北方工业大学,2010:25-26.
[15]宋丽华,高珂.嵌入式Linux下USB摄像头驱动实现[J].计算机工程,2010,36(9):282-284.
[16]黄思华,杜其伟.基于MiniGUI和嵌入式Linux的PDA设计与实现[J].计算机应用,2009,29(12):207-209.
[17]胡术.UNIX平台下进程定位与运行监控的实现[J].计算机应用,2008,28(12):288-290.