趙建軍,朱繼珍
(昆明理工大學(xué)理學(xué)院,昆明 650500)
隨著信息需求和人民生活水平的提高,人們對(duì)電子產(chǎn)品的需求日益增高,快速的將產(chǎn)品推向市場(chǎng)是提高市場(chǎng)占有率的關(guān)鍵。嵌入式產(chǎn)品開(kāi)發(fā)周期的縮短帶來(lái)的巨大壓力,迫使嵌入式開(kāi)發(fā)人員必須不斷創(chuàng)新開(kāi)發(fā)理念。Open CV以其強(qiáng)大的圖像和矩陣運(yùn)算能力以及良好的移植性使得在視覺(jué)應(yīng)用領(lǐng)域的嵌入式產(chǎn)品有著很大的應(yīng)用潛力,目前英特爾已經(jīng)有部分Open CV視覺(jué)算法庫(kù)是針對(duì)嵌入式系統(tǒng)而開(kāi)發(fā)的,它的開(kāi)源性大大減少了開(kāi)發(fā)者的編程工作量,進(jìn)而有效提高了開(kāi)發(fā)效率和程序運(yùn)行的可靠性以及縮短了產(chǎn)品的開(kāi)發(fā)周期,它是目前作為PC軟件進(jìn)入嵌入式開(kāi)發(fā)領(lǐng)域的一個(gè)較為成功的案例。
Open CV是一個(gè)基于BSD許可證授權(quán)(開(kāi)源)發(fā)行的跨平臺(tái)計(jì)算機(jī)視覺(jué)庫(kù),采用C/C++語(yǔ)言編寫,可以運(yùn)行在Linux/Windows/Mac等操作系統(tǒng)上。實(shí)現(xiàn)了圖像處理和計(jì)算機(jī)視覺(jué)方面的很多通用算法。它的目標(biāo)是構(gòu)建一個(gè)簡(jiǎn)單易用的計(jì)算機(jī)視覺(jué)框架,以幫助開(kāi)發(fā)人員更便捷地設(shè)計(jì)更復(fù)雜的與計(jì)算機(jī)視覺(jué)相關(guān)的應(yīng)用程序,以促進(jìn)視覺(jué)研究的發(fā)展,更有效的避免“閉門造車”。Open CV包含的函數(shù)有500多個(gè),覆蓋了計(jì)算機(jī)視覺(jué)的許多應(yīng)用領(lǐng)域,如工廠產(chǎn)品檢測(cè)、醫(yī)學(xué)成像、信息安全、用戶界面、攝像頭標(biāo)定、立體視覺(jué)和機(jī)器人等。開(kāi)發(fā)者可以自由地調(diào)用函數(shù)庫(kù)中的相關(guān)處理函數(shù)。作為一個(gè)基本的計(jì)算機(jī)視覺(jué)、圖像處理和模式識(shí)別的開(kāi)源項(xiàng)目,Open CV可以直接應(yīng)用于很多領(lǐng)域,作為二次開(kāi)發(fā)的理想工具。不過(guò)在利用Open CV做商業(yè)開(kāi)發(fā)應(yīng)用前,還應(yīng)該仔細(xì)閱讀Open CV包所附帶的 PUBLIC LICENSE。由于Open CV中提供的開(kāi)源代碼針對(duì)PC平臺(tái),在移植過(guò)程中需要針對(duì)特定平臺(tái)進(jìn)行代碼優(yōu)化。
Open CV主要分為五個(gè)模塊,其中主要的四個(gè)模塊結(jié)構(gòu)如圖1所示。
圖1 Open CV結(jié)構(gòu)圖
CV模塊:包含基本的圖像處理函數(shù)和高級(jí)的計(jì)算機(jī)視覺(jué)算法。
ML:是機(jī)器學(xué)習(xí)庫(kù),包含一些基于統(tǒng)計(jì)的分類和聚類工具。
HighGUI:包含圖像和視頻的輸入/輸出函數(shù)。
CXCORE:包含了Open CV的一些基本數(shù)據(jù)結(jié)構(gòu)和相關(guān)函數(shù)。
CVAUX:該模塊一般用于存放即將被淘汰的算法和函數(shù),同時(shí)也包含一些新出現(xiàn)的實(shí)驗(yàn)性的函數(shù)和算法。
(1)硬件平臺(tái)
Xilinx的XUP Virtex-II Pro Development Board平臺(tái)提供給用戶一種類似ARM的32位處理器——PowerPC處理器(硬核)。
(2)軟件開(kāi)發(fā)環(huán)境
Xilinx的嵌入式開(kāi)發(fā)套件(Embedded Development Kit,EDK)是基于eclipse平臺(tái)而設(shè)計(jì)開(kāi)發(fā)的工具,EDK帶有許多的工具和IP,可以用來(lái)設(shè)計(jì)完整的嵌入式處理器系統(tǒng),主要包括Xilinx平臺(tái)工作室XPS和軟件開(kāi)發(fā)套件SDK。
Open CV提供實(shí)現(xiàn)基于PC平臺(tái)Adaboost人臉檢測(cè)算法的一些精簡(jiǎn)代碼,這里設(shè)計(jì)的目標(biāo)是將其移植到XUP Virtex-II Pro Development Board平臺(tái)上的POWER PC處理器上實(shí)現(xiàn)檢測(cè)功能。
首先在EDK開(kāi)發(fā)環(huán)境下配置針對(duì)Open CV人臉檢測(cè)的Power PC硬件平臺(tái),包括PowerPC處理器、PLB總線、RS232串口、DDR存儲(chǔ)器等各種外設(shè)IP。并且編譯生成BIT流文件。建立后的硬件平臺(tái)如圖2所示。
圖2 Open CV人臉檢測(cè)的Power PC硬件平臺(tái)
硬件開(kāi)發(fā)完成后,接下來(lái)就是在SDK中開(kāi)發(fā)軟 件工程,硬件設(shè)計(jì)只是建立起一個(gè)可運(yùn)行人臉檢測(cè)算法的平臺(tái),給定一個(gè)樣本集,里面包含了兩個(gè)樣本集:人臉(正樣本)和非人臉(負(fù)樣本),可以從一系列的弱分類器中構(gòu)造出一個(gè)強(qiáng)分類器,這就是所謂的boosting過(guò)程。本課題采用的就是類似boost算法的基于類Haar特征的Adaboost人臉檢測(cè)算法。Adaboost算法,就是一種級(jí)聯(lián)分類器算法,它把大量的分類能力一般的弱分類串聯(lián)起來(lái),構(gòu)成一個(gè)分類能力很強(qiáng)的強(qiáng)分類器,再將若干個(gè)強(qiáng)分類器串聯(lián)起來(lái)用來(lái)作為檢測(cè)人臉的層級(jí)級(jí)聯(lián)分類器。根據(jù)Adaboost算法,一幅圖像中的一個(gè)子區(qū)域被分類為人臉區(qū)域當(dāng)且僅當(dāng)該子區(qū)域能通過(guò)算法中所有的級(jí)聯(lián)分類器;而一個(gè)子區(qū)域能通過(guò)一個(gè)分類器僅當(dāng)該子區(qū)域在該分類器所有特征上的特征值之和大于該分類器的閾值。
人臉檢測(cè)的功能描述主要在軟件工程中完成,這里以O(shè)pen CV人臉檢測(cè)庫(kù)作為工程鏈接庫(kù),通過(guò)對(duì)人臉檢測(cè)代碼的分析,發(fā)現(xiàn)其只使用到了Open CV的三個(gè)庫(kù):CV庫(kù)、cxcore庫(kù)和highgui庫(kù)。所以直接將這三個(gè)庫(kù)放到設(shè)計(jì)的工程目錄下以便進(jìn)行編譯鏈接,需要指出的是并不是直接完全復(fù)制這些庫(kù),不同的算法在不同的嵌入式平臺(tái)上移植所需要對(duì)庫(kù)函數(shù)的裁剪是不同的,這里在Open CV提供的人臉檢測(cè)代碼基礎(chǔ)上進(jìn)行修改優(yōu)化,主要是根據(jù)VC與SDK編譯環(huán)境的差別進(jìn)行修改,這里不詳細(xì)介紹SDK開(kāi)發(fā)流程,重點(diǎn)是通過(guò)以人臉檢測(cè)移植這個(gè)例子來(lái)探索Open CV的許多視覺(jué)應(yīng)用在嵌入式平臺(tái)上的移植方法。在SDK環(huán)境下修改和優(yōu)化Open CV提供的人臉檢測(cè)代碼如圖3所示。
圖3 SDK下編寫人臉檢測(cè)代碼
編譯工程并且正確生成elf文件。
在Open CV的人臉檢測(cè)模塊中,CVHaarClassifierCascade是存儲(chǔ)人臉信息的 knowledge base;IplImage是一種存儲(chǔ)了圖像數(shù)據(jù)的內(nèi)部格式。在人臉檢測(cè)中,它們是整個(gè)程序的輸入。
目標(biāo)是把Open CV的代碼移植到Xilinx Virtex II Pro上,考慮到性能和專用的特點(diǎn),不使用操作系統(tǒng)。這樣做引發(fā)了一個(gè)問(wèn)題:不能使用OS提供的文件系統(tǒng),可供操作的是線性的內(nèi)存地址;無(wú)法使用highgui中的圖形功能,這說(shuō)明程序的輸入將是原始圖片格式,輸出是監(jiān)測(cè)區(qū)域的坐標(biāo)值。
在Open CV的PC實(shí)現(xiàn)中,CVHaarClassifierCascade通過(guò)調(diào)用CVLoad對(duì)cascade的xml文件進(jìn)行解析之后得到;這個(gè)解析的過(guò)程是復(fù)雜的,沒(méi)有必要把這部分邏輯拿到嵌入式設(shè)備上。一個(gè)好的辦法是把CVHaarClassifierCascade的內(nèi)存鏡像搬到FPGA的DRAM當(dāng)中,這樣CVHaarDetectObjects直接使用其即可。
同樣,圖片的道理也是一樣的,在PC開(kāi)發(fā)當(dāng)中,Open CV支持多種圖片文件的輸入,然后通過(guò)解析,最后變成統(tǒng)一的格式IplImage結(jié)構(gòu)。這里把IplImage結(jié)構(gòu)搬到FPGA的DRAM當(dāng)中,就省去了圖片的格式解析過(guò)程。把CVHaarClassifierCascade和IplImage這兩個(gè)結(jié)構(gòu)的鏡像寫到文件中;然后由于FPGA上的PPC是Big-endian的,而X86 PC是little endian的,再使用網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換工具將其轉(zhuǎn)換為big-endian的鏡像,這個(gè)鏡像直接下載到FPGA的DRAM當(dāng)中,就可以用強(qiáng)制類型轉(zhuǎn)換為相應(yīng)的結(jié)構(gòu)體。
CVHaarClassifierCascade內(nèi)存鏡像的生成:
結(jié)構(gòu)體定義如下:
結(jié)構(gòu)當(dāng)中有指針,這使得映射的過(guò)程變得復(fù)雜,具體就是在實(shí)現(xiàn)的時(shí)候,把外層的struct寫到file里之后,需要調(diào)用內(nèi)層struct的寫出函數(shù),直到最后到?jīng)]有指針的一個(gè)結(jié)構(gòu)。在讀入過(guò)程中也采用同樣的過(guò)程即可。讀入的時(shí)候用同樣的順序調(diào)用即可(幾乎是把write改成read就可以了)。
這個(gè)過(guò)程比較簡(jiǎn)單,把IplImage的指針里的數(shù)據(jù)dump到文件中即可:
以int為單位進(jìn)行轉(zhuǎn)換經(jīng)過(guò)以上過(guò)程生成的image.big和cascade.big就可以直接下載到內(nèi)存當(dāng)中。
軟硬件開(kāi)發(fā)完成后,將BIT文件、elf文件、被轉(zhuǎn)換后的圖片和分類器文件下載到FPGA中,利用XMP(調(diào)試POWER PC處理器命令行工具)通過(guò)命令行運(yùn)行這個(gè)系統(tǒng)。最后在超級(jí)終端上輸出人臉檢測(cè)信息即人臉的坐標(biāo)信息(見(jiàn)圖4)。
圖4 輸出人臉坐標(biāo)信息
Open CV在嵌入式平臺(tái)上的移植要點(diǎn)
(1)使用低版本的Open CV。高版本的Open CV很大程度上依賴于C++的標(biāo)準(zhǔn)模板庫(kù)(STL)容器以及GCC和C99的擴(kuò)展,不能很方便的對(duì)嵌入式進(jìn)行擴(kuò)展,所以有必要用Open CV1.1版本或者之前的版本,這些幾乎是用純C寫的。
(2)精簡(jiǎn)Open CV,使用內(nèi)聯(lián)函數(shù)。在Open CV里面有很多針對(duì)X86的低級(jí)別優(yōu)化,可以使用嵌入式平臺(tái)支持的庫(kù)以及內(nèi)聯(lián)函數(shù)替換來(lái)進(jìn)行優(yōu)化,OPEN CV的API接口支持多種數(shù)據(jù)存儲(chǔ)格式,可以采用一種來(lái)編譯出更簡(jiǎn)單高效的代碼。
(3)去除不合理的浮點(diǎn)運(yùn)算。Open CV移植的另一個(gè)挑戰(zhàn)就是浮點(diǎn)運(yùn)算。它包含了一些專門的圖像處理功能,很依賴浮點(diǎn)運(yùn)算,但是許多Open CV的圖像處理功能,從來(lái)沒(méi)有使用浮點(diǎn)運(yùn)算,而一些特別的函數(shù)涉及到 Eigen values,feature spaces,image transformation and image statistics時(shí)往往使用的是浮點(diǎn)運(yùn)算。
(4)合理安排處理結(jié)構(gòu)。低層次的預(yù)處理,比如說(shuō) color space conversions,noise reduction and statistical computation更適合FPGA或者ASIC來(lái)實(shí)現(xiàn)。
(5)對(duì)Open CV函數(shù)的內(nèi)存進(jìn)行管理。例如,一些Open CV的API經(jīng)營(yíng)單位,是最初分配一個(gè)固定大小的,后來(lái)的擴(kuò)大是為防止溢出的必要措施,其內(nèi)容的增長(zhǎng)模式為“記憶存儲(chǔ)”。在程序開(kāi)始時(shí)分配合理足夠大的內(nèi)存來(lái)減少內(nèi)存碎片和不必要的調(diào)用。
(6)直接把VC里的檢測(cè)代碼放到SDK中編譯一般會(huì)出現(xiàn)3種錯(cuò)誤,一是long long類型編譯器似乎不支持,改成long類型;二是有些包含的頭文件找不到,編譯器無(wú)法處理嵌套的頭文件包含關(guān)系,改成包含所有頭文件;三是某些空函數(shù)未定義,將空函數(shù)刪除。
論文的意義是通過(guò)研究源自O(shè)pen CV人臉檢測(cè)算法在FPGA的移植,為探索Open CV的多種視覺(jué)應(yīng)用在嵌入式處理器上的移植提供啟示。如果可以將Open CV的所有視覺(jué)應(yīng)用功能移植在目前的嵌入式產(chǎn)品中去,將大大拓展嵌入式開(kāi)發(fā)人員的設(shè)計(jì)思路。將更快速、更低成本地開(kāi)發(fā)出具有突破性性能的產(chǎn)品。而Open CV本身的功能也還在不斷發(fā)展完善當(dāng)中,這將預(yù)示Open CV在嵌入式產(chǎn)品中將有著極大的應(yīng)用潛力。
[1]Gary Bradski Adrian Kaehler.學(xué)習(xí) Open CV(中文版)[M].于仕琪,劉瑞禎,譯.北京:清華大學(xué)出版社,2009-10.
[2]華清遠(yuǎn)見(jiàn)嵌入式培訓(xùn)中心.FPGA應(yīng)用開(kāi)發(fā)入門與典型案例[M].北京:人民郵電出版社.2008-07.
[3]田耘徐,文波.Xilinx FPGA開(kāi)發(fā)實(shí)用教程[M].北京:清華大學(xué)出版社,2008-11.
[4]楊強(qiáng)浩.基于EDK的FPGA嵌入式系統(tǒng)開(kāi)發(fā)[M].北京:機(jī)械工業(yè)出版社,2008-01.
[5]田耕,胡彬,許文波,等.Xilinx_ISE_Design_Suite_10.x_FPGA開(kāi)發(fā)指南.DSP、嵌入式與高速傳輸篇[M].北京:人民郵電出版社,2008-11.
[6]齊金山.基于Open CV的人臉檢測(cè)算法研究[J].淮陰師范學(xué)院學(xué)報(bào)(自然科學(xué)版),2009,8(3):218-220.
[7]湯鋒,王進(jìn).基于分層約束的人臉局部特征檢測(cè)[C].西安:第五屆中國(guó)計(jì)算機(jī)圖形學(xué)大會(huì),2004.
[8]張國(guó)斌.FPGA開(kāi)發(fā)全攻略—工程師創(chuàng)新設(shè)計(jì)寶典電子書(上冊(cè))[M/OL].2009.2,http://icode.csdn.net/source/3051760.
[9]于仕琪,張兆翔,譯.Open CV中文參考手冊(cè)[M/OL].2010.10,http://download.csdn.net/detail/ealingwang/2995991.