朱 磊,王 鑫,劉 屹,董新華
(1.西安工程大學(xué)電子信息學(xué)院,西安 710048;2.杭州感想科技有限公司,杭州 310052)
圖像視頻信息的采集傳輸是視頻監(jiān)控系統(tǒng)中的重要組成部分,隨著經(jīng)濟(jì)的快速發(fā)展,城市規(guī)模的迅速擴(kuò)大,視頻監(jiān)控系統(tǒng)也被廣泛應(yīng)用于企業(yè)、學(xué)校、銀行、居民小區(qū)等場(chǎng)合[1-2]。隨著無線網(wǎng)絡(luò)技術(shù)的發(fā)展,圖像視頻信息的傳輸也從最初的有線傳輸變成為無線網(wǎng)絡(luò)傳輸[3]。針對(duì)自研發(fā)的電能質(zhì)量問題模擬電源系統(tǒng)的運(yùn)行狀態(tài)的實(shí)時(shí)監(jiān)測(cè),提出了一種基于樹莓派的無線WiFi(wireless fidelity)視頻采集傳輸方法。
目前,圖像視頻網(wǎng)絡(luò)傳輸?shù)姆绞街饕譃閮煞N:一是基于WiFi的無線網(wǎng)絡(luò)傳輸,使用WiFi網(wǎng)絡(luò)傳輸較為方便,許多嵌入式產(chǎn)品也可以使用無線網(wǎng)卡來連接WiFi網(wǎng)絡(luò),使用較為方便;二是基于4G的無線網(wǎng)絡(luò)傳輸,雖然網(wǎng)速較快但由于是按流量計(jì)費(fèi),對(duì)于視頻傳輸來說價(jià)格相對(duì)較貴[4]。圖像視頻網(wǎng)絡(luò)傳輸常用的嵌入式操作系統(tǒng)中有Linux、Android、wince等,由于Linux是一款開放源代碼的操作系統(tǒng)且有性能高、穩(wěn)定、內(nèi)核精簡(jiǎn)等優(yōu)點(diǎn)[5]。而樹莓派操作系統(tǒng)是Linux操作系統(tǒng),所以選用樹莓派[6-7]?;跇漭傻臒o線WiFi視頻采集傳輸方法可以分為兩種:第一種方法是基于SD卡(secure digital memory card)轉(zhuǎn)存的視頻采集傳輸方法(記作方法一),其特點(diǎn)是采用H.264視頻編碼技術(shù),將采集到的視頻先儲(chǔ)存到樹莓派的SD卡中,然后通過無線網(wǎng)絡(luò)傳輸?shù)絇C(personal computer)機(jī)上[8-9];第二種方法是基于OpenCV(open source computer vision library)的視頻采集傳輸方法(記作方法二),其特點(diǎn)是采用JPEG(joint photographic experts group)壓縮算法,將采集到的視頻進(jìn)行壓縮之后通過無線網(wǎng)絡(luò)傳輸?shù)絇C機(jī)上[10]。
針對(duì)基于樹莓派的無線WiFi視頻采集傳輸方法存在的實(shí)時(shí)性差、傳輸速率慢的問題。現(xiàn)提出一種基于樹莓派的無線WiFi視頻采集傳輸方法,該方法使用Picamera采集視頻流,并且使用并行線程來處理獲取的視頻流,壓縮JPEG格式的網(wǎng)絡(luò)視頻流,最后向PC端發(fā)送JPEG格式的網(wǎng)絡(luò)視頻流。本文方法基本解決了實(shí)時(shí)性差、傳輸速率慢的問題。提出方法與基于SD卡轉(zhuǎn)存的視頻采集傳輸方法相比,具有更好的實(shí)時(shí)性,且解決了存儲(chǔ)空間占據(jù)較大的問題;與基于OpenCV的視頻采集傳輸方法(記作方法三)相比,畫質(zhì)更加的清晰;與基于Picamera的視頻流采集傳輸方法相比,數(shù)據(jù)傳輸?shù)乃俾矢?,達(dá)到了較好的效果。
基于樹莓派的無線WiFi圖像采集傳輸模塊如圖1所示,可以分為三個(gè)部分:一是用樹莓派及官方的攝像頭,對(duì)目標(biāo)的視頻進(jìn)行采集;二是將采集到的視頻進(jìn)行傳輸;三是在PC機(jī)上顯示采集到的視頻。該方法在硬件方面由樹莓派、路由器及PC機(jī)組成,軟件部分主要為Python編寫的客戶端和服務(wù)端以及Linux系統(tǒng)的環(huán)境配置等。
圖1 樹莓派視頻采集模塊示意圖
Python編程中提供了強(qiáng)大的網(wǎng)絡(luò)編程支持,網(wǎng)絡(luò)編程中的一個(gè)基本組件是套接字(Socket)。套接字是進(jìn)程間通信的一種方式,與其他進(jìn)程間通信的主要區(qū)別在于,套接字能夠?qū)崿F(xiàn)不同主機(jī)間的進(jìn)程間通信。套接字主要分為服務(wù)器套接字和客戶端套接字??蛻舳伺c服務(wù)端各有一個(gè)Python程序,通過網(wǎng)絡(luò)連接,這些程序可以在不同的計(jì)算機(jī)通過套接字進(jìn)行通信。創(chuàng)建服務(wù)器套接字后,讓其等待連接請(qǐng)求的到來,這樣套接字將在某個(gè)網(wǎng)絡(luò)地址處監(jiān)聽,網(wǎng)絡(luò)地址就是由IP(internet protocol)地址和端口號(hào)組成的,直到客戶端套接字建立連接后,服務(wù)器端和客戶端才能進(jìn)行通信。
基于SD卡轉(zhuǎn)存的視頻采集傳輸方法的主要特點(diǎn)是先將視頻儲(chǔ)存到SD卡中然后通過套接字傳輸?shù)絇C機(jī)端。方法具體是通過Python實(shí)現(xiàn)的,首先以PC機(jī)為服務(wù)端并實(shí)現(xiàn)其功能,創(chuàng)建套接字的時(shí)候可以指定三個(gè)參數(shù):一是地址族,默認(rèn)為Socket.AF_INET;二是流套接字或者數(shù)據(jù)報(bào)套接字,因?yàn)槭褂玫氖荰CP(transmission control protocol)套接字,所以選取流套接字 Socket.SOCK_STREAM[10];三是協(xié)議,使用的時(shí)候默認(rèn)值為0。然后用函數(shù)bind綁定本地信息,用listen來監(jiān)聽特定的地址,這里監(jiān)聽的地址為客戶端地址即樹莓派的IP地址。樹莓派為客戶端并實(shí)現(xiàn)其功能,使用攝像頭采集目標(biāo)的視頻,并且先將視頻儲(chǔ)存到樹莓派的SD卡中,然后創(chuàng)建套接字,連接到服務(wù)器端。服務(wù)器端套接字監(jiān)聽到后,就可以和樹莓派客戶端進(jìn)行通信。之后再進(jìn)行數(shù)據(jù)的傳輸,在傳輸之前對(duì)傳輸?shù)囊曨l進(jìn)行打包處理,定義打包規(guī)則以及定義文件頭信息(包含文件名和文件大小),首先發(fā)送頭部信息,然后檢查正常,開始處理文件并且讀取文件數(shù)據(jù),最后由Socket提供的send()函數(shù)發(fā)送數(shù)據(jù)。在服務(wù)器端由Socket套接字提供的recv()函數(shù)首先接收客戶端發(fā)過來的頭部信息,然后解包得到的文件名和文件大小,并且處理文件名,使用strip刪除文件名中多余的空字符,最后接收文件。Python的套接字提供了兩個(gè)函數(shù):send()和recv(),通過這兩個(gè)函數(shù)可以將在樹莓派采集到的視頻傳輸?shù)絇C機(jī)上。經(jīng)過測(cè)試,這種方法將采集到的視頻儲(chǔ)存到SD卡,畫質(zhì)雖然清晰,但是實(shí)時(shí)性較差且需要的存儲(chǔ)空間較多。
基于OpenCV的視頻采集傳輸方法,其特點(diǎn)就是采集到的圖像不用儲(chǔ)存到樹莓派的SD卡中,在采集的同時(shí)可以直接把圖像發(fā)送到PC端。首先實(shí)現(xiàn)PC機(jī)的客戶端的功能,客戶端連接端口后,發(fā)送需要協(xié)商的分辨率和幀數(shù),使傳輸圖像的屬性一致,客戶端使用線程,對(duì)圖片進(jìn)行收集,對(duì)收到的每一張圖片進(jìn)行解碼,并利用OpenCV播放出來。然后實(shí)現(xiàn)樹莓派的服務(wù)器端的功能,先通過在服務(wù)器端利用OpenCV捕獲到視頻中的每一幀圖片,將這些圖片進(jìn)行壓縮成JPEG格式,以便于傳輸,按照提前協(xié)商好的分辨率和幀數(shù)進(jìn)行打包編碼傳輸,利用服務(wù)器端打開端口,在連接客戶端后,便可以在客戶端中捕獲到服務(wù)器端的每一幀圖片,即可實(shí)現(xiàn)服務(wù)器端與客戶端兩端的實(shí)時(shí)視頻傳輸。這種方法是以樹莓派為服務(wù)器端、PC機(jī)端為客戶端,由樹莓派端采集視頻后通過無線網(wǎng)絡(luò)傳輸?shù)絇C機(jī)端。具體的操作方法是在PC端建立一個(gè)Python文件,同樣的,在樹莓派端建立一個(gè)Python的文件,并設(shè)置采集分辨率為640×480,幀數(shù)設(shè)置為30。然后分別運(yùn)行兩端的Python文件,在PC機(jī)端可以得到結(jié)果??蛻舳撕头?wù)端工作流程圖如圖2所示。
圖2 客戶端和服務(wù)端流程圖
基于Picamera視頻流傳輸方法的特點(diǎn)是不用儲(chǔ)存到樹莓派的SD卡中,在緩存中可以直接把圖像視頻信息實(shí)時(shí)的發(fā)送到PC端。由于視頻的采集傳輸方法的本質(zhì)是圖片的傳輸,而不是處理圖片,如果想處理每一幀圖片,最好的方法是通過拍攝一段視頻來解碼,然后使用OpenCV模塊從視頻中獲取每一幀的圖片,或者可以將獲取到的視頻,通過OpenCV模塊將其傳輸?shù)狡渌脑O(shè)備上去處理。雖然這種方法比較方便,但因?yàn)榈玫降囊曨l圖像不清晰,所以省去了OpenCV的采集傳輸視頻的功能,用Picamera模塊來代替OpenCV模塊。通過用Picamera模塊和IO模塊的搭配使用,得到了較好的結(jié)果。由于樹莓派的IO讀寫速度優(yōu)先,其用法可以通過創(chuàng)建一個(gè)新的數(shù)據(jù)流,然后通過獨(dú)立線程來處理獲取的圖像流,通過套接字傳輸,達(dá)到實(shí)時(shí)傳輸?shù)哪康?,處理和解碼的速度都較理想,并且得到的畫質(zhì)也比較清晰。
首先實(shí)現(xiàn)樹莓派的客戶端功能,創(chuàng)建和初始化套接字,然后設(shè)置攝像頭的分辨率以及幀數(shù)并創(chuàng)建一個(gè)Socket的文件流,通過Picamera模塊中的 capture_continuous()方法設(shè)置use_video_port捕獲圖片并且將捕獲的一組圖片轉(zhuǎn)換為網(wǎng)絡(luò)數(shù)據(jù)流,最后發(fā)送JPEG格式的視頻流。在PC機(jī)服務(wù)端部分,首先創(chuàng)建和初始化套接字,接收客戶端發(fā)過來的視頻流,然后通過cv2實(shí)時(shí)顯示得到的視頻流。具體操作如下:在PC端建立一個(gè)Python文件,在樹莓派端建立Python文件,并設(shè)置采集分辨率為640×480,幀數(shù)設(shè)置為30。之后運(yùn)行PC機(jī)服務(wù)器端的Python文件以及樹莓派端的Python文件。使用這個(gè)方法,PC機(jī)端將以10 frame/s左右的速度獲取一組640×480的圖片,服務(wù)端和客戶端接收流程圖如圖3所示。
圖3 服務(wù)端和客戶端接收流程圖
基于Picamera視頻流傳輸方法雖然是實(shí)時(shí)的,但是在實(shí)時(shí)傳輸?shù)乃俾史矫姹容^慢,存在一定缺陷。因此,為了得到一個(gè)更加理想的效果,在客戶端程序加入并行線程,通過使用線程將捕獲到的視頻流傳輸?shù)椒?wù)器端,加入線程將更加高效的同時(shí)處理圖像的捕捉和傳輸,這種方法能夠達(dá)到 15 frame/s左右的速度來獲取數(shù)據(jù)流。下面對(duì)部分程序進(jìn)行說明:在樹莓派端加入并行線程,net.write(struct.pack(′ def run(self): # 這是個(gè)并行運(yùn)行的線程 while not self.terminated: # 等待圖像被寫入視頻流 if self.event.wait(1): try:with net_lk: net.write(struct.pack(’ net.flush() self.stream.seek(0) net.write(self.stream.read()) finally: self.stream.seek(0) self.stream.truncate() self.event.clear() # 將處理完的圖片加載到序列中 with pool_lk: pool.append(self) 圖4 服務(wù)端和客戶端接收流程圖 為了測(cè)試本設(shè)計(jì)的應(yīng)用性,搭建了基于樹莓派系統(tǒng)的視頻采集和傳輸?shù)臏y(cè)試平臺(tái),并且針對(duì)項(xiàng)目電能質(zhì)量問題模擬電源及測(cè)試系統(tǒng)進(jìn)行電路圖像的采集和傳輸。硬件平臺(tái)需要用到樹莓派,CSI攝像頭以及PC機(jī)。樹莓派內(nèi)的操作系統(tǒng)用的是raspbian官方系統(tǒng)及Python3、Python的編輯器,并且需要安裝cv2模塊、Picamera模塊及IO模塊,這些模塊和軟件共同構(gòu)建了樹莓派端的開發(fā)環(huán)境。攝像頭選用的是樹莓派官方提供的攝像頭,該攝像頭具有價(jià)格便宜、占用內(nèi)存少及使用方便等優(yōu)點(diǎn)。PC機(jī)使用的是Windows系統(tǒng)。在軟件平臺(tái)搭建方面,PC機(jī)上需要安裝Python、OpenCV以及環(huán)境的配置等,在這里就不再贅述了。硬件平臺(tái)如圖5所示。 圖5 測(cè)試平臺(tái) 首先在測(cè)試前需要協(xié)定采集視頻的分辨率及其幀數(shù),采集的分辨率設(shè)置為640×480,幀數(shù)設(shè)置為每秒30幀。方法一是基于SD卡轉(zhuǎn)存的視頻采集傳輸方法,此方法是先儲(chǔ)存到SD卡中,再用Socket套接字傳輸,在PC機(jī)端接收到視頻文件,并且通過第三方軟件打開視頻文件。方法二是基于OpenCV的視頻傳輸方法,此方法是把采集到的視頻的每一幀用套接字傳輸?shù)絇C機(jī)端,在PC機(jī)上接收的。方法三是基于Picamera視頻流傳輸方法,此方法是將采集到的視頻流,轉(zhuǎn)換成網(wǎng)絡(luò)視頻流傳輸?shù)絇C機(jī)端。提出的改進(jìn)后的基于Picamera視頻流傳輸方法,為了更加高效地同時(shí)處理圖像的捕捉和傳輸,使用并增加了獨(dú)立的并行線程,提高了捕獲和傳輸?shù)乃俣葟亩岣吡诵省?/p> 在PC機(jī)端接收?qǐng)D像的畫質(zhì)方面:將上述3種方法分別提取如圖6(a)上的紅色區(qū)域塊進(jìn)行清晰度比較,比較后區(qū)域效果如圖6(b)~圖6(i)所示。由圖6(b)~圖6(i)可知,方法一雖然清晰但是由于其先儲(chǔ)存再傳輸?shù)奶攸c(diǎn),實(shí)時(shí)性不好,如圖6(b)、圖6(f)所示;方法二的畫質(zhì)與其他圖的畫質(zhì)相比,清晰度較差,如圖6(c)、圖6(g)所示;方法三的畫質(zhì)比方法二好,且實(shí)時(shí)性比方法一好,如圖6(d)、圖6(h)所示;將本文方法與其余3種方法進(jìn)行比較,結(jié)果顯示本文方法比方法一的實(shí)時(shí)好,比方法二的畫質(zhì)好,且本文方法比其余3種方法的傳輸速率要高,如圖 6(e)、圖6(i)所示。 圖6 各方法的效果 針對(duì)上述方法圖像傳輸?shù)乃俾史矫嫒绫?所示:方法一是基于SD卡轉(zhuǎn)存的視頻采集傳輸方法,其圖像傳輸速率在10 frame/s左右,方法二是基于OpenCV的視頻傳輸方法,其圖像傳輸速率在 10 frame/s左右,方法三是基于Picamera視頻流傳輸方法,其圖像傳輸速率在10 frame/s左右,提出的改進(jìn)后的基于Picamera視頻流傳輸方法,對(duì)樹莓派端的程序進(jìn)行了改進(jìn),使用了獨(dú)立的并行線程,從而提高了捕獲和傳輸?shù)男?。在樹莓派端,可以檢測(cè)出傳輸速度在15 frame/s左右。由表1可知,前幾種方法改進(jìn)之前的速率均是10 frame/s左右,但是本文方法速率可以達(dá)到15 frame/s左右甚至更高,方法的傳輸速率比較理想。 為了更加直觀地比較幾種方法的區(qū)別,做了批次的速率測(cè)量,并且計(jì)算出平均值,從表1中的各個(gè)方法的視頻傳輸速率對(duì)比,可以直觀的看出方法一的速率平均值為10.63 frame/s,方法二的速率平均值為10.88 frame/s,方法三的速率平均值 10.74 frame/s,改進(jìn)后的方法的速率平均值為15.39 frame/s,由此可以得出結(jié)論,本文方法比改進(jìn)之前的傳輸速率提高了接近1.5倍。 表1 各方法的視頻傳輸速率對(duì)比 提出一種基于樹莓派的無線WiFi視頻采集傳輸方法,硬件測(cè)試平臺(tái)由樹莓派、CSI攝像頭、PC機(jī)及路由器組成的,軟件方面使用了Python、OpenCV等軟件,共同組建了視頻采集和傳輸模塊。采用三種方法與本文方法進(jìn)行比較,本文方法與基于SD卡轉(zhuǎn)存的視頻采集傳輸方法比較,具備更好的實(shí)時(shí)性;與基于OpenCV的視頻采集傳輸方法比較,畫質(zhì)更加清晰;與基于Picamera視頻流采集傳輸方法相比,傳輸速率由原來的10 fps左右增加到了15 fps左右。通過使用基于樹莓派的無線WiFi視頻采集傳輸方法對(duì)視頻進(jìn)行采集和傳輸,實(shí)現(xiàn)了視頻實(shí)時(shí)傳輸?shù)墓δ堋Mㄟ^多次修改代碼,得到了比較理想的實(shí)驗(yàn)效果。4 測(cè)試平臺(tái)搭建及測(cè)試結(jié)果
5 結(jié)論