摘 要:當前有不少視頻監控系統是基于GSPCA開發的,它們存在不能在本地顯示視頻,缺乏移動檢測等圖像處理功能,對于存儲空間要求高,難于升級等缺點。為解決上述問題,結合Qt4和OpenCV開發了一種嵌入式視頻監控系統。該系統的硬件環境為ARM9系統,操作系統為Linux。系統不僅能夠在本地實時顯示監視畫面,還能夠根據移動檢測的結果記錄視頻,大大節省了存儲空間。系統還可以在上述檢測中加入與預設報警門限值進行比較的功能,根據比較結果決定是否報警并通過網絡將拍攝的圖像傳遞給遠端系統。達到了在本地顯示視頻,節約存儲空間,可進行移動檢測,便于升級的效果。
關鍵詞: 嵌入式視頻監控系統; 移動檢測; Qt; OpenCV
中圖分類號: TN919?34; TP33 文獻標識碼: A 文章編號: 1004?373X(2013)08?0104?05
0 引 言
隨著計算機與視頻技術的發展,人們已經可以用攝像裝置拍攝自己感興趣的圖像并保存、傳輸,比如在家庭、辦公室、停車場等場所安裝的視頻監控系統。這些場所安裝的監控系統一般要求成本低廉、具有視頻存儲和傳輸功能。使用嵌入式系統,可以實現上述目的。不過當前的很多嵌入式視頻監控系統是基于GSPCA[1]的系統。GSPCA是法國人編寫的Linux視頻驅動程序包,支持不少攝像頭,也提供了像Spacview之類的視頻錄制與傳輸程序。但基于GSPCA軟件包構建的監控系統有以下缺陷:首先,GSPCA的圖像必須先經過網絡傳到PC機上才能顯示的,如果在嵌入式系統的顯示屏上本身反而不能直接顯示;第二,GSPCA的圖像處理功能并不豐富,不能提供移動檢測等功能;第三,GSPCA的圖像格式只有MJPEG形式,等于每幀圖像都要存儲;這樣的存儲量過大,而如果使用MPEG格式,由于使用幀間壓縮,可以節省大量存儲空間;第四,缺乏移動偵測功能,因為通常視頻如果完全存儲下來即便使用MPEG格式也會占據很大的存儲空間;如果加入了移動檢測功能,在檢測到物體運動后再存儲視頻,就可以大大節省視頻文件占據的存儲容量;第五,GSPCA所提供的操作界面基本是自己編寫的,非常簡陋,較之主流的圖形化界面庫而言,缺乏對于后續開發的良好支撐,這一點嚴重阻礙了基于GSPCA產品的商業應用。另外,還有以下幾點:首先,隨著觸摸屏技術的快速發展,目前觸摸屏的成本已經很低,完全可以把觸摸屏應用于監控系統的啟動、管理和關閉,這樣可以非常方便使用者。其次,如果用戶不在現場,此監控系統還應該具備把視頻文件通過網絡發送給用戶的能力。綜上所述,在充分考慮后,基于嵌入式技術,開發出了一種成本適中、使用觸摸屏、具有視頻存儲、移動檢測和傳輸功能的視頻監控系統。該系統可以獨立應用于家庭中的實時監控,也可以用于辦公室、車場或和其他大型監控系統集成以執行大范圍的監控任務。
1 總體結構
監控系統由數字攝像設備和視頻監控終端組成。結構如圖1所示。數字攝像設備提供原始圖像數據,視頻監控終端對圖像數據進行處理,數字攝像設備與視頻監控終端的視頻數據接口相連。監控終端包括管理模塊、錄制與檢測模塊、顯示模塊、觸摸屏模塊、通信模塊。其中管理模塊具備系統管理功能,例如報警級別的設置;錄制與檢測模塊完成圖像數據壓縮、視頻錄制、差異檢測與報警任務;顯示模塊顯示當前實拍的圖像或按照不同速率播放錄制的視頻;觸摸屏模塊提供觸摸輸入并傳遞給管理模塊、錄制與檢測模塊和顯示模塊的功能;通信模塊可通過有線或無線方式傳輸報警信號和視頻文件,可以加密傳輸的數據。
本系統由軟件和硬件部分構成。硬件部分由TQ2440開發板和USB攝像頭構成。其中TQ2440開發板[2]上包括基于ARM9體系的s3c2410/2440CPU、32 MB內存、32 MB閃存、320×240點陣彩色液晶觸摸屏、USB口和以太網口。USB攝像頭為中星微ZC301攝像頭,支持常見的V4L協議。軟件部分包括linux操作系統(內核2.6)、Qt4圖形中間件、OpenCV2.0庫和自主開發的監控軟件。Linux操作系統(內核2.6)具備強大的多進程處理能力、出色的穩定性和良好的擴展性,易于安裝各種應用軟件和函數庫。Qt4圖形中間件具有豐富的圖形化工具庫,OpenCV2.0有強大的圖像處理能力。圖2為軟件系統的架構圖。
2 管理模塊設計及實現
管理模塊功能包含了攝像啟動、播放啟動、系統設置和系統退出功能。下圖為管理界面。管理模塊的開發主要是基于Qt4進行的。Qt是一個多平臺的C++圖形用戶界面應用程序框架,屬于諾基亞,現在發展到Qt4[3]。它提供給應用程序開發者建立藝術級的圖形用戶界面所需的所用功能。Qt是完全面向對象的因此很容易擴展,并且允許真正的組件編程。自從1996年早些時候Qt進入商業領域,它已經成為全世界范圍內數千種成功的應用程序的基礎,Qt不僅是流行的Linux[4]桌面環境KDE 的基礎,近年來越來越多的智能化儀表[5]、虛擬儀表[6]也開始采用Qt作為基本的圖形化操作界面。
管理模塊的主要工作流程是這樣的:用戶開啟系統后即進入主控菜單;在菜單中,選擇播放視頻、修改設置或攝像;如果是攝像,實時采集圖像并提示用戶選擇圖像保存方式究竟是比較節約空間的移動檢測方式還是常規方式;用戶選擇后開始錄制;當系統檢測到物體移動時將保存當前圖像;系統通過網絡發送出圖像文件;系統結束錄制,返回主控菜單;如果是播放,打開當前目錄,用戶可挑選需要查看的視頻文件;選中視頻文件后開始播放視頻,用戶可選擇播放視頻的速度;系統結束播放,返回主控菜單;如果是修改設置,則調整所需的系統屬性,例如背景圖案;保存修改的系統屬性到設置文件里;設置結束,返回主控菜單;用戶關閉系統退出。
管理模塊的主要流程如圖3所示。
管理模塊的部分代碼如下:
quit = new QToolButton(this); //退出功能
quit?>setText(QObject::tr(\"quit\"));
gear = new QToolButton(this); //系統設置
gear?>setText(QObject::tr(\"setup\"));
camera = new QToolButton(this); //錄制視頻
camera?>setText(QObject::tr(\"camera\"));
video = new QToolButton(this); //播放視頻
video?>setText(QObject::tr(\"play\"));
…
//界面布局
QHBoxLayout *vbuttonLayout0 = new QHBoxLayout;
QVBoxLayout *vbuttonLayout = new QVBoxLayout;
vbuttonLayout?>addWidget(camera);
vbuttonLayout?>addWidget(video);
QVBoxLayout *vbuttonLayout2 = new QVBoxLayout;
vbuttonLayout2?>addWidget(gear);
vbuttonLayout2?>addWidget(quit);
QGridLayout *mainLayout = new QGridLayout;
mainLayout?>addLayout(vbuttonLayout0,1,0);
mainLayout?>addLayout(vbuttonLayout,2,0);
mainLayout?>addLayout(vbuttonLayout2,2,1);
3 錄制與檢測模塊設計及實現
錄制與檢測模塊功能分成按常規拍攝和移動偵測拍攝兩種。后一種拍攝條件的每秒幀數低于常規拍攝,主要是考慮一些用戶可能希望長時間監視某個區域,這時若使用常規節奏拍攝就要耗費大量存儲空間,而使用移動偵測可大大節省存儲空間。
該模塊使用了OpenCV函數庫,OpenCV[7]是開放源代碼的計算機視覺類庫,由英特爾公司位于俄羅斯的研究實驗室所開發,它是可免費獲得的由一些C函數和C++類所組成的庫,用來實現常用的圖像處理及計算機視覺算法,已廣泛運用于人臉識別[8]、目標運動檢測[9] 、圖像處理[10]等領域。選用它有兩個原因:首先,OpenCV的圖像處理功能相當強大,不僅能處理圖像的格式、提供了提供移動檢測等功能;其次, OpenCV產生的視頻文件可以根據需要選擇MPEG4,MJPEG等多種壓縮格式,從壓縮機理上看,MPEG4算法由于采用插值與幀間預測,不需要壓縮每幀圖像,壓縮效果顯然好得多。綜合上述因素,選用了OpenCV。
模塊接收來自攝像頭的圖像數據。本模塊啟動后會調用函數cvCreateCameraCapture檢測攝像頭是否連接,如果檢測到攝像頭則得到一個指針,否則會報錯退出。之后的工作流程是:先調用cvQueryFrame操作此指針,再調用函數cvCreateVideoWriter指定視頻壓縮格式并獲得視頻文件指針。這樣可得到一個視頻緩沖區A,然后該緩沖區接收從USB攝像頭提取的圖像數據,如果沒有移動檢測,則該緩沖區的數據將按照選定的視頻壓縮格式以調用函數cvWriteFrame的方式被寫入視頻文件。如果有移動檢測,則調用函數motionDetect。該函數的功能如下:將A緩沖區的數據被保存到另外的緩沖區B里等待比較操作,A緩沖區繼續接收來自攝像頭的數據,A與B的數據在經過相關二值化和降噪處理后進行比較,如果比較中發現數據的不同之處已經超過預設的門限值,則把拍攝時間疊加入B緩沖區的視頻數據。此處的視頻數據記錄以調用cvWriteFrame的方式被寫入本地視頻文件。本地視頻文件的命名是按照數字升序自動產生的,因此不會覆蓋之前拍攝的視頻。操作過程如圖4所示。
錄制與檢測模塊的部分代碼如下:
capture = cvCreateCameraCapture(0); //打開攝像頭
p_current_frame = cvQueryFrame( capture ); //創建緩沖區A
if ( p_current_frame?>origin == IPL_ORIGIN_TL )
cvCopy( p_current_frame, m_opencvimg, 0 );
//創建緩沖區B
else
cvFlip( p_current_frame, m_opencvimg, 0 );
if (detect_is_needed == 1) {
//如不需要運動檢測
timeStamp(p_current_frame); //在視頻內寫入日期
cvWriteFrame(cv_writer,p_current_frame);
} else motionWrite(p_current_frame, m_opencvimg); //檢測并生成視頻
此外,當前后幀差異檢測的結果達到或超過了預設的報警門限,不僅可錄入到本地視頻文件,還可發出報警信號;同時還會將畫面再記錄入一個很短的臨時視頻文件中(例如長度為10 s),并將這個臨時視頻文件連同報警信號提交給通信模塊。該臨時視頻文件在記錄時每幅圖像都可加入年?月?日?時?分?秒格式的時間戳。臨時視頻文件的長度可以預先設置,該文件在傳輸后即被刪除以節省裝置的存儲空間。采用這種方式出于3種考慮:首先,自動發出的報警信息可以滿足迅速報警的需要,隨后發出的短長度臨時視頻文件可以提供具體的現場圖像信息;其次,上述數據量較之在網絡上傳輸整個的視頻文件可明顯降低通信帶寬,節省運行成本;最后,由于傳輸的過程耗時短,數據被截獲的概率低,安全性也有所提高。當用戶從管理界面選擇了錄制功能后,屏幕上將全屏顯示出當前采集的圖像。并在屏幕的偏下位置顯示出一組半透明的按鈕:“錄像”、“返回”和“節約/正?!薄_@是考慮到用戶可能需要隨時調整拍攝模式或停止攝像、暫停錄制:點按了“錄像”按鈕后液晶屏上的圖像會被記錄入視頻文件;點按“返回”后會中止錄制返回上級菜單;點按“節約”按鈕之后,系統僅僅在記錄到物體移動時才記錄視頻文件,且該按鈕上的字符變為“正常”,這時若再點按該按鈕,系統將按照常規速度記錄視頻文件,不再根據是否有物體移動記錄視頻。圖5為錄制與檢測模塊工作時的界面顯示。
4 顯示模塊設計及實現
顯示模塊有兩種工作模式:一種是本地實時監視模式;另一種是視頻回放模式。在本地監視模式下,本模塊啟動后也會檢測與攝像頭是否連接,如果沒有檢測到攝像頭則會報錯退出。檢測通過后,來自攝像頭的圖像被實時顯示在彩色液晶屏上。而且操作界面設計成使用戶可以在觀看監視畫面的同時能夠隨時開始錄制視頻文件或結束錄制,錄制視頻期間液晶屏實時顯示的內容不受錄制操作的任何影響。在視頻回放模式下,用戶可以在圖形化菜單中選擇以前記錄的視頻文件并播放,播放的畫面顯示在液晶屏上,播放時可以根據用戶需要隨時調整播放速度的快慢,也可以隨時暫停播放。
顯示模塊綜合使用了Qt4和OpenCV的庫函數。播放過程如下:通過Qt4提供的文件接口函數在制定路徑下找到要播放的視頻文件。在打開視頻文件前先開辟一個內存緩沖區C,將讀出的視頻數據寫入到此緩沖區內。通過在PaintEvent函數中調用函數drawImage將時間戳等字符數據寫入到視頻緩沖區C內,這一步是實現在Qt4界面內顯示圖像所必須的步驟。在這一步中還可以根據需要疊加控制按鈕到顯示畫面中。然后C緩沖區的合成視頻數據再寫入到操作系統的幀緩沖區內,過程如圖6所示。在Qt中設置好每秒寫入幀緩沖區25幀畫面,用戶就可以從液晶屏上看到連續運動的圖像了。實時顯示的過程與播放過程很相似,不同之處是圖像數據的來源從視頻文件變成了USB攝像頭。
打開視頻文件及建立緩沖區C的部分代碼如下:
capture = cvCaptureFromAVI(qPrintable(avi_file));
frame = cvQueryFrame( capture );
//創建緩沖區C
orig_img = QImage(QSize(frame?>width,frame?>height),QImage::Format_RGB888);
……
paintEvent中的相關代碼如下:
void PlayerWidget::paintEvent(QPaintEvent* e)
{
QPainter painter(this);
painter.drawImage(0,0,orig_img); //字符疊加
……
QPainter patr(this); //控制按鈕疊加
patr.drawRoundRect(PAUSE_X,BUTTON_Y,BUTTON_W,BUTTON_H);
patr.drawText(PAUSE_X+11,BUTTON_Y+20,QObject::tr(\"暫停\"));
……
}
5 通信模塊設計
通信模塊使用了socket函數,通過線程機制獨立于其他程序運行。模塊分成初始化和傳輸兩部分。在攝像模塊分配視頻緩沖區之后就初始化通信模塊。初始化過程首先以函數pthread_create啟動了一個獨立的線程,該線程調用cvCreateVideoWriter獲取被傳輸視頻文件指針,待函數正確返回指針后再建立socket連接,至此初始化過程結束。當攝像模塊檢測到物體移動后,調用cvWriteFrame在抓取的幀圖像中打上時間戳并將其存儲為臨時視頻文件,隨后向遠端服務器發送連接請求,連接建立后,通過TCP連接傳送該文件。在傳輸結束后再等待一段時間后刪除臨時文件;之后釋放視頻文件指針,釋放socket連接,最后注銷線程。
通信模塊的部分代碼如下:
//創建視頻緩沖區,保存視頻文件
snprintf(video_file_name,20,\"secondVid.avi\",);
cv_2nd_writer = cvCreateVideoWriter(video_file_name,CV_FOURCC('M','P','4','2'),8,size_2nd,1);
cvWriteFrame(cv_2nd_writer,p_current_frame);
……
//連接客戶機與服務器
connect(client_socket,(struct sockaddr*)server_addr, server_addr_length);
strncpy(buffer, video_file_name, strlen(video_file_name)>BUFFER_SIZE?BUFFER_SIZE:strlen(video_file_name));
……
//向服務器端發送視頻文件
send(client_socket,buffer,file_block_length,0)
……
//關閉套接口,釋放緩沖區
close(client_socket);
cvReleaseVideoWriter(cv_2nd_writer);
6 結 語
經過測試,證明嵌入式家用視頻監控系統達到了預期的功能:既可以按照普通速率錄制視頻并實時顯示在液晶屏上,也可以通過移動檢測方式,只記錄變化較大的圖像;可以通過圖形化界面,以觸摸方式選擇實時錄制視頻或者查看以前錄制的視頻。在移動檢測方式下,可以報警并將圖像通過網絡發送給遠端服務器。
后續的開發包括:加強移動偵測處理能力,做到能夠識別某些特征物;加入鏡頭移動功能,增大監視范圍;增添移動互聯網接口,利用手機查看視頻文件;增加視頻記錄格式,支持更多文件格式;豐富圖形化界面功能,增添報時、對講、夜光等功能。
參考文獻
[1] Linweig. GSPCA驅動移植介紹[OL].[2010?02?10]. http://blog.csdn.net/linweig/article/details/5305334.
[2] 廣州天嵌計算機科技有限公司. TQ2440開發板使用手冊[R].廣州:天嵌計算機科技有限公司,2009.
[3] 成潔,盧紫毅.Linux窗口程序設計:Qt4精彩實例分析[M]. 北京:清華大學出版社,2008.
[4] 陳莉君.Linux操作系統內核分析[M].北京:人民郵電出版社,2000.
[5] 陳卿,戴仙金,唐玉國.基于Qt/Embedded的新生兒監護儀軟件系統設計與實現[J].微計算機信息,2012,28(9):431?432.
[6] 王潤民,趙祥模,惠飛,等.基于嵌入式Linux與QT的汽車虛擬儀表設計[J].現代電子技術,2012,35(6):1?4.
[7] BRADSKI Gary, KAEHLER Adrian. Leanring OpenCV [M]. United States: O'Reilly Media, Inc., 2008.
[8] 劉靜.基于OpenCV機器視覺庫的人臉圖像預處理方法研究與實現[J].電子設計工程,2012,20(16):186?187.
[9] 劉馨,馬宏峰,王宏斌.基于OpenCV和DirectShow的交通運動目標檢測算法研究[J].華東交通大學學報,2012,29(3):21?25.
[10] 黃振峰,陳海平,鄧培,等.基于OpenCV與USB工業相機零件檢測系統的圖像處理研究[J].現代電子技術,2012,35(18):128?132.