嚴羽 王永眾 楊來邦
摘 要:民用領域上無人機的航拍系統(tǒng),不僅給專業(yè)工作者帶來方便,還給普通生活帶來了樂趣。本文以無人機本身自帶的圖傳系統(tǒng)為基礎通過視頻處理技術將視頻流處理后通過Android手機4G網絡實時上傳到搭建好的服務器上,同時也將無人機飛行參數(shù)一并上傳,然后通過PC端獲取服務器的視頻流數(shù)據以及飛行參數(shù),PC端通過軟件能實時顯示前方無人機拍攝的畫面以及當前無人機的飛行狀態(tài)。
關鍵詞:無人機;實時圖傳;視頻傳輸文章編號:2095-2163(2019)04-0065-06 中圖分類號:TP311.52 文獻標志碼:A
0 引 言
無人機出現(xiàn)在1917年,早期的無人駕駛飛行器的研制和應用主要用作靶機,應用范圍主要是在軍事上,后來逐漸用于作戰(zhàn)、偵察及民用遙感飛行平臺。20世紀80年代以來,隨著計算機技術、通訊技術的迅速發(fā)展以及各種數(shù)字化、重量輕、體積小、探測精度高的新型傳感器的不斷面世,無人機的性能不斷提高,應用范圍和應用領域迅速拓展。世界范圍內的各種用途、各種性能指標的無人機的類型已達數(shù)百種之多。續(xù)航時間從1 h延長到幾十個h,任務載荷從幾kg到幾百kg,這為長時間、大范圍的遙感監(jiān)測提供了保障,也為搭載多種傳感器和執(zhí)行多種任務創(chuàng)造了有利條件。
近年來,傳統(tǒng)的衛(wèi)星遙感系統(tǒng),已經不能夠滿足于高分辨率影像的需求,所以在這樣的情形之下,無人機[1]因其自身所獨有的優(yōu)勢被廣泛應用,成為了衛(wèi)星遙感系統(tǒng)檢測的補充。
無人機遙感技術可快速地對地質環(huán)境信息和過時的 GIS數(shù)據庫進行更新、修正和升級 。為政府和相關部門的行政管理、土地、地質環(huán)境治理,提供及時的技術保證。
隨著國家改革開放的逐步深入,經濟建設迅猛發(fā)展,各地區(qū)的地貌發(fā)生巨大變遷?,F(xiàn)有的航空遙感技術手段已無法適應經濟發(fā)展的需要。新的遙感技術為日益發(fā)展的經濟建設和文化事業(yè)服務。以無人駕駛飛機為空中遙感平臺的技術,是為適應這一需要而發(fā)展起來的一項新型應用性技術,能夠較好地滿足現(xiàn)階段國家對航空遙感業(yè)務的需求,對陳舊的地理資料進行更新。
目前低空無人機遙感技術在航拍、航測、國土、農業(yè)、環(huán)保、應急救災和科學研究等領域應用廣泛[2-3],無人機遙感航空技術以低速無人駕駛飛機為空中遙感平臺,用彩色、黑白、紅外、攝像技術拍攝空中影像數(shù)據;并用計算機對圖像信息加工處理。該系統(tǒng)在設計和最優(yōu)化組合方面具有突出的特點,是集成了遙感、遙控、遙測技術與計算機技術的新型應用技術。
1 無人機飛行參數(shù)獲取與圖傳系統(tǒng)
1.1 軟硬件平臺簡介
(1)大疆系列無人機一臺;
(2)搭載Android系統(tǒng)手機一臺(要帶有4 G流量卡);
(3)X86系列多核處理服務器一臺,該服務器要固定IP同時要有大容量帶寬;
(4)通用計算機一臺作為接收終端使用。
本文無人機采用大疆精靈系列無人機。該無人機搭載了6個視覺傳感器、主相機、2組紅外傳感器、1組超聲波傳感器、GPS/GLONASS雙模衛(wèi)星定位系統(tǒng)、IMU和指南針雙冗余傳感器。通過無人機的無線傳輸設備連接遙控器,遙控器一端與手機相連。無人機將拍攝到的圖像畫面以及飛行參數(shù)通過無線傳回到遙控器,手機從遙控器獲取數(shù)據并通過4G網絡傳遞到已經搭建好的服務器平臺,PC端通過網絡可以實時獲取無人機拍攝的影像以及各飛行參數(shù)。
1.2 H264視頻流簡介
H264是新一代的編碼標準,以高壓縮、高質量和支持多種網絡的流媒體傳輸著稱[4]。在H264協(xié)議里定義了3種幀:完整編碼的幀叫I幀;參考之前的I幀生成的只包含差異部分編碼的幀叫P幀;參考前后的幀編碼的幀叫B幀。 H264采用的核心算法是幀內壓縮和幀間壓縮,幀內壓縮是生成I幀的算法,幀間壓縮是生成B幀和P幀的算法。3種幀的說明:
1.2.1 I幀
I幀:幀內編碼幀。為關鍵幀,是一幀畫面的完整保留;解碼時只需要I幀就可以完成。
I幀特點:
(1)解碼時僅用I幀的數(shù)據就可重構完整圖像;
(2)I幀是P幀和B幀的參考幀;
(3)I幀是基礎幀即第一幀,在一組中只有一個I幀;
(4)幀所占數(shù)據的信息量比較大。
1.2.2 P幀
P幀:前向預測編碼幀。P幀表示的是這一幀跟之前的一個關鍵幀(或P幀)的差別,解碼時需要用之前緩存的畫面疊加上本幀定義的差別,生成最終畫面。
P幀特點:
(1)P幀是I幀后面相隔1~2幀的編碼幀;
(2)P幀采用運動補償?shù)姆椒▊魉推渑c前面的I或P幀的差值及運動矢量(預測誤差);
(3)解碼時必須將I幀中的預測值與預測誤差求和后才能重構完整的P幀圖像;
(4)P幀屬于前向預測的幀間編碼。其只參考前面最靠近其的I幀或P幀;
(5)由于P幀是參考幀,可能造成解碼錯誤的擴散。
1.2.3 B幀
B幀:雙向預測內插編碼幀。是雙向差別幀,也就是B幀記錄的是本幀與前后幀的差別。要解碼B幀,不僅要取得之前的緩存畫面,還要解碼之后的畫面,通過前后畫面與本幀數(shù)據的疊加取得最終的畫面。
B幀特點
(1)B幀是由前面的I或P幀和后面的P幀來進行預測的;
(2)B幀傳送的是其與前面的I或P幀和后面的P幀之間的預測誤差及運動矢量;
(3)B幀壓縮比最高,因為其只反映參考幀間運動主體的變化情況,預測比較準確;
H264功能分為2層:視頻編碼層面(VCL)和網絡抽象層面(NAL)。其中,前者負責有效表示視頻數(shù)據的內容,而后者負責格式化數(shù)據并提供頭信息,以保證數(shù)據適合各種信道和存儲介質上的傳輸[5]。因此每幀數(shù)據就是一個NAL單元(SPS與PPS除外)。在實際的H264數(shù)據幀中,往往幀前面帶有00 00 00 01 或 00 00 01分隔符,一般來說編碼器編出的首幀數(shù)據為PPS與SPS,接著為I幀。
通過NALU類型人們可以判斷幀類型見表1。
以00 00 00 01分割之后的下一個字節(jié)就是NALU類型,將其轉為二進制數(shù)據后:
(1)第1位禁止位,值為1表示語法出錯;
(2)第2~3位為參考級別;
(3)第4~8為是nal單元類型。
圖1所示是從無人機視頻流中截取的視頻文件,以16進制的格式打開的視頻流數(shù)據。
從劃紅線處可以看出以00 00 00 01分割之后有67 68 65 61
其中,0x67的二進制碼為:0110 0111
4-8位00111,轉為十進制7,參考表1,7對應序列參數(shù)集SPS。
其中,0x68的二進制碼為:0110 1000
4-8位01000,轉為十進制8,參考表1,8對應圖像參數(shù)集PPS。
其中,0x65的二進制碼為:0110 0101
4-8位00101,轉為十進制5,參考表1,5對應IDR圖像中的片(I幀)。
其中,0x61的二進制碼為:01100001
4-8位00001,轉為十進制1,參考表1,1對應非IDR圖像的片即非I幀,因為該幀在I幀后面則根據P幀特點可以判斷出是P幀而不可能是B幀。
H264的SPS和PPS串,包含了初始化H264解碼器所需要的信息參數(shù),包括編碼所用的profile、level、圖像的寬和高,deblock濾波器等。SPS中的信息至關重要。如果其中的數(shù)據丟失或出現(xiàn)錯誤,那么解碼過程很可能會失敗,分離H264碼流時,需要首先寫入SPS和PPS,否則會導致分離出來的數(shù)據沒有SPS、PPS而無法播放。
1.3 H264視頻流處理
手機端實時從遙控器獲取的H264視頻流是一段非常簡短且由多個或一個幀組成的流文件。如圖1所示,所做的工作就是把每一幀給分離出來。處理的方法是組建一個通道,該通道的作用是一端一直獲取傳輸過來的H264視頻流且將該視頻流的每一幀分離出來,通過管道傳輸?shù)搅硪欢?。而另一端封裝成flv的格式通過網絡發(fā)送到服務器,為保證視頻質量以及實時性,上述過程都是并行化執(zhí)行。因為實時圖傳對運行效率有較高的要求,因此上述涉及到大量運算的過程都是在c環(huán)境中運行的。
1.4 RTMP協(xié)議
本地視頻流數(shù)據需要通過流媒體協(xié)議(如RTMP、HTTP、UDP、TCP、RTP等)推送至服務器,而本文以RTMP協(xié)議推送為主。
RTMP是Real Time Messaging Protocol(實時消息傳輸協(xié)議)的首字母縮寫。該協(xié)議基于TCP,是一個協(xié)議族,包括RTMP基本協(xié)議及RTMPT/RTMPS/RTMPE等多種變種[6]。RTMP是一種設計用來進行實時數(shù)據通信的網絡協(xié)議,主要用來在Flash/AIR平臺和支持RTMP協(xié)議的流媒體/交互服務器之間進行音視頻和數(shù)據通信。支持該協(xié)議的軟件包括Adobe Media Server/Ultrant Media Server/red5等。
通過從官網下載的開源函數(shù)庫編譯后的libtrmp提供的API來進行推流,其中的RTMP協(xié)議已經封裝在相關函數(shù)中。librtmp提供的API中只需要常見的幾個API就可以將數(shù)據流推送到服務器,所需要的API如下:
RTMP_Init()//初始化結構體
RTMP_Free()
RTMP_Alloc()
RTMP_SetupURL()//設置rtmp server地址
RTMP_EnableWrite()//打開可寫選項,設定為推流狀態(tài)
RTMP_Connect()//建立NetConnection
RTMP_Close()//關閉連接
RTMP_ConnectStream()//建立NetStream
RTMP_DeleteStream()//刪除NetStream
RTMP_SendPacket()//發(fā)送數(shù)據
推流函數(shù)流程如圖2所示。
1.5 基于RTMP協(xié)議的H264推流器
通過RTMP協(xié)議將H264格式的視頻流發(fā)送到服務器中實現(xiàn)推流效果具體程序流程如圖3所示。
整個程序框圖包含4個接口函數(shù):
GetH264():獲取H264視頻流數(shù)據。
RTMPH264_Connect():建立RTMP連接。
RTMPH264_Send():發(fā)送數(shù)據。
RTMPH264_Close():關閉RTMP連接。
按照先后順序依次調用上述函數(shù)可以推流H264格式視頻流到服務器。上述4個接口函數(shù)中又包含以下函數(shù),這些函數(shù)主要功能如下:
GetH264()中包含以下函數(shù):
FilterH264():對原始視頻流過濾。
H264toMem():對接收到的H264視頻流以隊列的形式放入內存緩存中。
RTMPH264_Connect()中包含以下函數(shù):
InitSockets():初始化Socket。
RTMP_Alloc():為結構體“RTMP”分配內存。
RTMP_Init():初始化結構體“RTMP”中的成員變量。
RTMP_SetupURL():設置輸入的RTMP連接的URL。
RTMP_EnableWrite():發(fā)布流的時候必須要使用。如果不使用則代表接收流。
RTMP_Connect():建立RTMP連接,創(chuàng)建一個RTMP協(xié)議規(guī)范中的NetConnection。
RTMP_ConnectStream():創(chuàng)建一個RTMP協(xié)議規(guī)范中的NetStream。
RTMPH264_Send()中包含以下函數(shù):
ReadFirstNaluFromBuf():從內存中讀取出第一個NAL單元。
ReadOneNaluFromBuf():從內存中讀取出一個NAL單元。
H264_decode_sps():解碼SPS,獲取視頻的寬、高、幀率信息。
SendH264Packet():發(fā)送一個NAL單元。
SendH264Packet()中包含以下函數(shù):
SendVideoSpsPps():如果是關鍵幀,則在發(fā)送該幀之前先發(fā)送SPS和PPS。
SendPacket():組裝一個RTMPPacket,調用RTMP_SendPacket()發(fā)送出去。
RTMP_SendPacket():發(fā)送一個RTMP數(shù)據RTMPPacket。
RTMPH264_Close()中包含以下函數(shù):
RTMP_Close():關閉RTMP連接。
RTMP_Free():釋放結構體“RTMP”。
CleanupSockets():關閉Socket。
1.6 服務器技術
由于視頻的實時性對服務器提出較高的要求,數(shù)據傳輸時要盡量避免延遲所以選用較為成熟的nginx web服務器來接收發(fā)送過來的視頻流。
Nginx("engine x")是一款由俄羅斯程序設計師Igor Sysoev所開發(fā)高性能的 Web和反向代理服務器,也是一個 IMAP/POP3/SMTP代理服務器[7]。該服務器具有以下優(yōu)勢:
(1)Nginx使用基于事件驅動架構,使得其可以支持數(shù)以百萬級別的TCP連接。
(2)高度的模塊化和自由軟件許可證使得第三方模塊層出不窮。
(3)Nginx是一個跨平臺服務器,可以運行在Linux、 FreeBSD、 Solaris、 AIX、 Mac OS、 Windows等操作系統(tǒng)上。
最重要的一點是該服務器完全開源,可以通過自己的需要專門定制自己的需求同時該服務器具有的模塊化更易于開發(fā)和維護,這些優(yōu)秀的設計帶來的極大的穩(wěn)定性能,使得大量從事軟件開發(fā)的人員使用和維護之。
Nginx帶有的RTMP模塊使得配置該服務器變得非常簡單且高效,因此配置時只要修改nginx.conf配置文件就行,在配置文件中主要加入以下程序:
rtmp {
server {
listen 1935;
application rtmplive{
live on;
record off;
}
}
RTMP表示的是網絡傳輸RTMP協(xié)議而非HTTP協(xié)議,其中1935是監(jiān)聽端口,服務器一直監(jiān)聽該端口若有數(shù)據進來則從該端口拉取數(shù)據,獲取的數(shù)據可以存放在硬盤或內存中,本文涉及到延遲問題則直接存放在內存中。
1.7 程序流程圖及主要代碼
具體的程序流程如圖4所示。
上述流程是無人機視頻流部分,下面是關于無人機相關參數(shù)獲取過程,其中包括:高度、速度、經緯度、飛行參數(shù)等。
Aircraft aircraft = (Aircraft) DJISDKManager.getInstance().getProduct();
if(aircraft!=null){aircraft.getFlight Controller().setStateCallback(new
FlightControllerState.Callback(){
Public void onUpdate(FlightController State flightControllerState){
if (flightControllerState.getGPSSignal Level() != null) {
GPSSignalLevel gpsSignalLevel=flight ControllerState.
getGPSSignalLevel();
....}
}
});}
函數(shù)onUpdate()是獲取無人機飛行時的相關參數(shù)包括GPS信號強度、當前飛行的高度、速度、經緯度、飛行時的姿態(tài)角等。
public String SendData(String url, Wurenji express, String contentType) {
try {
vehicle = new JSONStringer().object().key("Wurenji").object()
.key("guid").value(express.guid)
.key("Site").value(express.Site)
.key("Pitch").value(express.Pitch)
.key("Yaw").value(express.Yaw)
.key("Roll").value(express.Roll)
....
.endObject();
StringEntity entity = new StringEntity(vehicle.toString(), encode);