何 鵬, 王連鵬, 楚艷紅
(齊齊哈爾大學(xué)通信與電子工程學(xué)院,黑龍江齊齊哈爾161006)
作為移動通信終端產(chǎn)品的智能手機(jī)是實現(xiàn)三網(wǎng)融合業(yè)務(wù)的重要載體,在激烈的手機(jī)市場競爭中,融合了計算機(jī)視覺技術(shù)的智能手機(jī)是提升競爭力的主要途徑之一[1]。本文在基于Linux操作系統(tǒng)的智能手機(jī)上[2],以Intel公司的開源計算機(jī)視覺庫(opensourcecomputervision,OpenCV)為基礎(chǔ)函數(shù)庫,開發(fā)了智能手機(jī)手勢識別控制應(yīng)用系統(tǒng)。對于決策部分的實現(xiàn),本文以手機(jī)中音樂播放應(yīng)用程序為例,實現(xiàn)了通過手勢開啟音樂播放軟件的功能。本系統(tǒng)的基礎(chǔ)上還可以擴(kuò)展很多功能,如自拍功能,即通過手勢開啟手機(jī)的自拍功能,使用戶擺脫了限于規(guī)定時間啟動拍攝的束縛等。本系統(tǒng)豐富智能手機(jī)的實用功能,將大大提高了在智能手機(jī)產(chǎn)品中的競爭力。
隨著信號處理和計算機(jī)技術(shù)的發(fā)展,利用攝像機(jī)獲取數(shù)字圖像,再用計算機(jī)實現(xiàn)對視覺信息處理的過程就是計算機(jī)視覺[3]。機(jī)器視覺則是建立在計算機(jī)視覺的基礎(chǔ)之上,偏重于計算機(jī)視覺技術(shù)的工程化,重點在于感知環(huán)境中物體的形狀、位置、姿態(tài)和運動等幾何信息。一個機(jī)器視覺系統(tǒng)應(yīng)該能夠自動獲得數(shù)字圖像,對圖像中的特征量進(jìn)行處理、分析和測量,從而得到對目標(biāo)物體的某種認(rèn)識并做出相應(yīng)的決策[4]。
OpenCV,即開放源代碼計算機(jī)視覺庫,是英特爾公司資助的兩大圖像處理利器之一,它內(nèi)嵌圖像處理、模式識別、三維重建、物體跟蹤、機(jī)器學(xué)習(xí)和線性代數(shù),提供了各種各樣的算法。OpenCV采用C/C++語言編寫,可以運行在Linux/Windows/Mac等操作系統(tǒng)上,OpenCV還提供了 Python、Ruby、MATLAB以及其他語言的接口。OpenCV的一個目標(biāo)是構(gòu)建一個簡單易用的計算機(jī)視覺框架,以幫助開發(fā)人員更便捷地設(shè)計更復(fù)雜的計算機(jī)視覺相關(guān)應(yīng)用程序?;窘Y(jié)構(gòu)主要由CXCore模塊、CV模塊、HighGUI模塊和ML模塊構(gòu)成[5]。
由于OpenCV采用C/C++語言編寫而且都是經(jīng)過優(yōu)化的,所以基于OpenCV開發(fā)的程序有很高的運行效率,將它應(yīng)用于機(jī)器視覺系統(tǒng)的開發(fā)會大幅提高系統(tǒng)的性能,非常適合智能手機(jī)這類嵌入式設(shè)備的性能需求[6]。
為了宿主機(jī)編譯出的程序能夠在目標(biāo)平臺ARM(advanced RISCmachines)上運行,這里需要使用ARM的交叉編譯器armlinux-gcc重新編譯OpenCV源碼。本系統(tǒng)宿主機(jī)使用的Linux版本是Ubuntu 9.10,交叉編譯器版本為arm-linux-gcc 2.95.3。
(1)首先需要在Ubuntu系統(tǒng)中安裝所需的依賴庫
所需的依賴庫有manpages-dev、pkg-config和zlib1g-dev。
另外,還需要到http://downloads.sourceforge.net分別下載libpng、libjpeg和libz源碼包進(jìn)行編譯安裝。
(2)配置OpenCV安裝信息
在終端窗口進(jìn)入解壓后的OpenCV目錄下,運行如下配置命令:
這里使用參數(shù)--enable-static--disable-shared來生成靜態(tài)庫。
(3)編譯、安裝
sudo make
sudo make install
本系統(tǒng)開發(fā)測試使用ARM 9開發(fā)板,它采用Samsung公司的S3C2410微處理器,SDRAM 64MB,NAND Flash 64MB,NOR Flash 2MB,10/100M以太網(wǎng)口,USB接口等,系統(tǒng)相關(guān)的主要外設(shè)為TFT液晶屏和基于OV511芯片的USB攝像頭。系統(tǒng)軟件部分,系統(tǒng)引導(dǎo)程序Bootloader使用采用由德國DENX小組開發(fā)的U-Boot 1.1.4,Linux內(nèi)核版本為2.4.18,對于液晶屏和USB攝像頭的驅(qū)動以動態(tài)模塊方式加載。
系統(tǒng)上電后直接從0x00000000處開始執(zhí)行,此處是Nor Flash的起始地址,裝有Bootloader系統(tǒng)引導(dǎo)程序,由于Nor Flash具有芯片內(nèi)執(zhí)行(execute in place)的特點,所以U-Boot的第一階段代碼直接在NorFlash中執(zhí)行,首先對SDRAM、Flash大小自動檢測,SDRAM的故障檢測,CPU型號檢測等。然后引導(dǎo)它的第二階段代碼到SDRAM執(zhí)行,它把Linux內(nèi)核引導(dǎo)到SDRAM執(zhí)行,Linux內(nèi)核程序完成自解壓與重定位,最后掛載根文件系統(tǒng),執(zhí)行手機(jī)服務(wù)程序。系統(tǒng)架構(gòu)圖如圖1所示[7]。
利用OpenCV來訓(xùn)練一個Haar特征[8-10]的分類器,它是一個級聯(lián)的boosted分類器[11-13]。每一級的子分類器則由積分圖像計算得到許多Haar特征構(gòu)成,并且每個特征帶一個閾值和兩個分支值,每級子分類器帶一個總的閾值。訓(xùn)練一個Haar分類器分為準(zhǔn)備正負(fù)樣本、創(chuàng)建正樣本集和訓(xùn)練分類器得到訓(xùn)練模型。
圖1 系統(tǒng)架構(gòu)
3.1.1 樣本準(zhǔn)備
首先要建立所需的工作目錄,即在home/wlp/opencv/下建立hand-defect_control目錄,進(jìn)入此目錄,再建立img和_img目錄。
(1)正樣本圖片及其描述文件的建立
本次實驗使用了100張不同人物的同一種手勢的圖片,將其用圖像編輯軟件剪裁成長寬各20個像素大小的圖片,格式為JPEG,文件名分別為 img1.jpg、img2.jpg、…img100.jpg。將它們存于hand-defect_control/img目錄里。
在hand-defect_control目錄下建立文本格式的描述文件,命名為info.txt,并將100張樣本圖片的描述信息寫入此文件。其中每一個文本行對應(yīng)一個樣本圖片的信息,每行的第一個元素是圖片文件名(帶路徑信息),第二個元素是對象實體的個數(shù)。后面緊跟著的是與之匹配的矩形框(x,y,寬度,高度)。例如img/img1.jpg 1 0 0 20 20。
(2)負(fù)樣本圖片及其描述文件的建立
這里使用了200張不含手勢特征的風(fēng)景照片,處理為長寬各400像素大小圖片,負(fù)樣本圖片的尺寸大小只要大于等于正樣本圖片尺寸即可。格式為JPEG,文件名分別為bg1.jpg、bg2.jpg、… bg100.jpg。將它們存于hand-defect_control/_img目錄里。負(fù)樣本描述文件的創(chuàng)建方法同正樣本描述文件,在handdefect_control目錄下建立名為bg.txt文件,將200張負(fù)樣本圖片的描述信息寫入此文件,這里僅描述文件名即可。如_img/bg1.jpg。
3.1.2 正樣本創(chuàng)建
正樣本由opencv-createsamples程序來創(chuàng)建。它是OpenCV自帶的可執(zhí)行文件,編譯安裝完OpenCV后可在安裝路徑下bin目錄下找到它。在終端窗口進(jìn)入hand-defect_control目錄鍵入如下命令:
opencv-createsamples-vec hand.vec-info info.txt-bg bg.txtnum 8-w 20-h 20
在當(dāng)前目錄下便生成正樣本文件hand.vec,這是HaarTraining訓(xùn)練時所需輸入的vec文件。
3.1.3 訓(xùn)練分類器
樣本創(chuàng)建之后,接下來要訓(xùn)練分類器,這是由opencv-haartraining程序來創(chuàng)建,該程序同opencv-createsamples程序一樣也是由OpenCV給出,并且在相同的路徑下可以找到。終端命令行進(jìn)入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
執(zhí)行完后分類器信息將保存到xml文件中,就是當(dāng)前目錄下生成的data.xml文件。下面的應(yīng)用程序中將調(diào)用這個分類器對輸入的圖像信息進(jìn)行識別。
當(dāng)用戶開啟本手勢識別控制應(yīng)用程序后,此應(yīng)用程序使用函數(shù) cvLoad載入上節(jié)訓(xùn)練的分類器文件 data.xml,再用cvCaptureFromCAM函數(shù)獲取攝像頭來采集視頻圖像,cvGrab-Frame函數(shù)可以從輸入的視頻流中抓取一幀圖像,由于Haar特征是基于灰度的,所以cvCvtColor函數(shù)將這幀圖像轉(zhuǎn)換為灰度圖像,這時調(diào)用cvHaarDetectObjects函數(shù)來檢測目標(biāo)圖像,此函數(shù)首先采用與訓(xùn)練時同樣大小的搜索窗口去遍歷整幅待檢測圖像,窗口每移動到一個位置處,便調(diào)用一次cvRun-HaarClassifierCascade函數(shù)進(jìn)行檢測,計算窗口內(nèi)的Haar特征,加權(quán)后與分類器中的Haar特征的閥值進(jìn)行比較,由比較結(jié)果來確定是左還是右分支值,再將得到的所有分支值累加后與當(dāng)前級的閥值相比較,當(dāng)大于該閥值時才可以進(jìn)入下一級的篩選,當(dāng)通過所有級的時候即可認(rèn)為此目標(biāo)手勢以大概率情形被命中。然后,為了搜索待檢測圖像中不同大小的目標(biāo)手勢,還要按一定的比例擴(kuò)大搜索窗口(如本例采用比例系數(shù)為1.1,每次將搜索窗口擴(kuò)大10%)再對待檢測圖像進(jìn)行遍歷檢測。最后,當(dāng)檢測到目標(biāo)手勢時分類器輸出為1,啟動音樂播放應(yīng)用程序或其它操作,否則進(jìn)行下一幀的圖像檢測。程序流程圖如圖2所示。
圖2 程序流程
在shell下,用cd命令進(jìn)入手勢識別控制程序的源代碼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
在當(dāng)前目錄下便生成了 hand-defect_control.out可執(zhí)行文件。由于本系統(tǒng)的運行環(huán)境是在嵌入式設(shè)備上,所以這里要加參數(shù)-static,用靜態(tài)庫鏈接的方式是在程序編譯時就將所需的庫一同編譯到目標(biāo)代碼中,這種方式在嵌入式設(shè)備上具有很多優(yōu)點,如運行速度比動態(tài)加載要快,減少對環(huán)境的依賴,使用簡單等。將hand-defect_control.out加入根文件系統(tǒng)中,再將根文件系統(tǒng)下載到開發(fā)板中就可以運行了[14]。
本程序運行后抓取幀數(shù)據(jù)進(jìn)行識別,以當(dāng)前幀的灰度圖像為例,如圖3所示。圖3中人物的手勢即為訓(xùn)練Haar特征的分類器所能識別的目標(biāo),所以此幀圖像應(yīng)該被本程序正確識別并執(zhí)行相應(yīng)的決策動作。圖4中的Debug Message提示的內(nèi)容是為方便結(jié)果分析而在源程序中加入的若干調(diào)試信息,對這幀圖像處理后便在命令提示符下輸出如圖4所示的信息,可見已經(jīng)成功識別并啟動了音樂播放程序Madplay,調(diào)試的語句使用了getpid函數(shù)獲取了hand_defect_control進(jìn)程及其啟動的Madplay進(jìn)程的進(jìn)程號,分別為1752和1753。
圖3 抓取幀灰度圖像
圖4 調(diào)試信息輸出
Linux中的系統(tǒng)管理命令ps可以顯示當(dāng)前系統(tǒng)中的進(jìn)程列表,在列表中可以找到hand_defect_control和Madplay進(jìn)程的詳細(xì)信息如圖5所示,圖中第二列既為進(jìn)程的進(jìn)程號,可知這兩個進(jìn)程號分別為1752和1753,這也正是調(diào)試信息所顯示的進(jìn)程號。從而說明手勢識別控制程序成功檢測并執(zhí)行了相應(yīng)的決策。
在Linux系統(tǒng)中能使用攝像頭,僅加載此外設(shè)的驅(qū)動程序是不夠的,還需要V4L(video4linux)的支持,它是Linux內(nèi)核里支持影像設(shè)備的一組APIs,配合視頻采集設(shè)備的驅(qū)動程序,實現(xiàn)影像采集、AM/FM無線廣播、影像CODEC、頻道切換等功能。而本系統(tǒng)所用OpenCV的cvCaptureFromCAM函數(shù)正是把V4L作為接口,從攝像頭讀取視頻流分配和初始化CvCapture結(jié)構(gòu)。
圖5 系統(tǒng)進(jìn)程列表輸出
V4L和OV511芯片的USB攝像頭驅(qū)動都可以在進(jìn)入Linux源碼目錄進(jìn)行配置、編譯得到。從Linux2.4版本開始OV511驅(qū)動程序就已經(jīng)是內(nèi)核代碼的一部分了。首先在終端運行makemenuconfig命令打開MainMenu窗口,并進(jìn)入“Multimedia devices”菜單選項,將Video For Linux配置為模塊;返回Main Menu窗口,再進(jìn)入“USB support”菜單選項,將 USB OV511Camera support設(shè)置為模塊;保存退出后用使用 make modules命令編譯鏈接模塊。這樣就可以分別在Linux內(nèi)核源碼目錄/KernelCode/2410/drivers/media/video和/KernelCode/2410/drivers/usb/文件夾中生成videodev.o模塊和ov511.o模塊??梢杂萌缦旅钫Z句進(jìn)行動態(tài)加載這兩個模塊:
這樣程序中調(diào)用cvCaptureFromCAM函數(shù)便可以獲取攝像頭采集圖像,其中OpenCV程序中默認(rèn)設(shè)備為/dev/video0[15-16]。
一般是將程序的一次執(zhí)行過程稱為進(jìn)程。通過處于運行態(tài)的手勢識別控制進(jìn)程來啟動一個靜態(tài)的音樂播放程序使其變?yōu)檫M(jìn)程將涉及進(jìn)程控制技術(shù)。在Linux中有6個以exec開頭的函數(shù)提供了在一個進(jìn)程中啟動另一個進(jìn)程的方法,它搜索文件系統(tǒng)中指定路徑的文件,并用它來取代原調(diào)用進(jìn)程的數(shù)據(jù)段、代碼段和堆棧段,這意味著原進(jìn)程已經(jīng)消亡了。但本系統(tǒng)的手勢識別控制程序在成功啟動音樂播放程序后,需要返回并等待執(zhí)行其它擴(kuò)展功能的命令,所以它不能消亡,可以把exec函數(shù)與創(chuàng)建進(jìn)程的fork函數(shù)相結(jié)合來解決這個問題。關(guān)鍵代碼如下:
由于fork函數(shù)得到的子進(jìn)程是父進(jìn)程hand_defect_control的一個復(fù)制,它復(fù)制了父進(jìn)程中的代碼段、數(shù)據(jù)段和堆棧段里的大部分內(nèi)容,對它的消亡不會影響到父進(jìn)程,所以在這個新創(chuàng)建的子進(jìn)程中使用exevp函數(shù)調(diào)用Madplay.out音樂播放程序取代這個子進(jìn)程,就不會破壞原手勢識別控制進(jìn)程的繼續(xù)執(zhí)行了[17]。
本文介紹了機(jī)器視覺技術(shù)在智能手機(jī)中應(yīng)用的方法并實現(xiàn)了手勢識別控制功能模塊。從性能角度來看,此模塊是基于OpenCV開發(fā)的,具有運行效率高、算法成熟穩(wěn)定等優(yōu)點;從功能角度來看,此模塊使用手勢來控制手機(jī),而且留有功能擴(kuò)展接口,滿足了用戶對手機(jī)多功能的需求。在激烈的智能手機(jī)市場競爭中,這種既華麗又實用的非接觸式控制使用手機(jī)的方式使嵌入式Linux操作系統(tǒng)的智能手機(jī)大大提高了市場競爭力,具有廣闊的發(fā)展前景。
[1]徐連霞.淺談智能手機(jī)(Smart Phone)的應(yīng)用與開發(fā)[J].電腦知識與技術(shù),2009,18(33):9304-9306.
[2]吳岳.Linux C程序設(shè)計大全[M].北京:清華大學(xué)出版社,2009:7-8.
[3]張梅,文靜華.淺談計算機(jī)視覺與數(shù)字?jǐn)z影測量[J].地理空間信息,2010,8(2):15-17.
[4]張廣軍.機(jī)器視覺[M].北京:科學(xué)出版社,2005:1-3.
[5]劉瑞禎,于仕琪.OpenCV教程-基礎(chǔ)篇[M].北京:北京航空航天大學(xué)出版社,2007.
[6]譚學(xué)科.基于ARM和OpenCV的增強(qiáng)現(xiàn)實平臺研究[D].大連:大連理工大學(xué),2009:46-60.
[7]邱毅凌.現(xiàn)代嵌入式系統(tǒng)開發(fā)專案實務(wù)[M].北京:電子工業(yè)出版社,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].計算機(jī)與數(shù)字工程,2010,38(8):175-177.
[12]郭磊,王秋光.Adaboost人臉檢測算法研究及OpenCV實現(xiàn)[J].哈爾濱理工大學(xué)學(xué)報,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的視頻系統(tǒng)的應(yīng)用和開發(fā)[D].北京:北方工業(yè)大學(xué),2010:25-26.
[15]宋麗華,高珂.嵌入式Linux下USB攝像頭驅(qū)動實現(xiàn)[J].計算機(jī)工程,2010,36(9):282-284.
[16]黃思華,杜其偉.基于MiniGUI和嵌入式Linux的PDA設(shè)計與實現(xiàn)[J].計算機(jī)應(yīng)用,2009,29(12):207-209.
[17]胡術(shù).UNIX平臺下進(jìn)程定位與運行監(jiān)控的實現(xiàn)[J].計算機(jī)應(yīng)用,2008,28(12):288-290.