公衍宇, 郭 琦 ,于 超
(1.河北工业大学 信息工程学院,天津 300380;2.河北工业大学 机械工程学院,天津 300380)
Android是Google开发的基于Linux平台的开源手机操作系统,本意为“机器人”。它包括操作系统、用户界面和应用程序——移动电话工作所需的全部软件,而且不存在任何以往阻碍移动产业创新的专有权障碍。OpenCV于1999年由Intel建立,现在由Willow Garage提供支持。OpenCV是一个基于BSD许可证授权(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Mac OS和Android操作系统上。它轻量级而且高效——由一系列C函数和少量C++类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉的接口,实现了图像处理和计算机视觉方面的很多通用算法[1-2]。Android应用程序是通过Android SDK(Software Develo-pment Kit)利用Java编程语言进行开发的,此虚拟机支持JNI,同时伴随着Android NDK的发布,使开发者利用第三方C/C++库协助编写Android程序成为可能,如OpenCV库便可方便地应用在Android系统中[3]。
OpenCV从2.2版本以后支持Android,本设计的编译环境PC端为ubuntu 10.10,所用OpenCV版本为2.2 1。OpenCV只提供C/C++、Python接口,这就涉及到Java与C/C++混合编程、Java程序与C/C++程序互相调用的问题,而Android NDK很好地解决了这一问题,它提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。同时还集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、等差异,开发人员只需要简单修改mk文件 (指出 “哪些文件需要编译”、“编译特性要求”等),就可以创建出so。
官方提供的Android NDK R4版本对于有些OpenCV中使用的一些C++概念不支持Cryta x为我们提供了一种支持OpenCV的Android NDK修订版。本设计Android NDK所使用的版本为android-ndk-r4-linux-cry-tax-4在开始编译安装OpenCV库之前,需要在PC机Ubuntu操作系统下安装如:cmake、buid-essential等编译OpenCV库需要用到的工具。在此环境下编译并安装OpenCV库。
OpenCV现已官方支持在Android环境下的开发,OpenCV2.2源文件包中包含一android文件夹,在此文件夹中包括一些官方提供的编译文件,利用NDK并借助这些编译文件对OpenCV源码进行编译,就可生成适用于在Android环境下运行的静态库。在编译之前需要解压缩android-ndkr4-linux-x86-crytax-4.tar.bz2,完成修订版本 NDK 的安装。 进入OpenCV2.2内的android文件夹下,执行 “mkdir build”指令,完成创建build文件夹,然后执行 “cd build”指令进入build文件夹,随后执行“cmake..”指令生成makefile编译文件,最后执行“make”指令对其进行编译,编译完成后将生成OpenCV静态库,用于在Android环境下基于OpenCV的Android应用软件开发。
在Android系统下基于OpenCV的人脸检测实现需通过Android NDK工具集将利用JNI编写的本地代码组件嵌入到Android应用程序中,所以整个实现过程分为两个步骤首先,通过JNI与OpenCV接口编写本地C/C++代码,并利用Android NDK对其进行编译生成Java可调用的共享库,接下来利用Android应用程序框架编写Java端代码,最后通过Android SDK生成Android应用程序,整体设计框架如图1所示。
图1 整体设计框架Fig.1 Overall design framework
打开 eclipse,新建一个 workspace,在 Window->Preferences中设置好Android SDK的路径。然后新建一个Android项目,Build Target选择Android2.2,命名为"facedetect",活动名改为“facedetect”,Package name 中 填 写 com.testopencv.facedetect,最后点击finish。
首先在工程目录下新建jni文件夹,新建C++源代码文件并引入此头文件,编写函数实现代码。
分类器文件与图片文件的路径分别在Java端利用String静态变量进行存储,在本地代码端需要得到此String变量的UTF-8形式用来加载分类器和图片文件,这就需要通过JNI来实现。关键代码如下:
以上代码可得到分类器的绝对路径,图片文件的存储绝对路径也可以此方式得到[4]。
人脸检测是指在输入图像中将人脸从庞杂的背景中提取出来,并返回人脸在图像中的位置、大小等信息。首先将彩色图像转换为灰度图像,然后对图像进行直方图均衡化,最后利用分类器对图像中某一区域是否为人脸进行检测。OpenCV将分类器信息利用xml文件进行存储,同时OpenCV自带分类器训练程序:haartrfimng.exe,可以使用它来方便的进行haar-like特征分类器的训练。将分类器xm l文件放在Java工程目录下的asset文件夹内,当安装应用时,利用流操作将此文件写入sd卡上的指定路径下,同时将此途径存储在一静态变量String,人脸检测函数实现关键代码如下:
检测到的人脸位置信息将会存入数据类型为vector<RECT>的faces中,最后通过迭代将检测到人脸的矩形信息分别换算成空心圆信息存入一个int数组,此空心圆信息包括圆心的x坐标、y坐标以及半径。
在C/C++端得到人脸位置信息后,需要将此信息传入Java端进行UI更新,这依然需要通过JNI来完成。在IntentService类中新建一int数组用来存放检测到的人脸位置信息,当本地人脸检测操作执行完成后对其进更新与读取,关键代码如下:
有两个脚本文件需要编写,分别是Android.mk和Application.mk文件。Android.mk文件描述了需要NDK进行编译的源文件,以及所要形成的组件,Application.mk文件描述一些关于本应用的辅助编译信息,这个编译文件是可选的。
在Java工程目录下的jni文件夹下新建Android.mk文件。 打开此文件,首先定 LOCAL_PATH:=$(call my-dir)”, 用来定位源代码文件所在目录;其次 “include$(CLEAR_VARS)”,用来清除许多LOCAL_XXX变量,因为所有编译控制文件都是在一个GNU Make执行上下文中进行解析,而此时所有变量都是全局可见的,所以需要这一操作;由于利用第三方库OpenCV协助开发,需要指定此库通过NDK编译好的静态版本的头文件、静态库文件的搜索路径与连接标记,所以编写如下如下6条语句:
最后需说明所要产生的是静态库还是动态库,由于动态库为所需,故编写如下代码:
include$(BUILD_SHARED_LIBRARY)
在Java工程目录下的jni文件夹下新建Application.mk文件,由于需要在ARM-V7构架的CPU上运行,所以通过定义“APP_ABI:=armeabi-v7a“来指定。 打开 Cygwin,进入本Android工程目录下的jni文件中,执行”$NDK/ndk-build”命令,执行完毕后将生成共享文件libface detect.so。
人脸检测的实现充分说明了在Android系统下利用OpenCV进行计算机视觉研究与开发的可行性与实用性,虽然由于Android NDK工具还处于初级发展阶段,不够成熟,以及硬件配置的差距,致使最后人脸检测操作的运行速度相对较慢,但随着NDK的发展,利用其进行编译的本地代码在Android系统中的运行将更加高效,同时越来越强大的硬件配置也将给予有力支持。Android系统如今发展迅速,许多第三方库现已提供Android通用编程接口,这为Android应用软件开发人员提供极大的便利,OpenCV也会在下一版本提供此接口,但对于计算机视觉算法研究人员以及对软件深度开发人员来说,利用JNI编写本地代码,NDK编译本地代码的方式还是必须的,并且这一方式也更加灵活。
[1]Gray Bradski,Adrian Kaebler.Learning OpenCV:Computer Vision with the OpenCV Library[M].USA:O Reilly media,2008.
[2]Willow Garage.OpenCV wiki[EB/OL].[2012-05](2012-07).http://opencv.willowgarage.com/wiki/Welcome.
[3]Google.Android Guide[EB/OL].[2012-02](2012-07).http://developer.android.com/guide/index.htm l.
[4]张莹,李勇平,敖新宇.基于OpenCV的通用人脸检测模块设计[J].计算机工程与科学,2011(1):97-101.ZHANG Ying,LI Yong-ping,AO Xin-yu.Common face detection module design based on OpenCV[J].Computer Eng ineering and Science,2011(1):97-101.
[5]韩露,李祖枢,陈东义.一种Java与OpenCV结合实现的目标检测模块[J].计算机应用,2008(3):773-775.HAN Lu,LI Zu-shu,CHEN Dong-yi.A Java and OpenCV combination of the goal detection module[J].Computer Applications,2008(3):773-775.
[6]任俊伟,林东岱.JNI技术实现跨平台开发的研究[J].计算机应用研究,2005(7):180-184.REN Jun-wei,LIN Dong-dai.JNI technology to achieve crossplatform development[J].Computer Applications Research,2005(7):180-184.
[7]陈勇飞,刘新明.基于肤色和类Harr特征的人脸图像的人脸检测[J].计算机工程与应用,2008(33):174-180.CHEN Yong-fei,LIU Xin-ming.Face images based on skin color and class Harr features face detection[J].Computer Engineering and Applications,2008(33):174-180.
[8]张靠社,张增强,杨宝杰.基于Hamilton能量函数含TCSC的电力系统非线性控制[J].陕西电力,2009(3):23-26.ZHANG Kao-she,ZHANG Zeng-qiang,YANG Bao-jie.Nonlinear control for power system with TCSC based on hamiltonian energy function[J].Shaanxi Electric Power,2009(3):23-26.
[9]孟洪波,王亚军,方涛.气相色谱法检测无水肼中水含量的不确定度评定[J].火箭推进,2011(3):68-72.MENG Hong-bo,WANG Ya-jun,FANG Tao.Uncertainty evaluation of detecting the water content in anhydrous hydrazine with gas chromatography[J].Journal of Rocket Propulsion,2011(3):68-72.