摘 要: 詳細(xì)描述了在ARM-Linux嵌入式系統(tǒng)中移植OpenCV的方法,并在OpenCV的基礎(chǔ)上運(yùn)用Surendra算法設(shè)計(jì)了一個(gè)結(jié)合監(jiān)控和運(yùn)動(dòng)目標(biāo)跟蹤功能的網(wǎng)絡(luò)視頻監(jiān)控系統(tǒng)。
關(guān)鍵詞: 視頻監(jiān)控;ARM-Linux嵌入式系統(tǒng);OpenCV;Surendra算法
近年來(lái),公共場(chǎng)所的安全防范問(wèn)題得到了越來(lái)越多的關(guān)注,一些視頻監(jiān)控系統(tǒng)也日益重要起來(lái),。嵌入式系統(tǒng)的硬件集成化程度高,軟件采用實(shí)時(shí)多任務(wù)操作系統(tǒng)和相應(yīng)的應(yīng)用軟件,軟硬件均可裁減,。隨著大規(guī)模集成電路的發(fā)展,ARM處理器的速度也越來(lái)越快,以ARM處理器為核心的嵌入式平臺(tái)在視頻監(jiān)控方面具有很大的優(yōu)勢(shì)[1]。本文詳細(xì)描述了在ARM-Linux嵌入式系統(tǒng)中移植OpenCV的方法,并在此基礎(chǔ)上運(yùn)用Surendra算法設(shè)計(jì)了一個(gè)結(jié)合監(jiān)控和運(yùn)動(dòng)目標(biāo)跟蹤功能的網(wǎng)絡(luò)視頻監(jiān)控系統(tǒng),。
1 OpenCV簡(jiǎn)介
OpenCV是由Intel公司發(fā)起并參與開發(fā)且在近年來(lái)迅速普及的計(jì)算機(jī)視覺研究工具,是一個(gè)跨平臺(tái)的計(jì)算機(jī)視覺庫(kù)[2],。OpenCV可以在Windows、Linux以及Android等系統(tǒng)上運(yùn)行,Intel公司免費(fèi)開放該函數(shù)庫(kù)的源代碼,。OpenCV提供了非常豐富的幀提取函數(shù)和視覺處理算法,開發(fā)者可以在其視頻開發(fā)項(xiàng)目中直接調(diào)用進(jìn)行算法移植并添加自己編寫的程序,即可完成復(fù)雜龐大的開發(fā)任務(wù),達(dá)到事半功倍的效果[3],。
2 系統(tǒng)硬件構(gòu)架
系統(tǒng)基于客戶端/服務(wù)器的模式運(yùn)行。服務(wù)器采用Mini2440開發(fā)板,該開發(fā)板基于ARM9內(nèi)核,安裝了Linux-2.6.32內(nèi)核的Linux操作系統(tǒng),微處理器采用Samsung S3C2440,采用專業(yè)的CPU內(nèi)核電源芯片和復(fù)位芯片以保證系統(tǒng)的穩(wěn)定性,最高主頻為533 MHz,??蛻舳藶槠胀≒C,在PC上安裝Fedora11操作系統(tǒng)和OpenCV函數(shù)庫(kù),客戶端通過(guò)網(wǎng)絡(luò)同時(shí)接收來(lái)自多個(gè)服務(wù)器的視頻數(shù)據(jù)[4-5]。整個(gè)系統(tǒng)的硬件結(jié)構(gòu)如圖1所示,。
3 移植OpenCV函數(shù)庫(kù)
最終的目標(biāo)是要在ARM嵌入式平臺(tái)上實(shí)現(xiàn)系統(tǒng)監(jiān)控和跟蹤功能,故需要交叉編譯在ARM-Linux平臺(tái)上移植OpenCV函數(shù)庫(kù)[6],。移植過(guò)程如下:
(1)獲取OpenCV源代碼后解壓,在當(dāng)前目錄下輸入如下命令:./configure
--host=arm-linux --without-gtk
--without-carbon --without-quicktime
--without-ffmpeg --without-python
--without-swig --enable-static
--enable-share --disable-apps
CXX=arm-linux-g++ CC=arm-linux-gcc
--prefix=/usr/local/opencv
&make &make install
(2)設(shè)置環(huán)境變量:export PKG_CONFIG
_PATH=$PKG_CONFIG_PATH:/usr/local/opencv/lib/pkgconfig。編譯OpenCV源代碼自帶的例程,測(cè)試OpenCV函數(shù)庫(kù)移植是否成功,。因?yàn)樵谝浦睴penCV函數(shù)庫(kù)時(shí)沒(méi)有添加對(duì)gtk的支持,故在編譯例程drawing.c時(shí)要去掉與顯示相關(guān)的函數(shù),。使用命令:arm-linux-gcc drawing.c-o drawing′pkg-config--cflags opencv′′pkg-config--libs opencv′,生成可執(zhí)行文件drawing,。
(3)在OpenCV安裝路徑/usr/local/opencv下,把lib文件夾里的庫(kù)文件拷貝到ARM-Linux平臺(tái)的文件系統(tǒng)里。運(yùn)行可執(zhí)行文件drawing,如果在ARM-Linux平臺(tái)上成功執(zhí)行,則表示OpenCV函數(shù)庫(kù)移植成功,。
4 嵌入Surendra算法
網(wǎng)絡(luò)視頻監(jiān)控系統(tǒng)是通過(guò)攝像頭獲取圖像,對(duì)獲取到的圖像進(jìn)行處理確定運(yùn)動(dòng)目標(biāo),若發(fā)生異常情況,系統(tǒng)會(huì)自動(dòng)發(fā)出警告并啟動(dòng)錄像功能進(jìn)行錄制保存,。運(yùn)動(dòng)目標(biāo)檢測(cè)是該系統(tǒng)的核心,是實(shí)現(xiàn)運(yùn)動(dòng)目標(biāo)識(shí)別和跟蹤的基礎(chǔ)。對(duì)比各種運(yùn)動(dòng)目標(biāo)檢測(cè)算法,同時(shí)根據(jù)系統(tǒng)處理器的運(yùn)算能力,本文選用Surendra背景更新算法作為運(yùn)動(dòng)目標(biāo)的檢測(cè)算法[7],。
Surendra算法能夠自適應(yīng)地獲取背景圖像,其基本思想是通過(guò)當(dāng)前幀幀差圖像找到物體的運(yùn)動(dòng)區(qū)域,保持該區(qū)域內(nèi)的背景不變,用當(dāng)前幀更新非運(yùn)動(dòng)區(qū)域的背景,經(jīng)過(guò)迭代運(yùn)算后就可以提取出背景圖像,實(shí)現(xiàn)自動(dòng)更新[8],。Surendra算法步驟如下:
運(yùn)動(dòng)目標(biāo)的檢測(cè)就是在當(dāng)前幀圖像中提取運(yùn)動(dòng)目標(biāo),而一般情況下前景的運(yùn)動(dòng)目標(biāo)與背景的灰度值有很大的差異,但運(yùn)動(dòng)物體本身的灰度值差異一般不會(huì)很大。因此背景差分二值圖像為:
其中,Ii為當(dāng)前幀圖像,Bi為背景圖像,。差分二值圖像的灰度值為255的像素點(diǎn)可視為前景的運(yùn)動(dòng)目標(biāo)點(diǎn),。通過(guò)比較這些點(diǎn)的個(gè)數(shù)變化是否在一定的閾值內(nèi)可以判斷是否有運(yùn)動(dòng)物體進(jìn)入監(jiān)控區(qū)域。
在圖像處理中,不同類型的圖像內(nèi)部結(jié)構(gòu)不同,需要根據(jù)圖像的結(jié)構(gòu)采用不同的方法將圖像數(shù)據(jù)讀入內(nèi)存[9],。OpenCV的API函數(shù)cvCaptureFromCAM可以將圖像數(shù)據(jù)從攝像頭中加載進(jìn)來(lái),圖像結(jié)構(gòu)類型使用IplImage結(jié)構(gòu)體來(lái)表示,。cvCaptureFromCA的函數(shù)原型為:CvCapture*cvCaptureFromC AM(int index),它返回值為一個(gè)指向CvCapture結(jié)構(gòu)體的指針,然后通過(guò)調(diào)用API函數(shù)cvQueryFrame(CvCapture*capture)返回得到一個(gè)指向IplImage結(jié)構(gòu)體的指針,采集進(jìn)來(lái)的圖像信息就保存在IplImage結(jié)構(gòu)體中。IplImage結(jié)構(gòu)體的width,、height,、widthStep成員分別指示了圖像的寬像素?cái)?shù)、高像素?cái)?shù),、排列圖像的行大小,指針參數(shù)imageData指向了實(shí)際的圖像數(shù)據(jù),。圖像數(shù)據(jù)可以看作一個(gè)二維矩陣,相應(yīng)的處理可以看作對(duì)一個(gè)二維矩陣的處理,對(duì)圖像進(jìn)行嵌入Surendra算法開發(fā)主要就是對(duì)imageData指向的數(shù)據(jù)進(jìn)行操作[10]。在實(shí)際開發(fā)中,為了減輕處理器的運(yùn)算壓力,嵌入Surendra算法是以當(dāng)前幀的前4幀圖像作為背景圖像,即Ii和Ii-4分別代表當(dāng)前幀和前一幀圖像,然后依據(jù)Surendra算法原理對(duì)兩幀圖像求幀差分并進(jìn)行二值化,最終檢測(cè)出運(yùn)動(dòng)物體,。
5 客戶端/服務(wù)器設(shè)計(jì)
系統(tǒng)軟件設(shè)計(jì)采用客戶端/服務(wù)器的模式結(jié)合Linux多線程的編程方法,使整個(gè)系統(tǒng)能夠流暢地實(shí)現(xiàn)多用戶的接入和切換,。每個(gè)作為服務(wù)器的ARM嵌入式平臺(tái)上外接一個(gè)USB攝像頭,分布于監(jiān)控點(diǎn)上的多個(gè)服務(wù)器通過(guò)網(wǎng)絡(luò)連接到作為客戶端的PC上,由此構(gòu)成了整個(gè)網(wǎng)絡(luò)監(jiān)控系統(tǒng)[11]。在系統(tǒng)中使用IP地址作為服務(wù)器的編號(hào),用來(lái)區(qū)分來(lái)自于不同監(jiān)控點(diǎn)上傳送來(lái)的視頻信息,。
系統(tǒng)軟件由兩部分組成,分別是基于ARM嵌入式平臺(tái)上的服務(wù)器端和基于PC上的客戶端[12],。服務(wù)器端需要完成3個(gè)基本任務(wù),即圖像獲取、圖像處理和處理后圖像數(shù)據(jù)的網(wǎng)絡(luò)發(fā)送,。在軟件設(shè)計(jì)上,使用3個(gè)線程實(shí)現(xiàn)這3個(gè)任務(wù),在線程之間采用互斥鎖的機(jī)制對(duì)關(guān)鍵數(shù)據(jù)進(jìn)行保護(hù)和實(shí)現(xiàn)線程之間的同步,以保證系統(tǒng)的平穩(wěn),、流暢運(yùn)行。圖像獲取線程與圖像處理線程之間,、圖像處理線程與圖像發(fā)送線程之間共同維護(hù)了兩個(gè)緩沖區(qū)img1和img2,圖像數(shù)據(jù)基于流水線的模式由USB攝像頭采集進(jìn)來(lái)經(jīng)處理后再通過(guò)TCP/IP網(wǎng)絡(luò)發(fā)送出去[13-14],。服務(wù)器端的運(yùn)行機(jī)制如圖2所示。
可看到緩沖區(qū)img1和img2分別有兩個(gè)線程擁有權(quán)限對(duì)其進(jìn)行操作,如果兩個(gè)線程同時(shí)對(duì)數(shù)據(jù)進(jìn)行讀寫,就會(huì)出現(xiàn)競(jìng)爭(zhēng)現(xiàn)象,進(jìn)而破壞數(shù)據(jù)的完整性,。針對(duì)這種情況,采用了Linux互斥鎖的機(jī)制,控制程序在對(duì)緩沖區(qū)進(jìn)行讀寫操作時(shí)永遠(yuǎn)只會(huì)響應(yīng)一個(gè)線程的操作請(qǐng)求,如在圖像獲取線程與圖像處理線程之間采用如下處理:
……
data_process=0;
pthread_mutex_lock(&mutex);
……//算法處理代碼
data_process=1;
pthread_mutex_lock(&mutex);
………
運(yùn)用這樣的方法就可以對(duì)數(shù)據(jù)在特定時(shí)間進(jìn)行保護(hù),同時(shí)也可以實(shí)現(xiàn)線程之間的同步,非常有利于系統(tǒng)的流暢運(yùn)行,。圖像獲取線程每秒從USB攝像頭中采集30幀的數(shù)據(jù)。為了提高處理速度,選擇灰度圖像處理,大大減少了ARM處理器的工作量,提高了系統(tǒng)的運(yùn)行效率,。
相對(duì)于服務(wù)器端,客戶端在實(shí)現(xiàn)上簡(jiǎn)單很多,。客戶端構(gòu)建在PC上,只需要完成圖像數(shù)據(jù)的網(wǎng)絡(luò)接收和圖像顯示兩個(gè)基本任務(wù)。它們由兩個(gè)線程來(lái)實(shí)現(xiàn),兩個(gè)線程之間共同維護(hù)一個(gè)緩沖區(qū),也是采用互斥鎖的機(jī)制對(duì)數(shù)據(jù)在特定時(shí)間進(jìn)行保護(hù),。用戶通過(guò)IP地址作為編號(hào)識(shí)別不同的服務(wù)器端,在計(jì)算機(jī)上可以對(duì)關(guān)心的區(qū)域進(jìn)行實(shí)時(shí)的遠(yuǎn)程監(jiān)控和跟蹤,。
本系統(tǒng)成功地將OpenCV函數(shù)庫(kù)移植到ARM-Linux嵌入式系統(tǒng)中,并基于OpenCV函數(shù)庫(kù)和Surendra算法開發(fā)與實(shí)現(xiàn)了一個(gè)嵌入式網(wǎng)絡(luò)視頻監(jiān)控系統(tǒng)。在系統(tǒng)運(yùn)行的過(guò)程中,每秒從USB攝像頭中采集30幀的圖像數(shù)據(jù),每4幀圖像之間進(jìn)行一次算法處理,即相當(dāng)于每間隔0.13 s進(jìn)行一次Surendra算法處理,。這樣不但減輕了處理器的運(yùn)算壓力,同時(shí)也能滿足系統(tǒng)對(duì)視頻連續(xù)性與運(yùn)動(dòng)物體檢測(cè)的要求,。
參考文獻(xiàn)
[1] 陳艷華,侯安華,劉盼盼.基于ARM的嵌入式系統(tǒng)開發(fā)與實(shí)例[M].北京:人民郵電出版社,2008.
[2] Intel Corporation. OpenCV reference manual[S/OL]. (2001)[2001].http://www.intel.com.
[3] 劉瑞幀,于士琪.OpenCV教程——基礎(chǔ)篇[M].北京:北京航空航天大學(xué)出版社,2007.
[4] 周香珍,芮筱亭,張順.基于DSP的運(yùn)動(dòng)目標(biāo)跟蹤系統(tǒng)的實(shí)現(xiàn)[J].微計(jì)算機(jī)信息,2008(23):189-191.
[5] 汪愛麗,劉孟洪.基于ARM的嵌入式網(wǎng)絡(luò)監(jiān)控系統(tǒng)構(gòu)建[J].微處理機(jī),2009(5):59-60.
[6] 尹俊超,劉直芳.基于OpenCV的運(yùn)動(dòng)目標(biāo)檢測(cè)與跟蹤[J].計(jì)算機(jī)工程與設(shè)計(jì),2011,32(8):2817-2820.
[7] 汪成亮,賈亮亮.一種基于改進(jìn)Surendra背景更新算法的運(yùn)動(dòng)目標(biāo)檢測(cè)[J].世界科技研究與發(fā)展,2012,34(2):272-275.
[8] 徐方明,盧官明.基于改進(jìn)surendra背景更新算法的運(yùn)動(dòng)目標(biāo)檢測(cè)算法[J].山西電子技術(shù),2009(5):39-40,71.
[9] 阮秋琦.數(shù)字圖像處理學(xué)[M].北京:電子工業(yè)學(xué)院,2007.
[10] 賈永紅,張謙.數(shù)字圖像處理實(shí)習(xí)教程[M].武漢:武漢大學(xué)出版社,2012.
[11] 唐人財(cái),劉連浩.基于嵌入式Linux遠(yuǎn)程圖像監(jiān)控系統(tǒng)的設(shè)計(jì)[J].計(jì)算機(jī)與現(xiàn)代化,2010(11):31-34,38.
[12] 諶洪茂,徐猛華.基于嵌入式遠(yuǎn)程監(jiān)控系統(tǒng)的設(shè)計(jì)[J].計(jì)算機(jī)與現(xiàn)代化,2004(2):86-88.
[13] 方曉翠,周淵平,王小紅.嵌入式遠(yuǎn)程視頻監(jiān)控系統(tǒng)的設(shè)計(jì)[J].通信技術(shù),2011,44(10):105-108.
[14] 王秀芳,張昆,桑圣潔.基于ARM的圖像監(jiān)控系統(tǒng)的開發(fā)[J].科學(xué)技術(shù)與工程,2011,11(14):3313-3317,3321.