免備案空間哪家好寧波seo服務(wù)推廣
目錄
- 1、前言
- 版本更新說(shuō)明
- 免責(zé)聲明
- 2、我已有的FPGA視頻拼接疊加融合方案
- 3、設(shè)計(jì)思路框架
- 視頻源選擇
- OV5640攝像頭配置及采集
- 靜態(tài)彩條
- 視頻拼接算法
- 圖像緩存
- 視頻輸出
- 4、vivado工程詳解
- 5、工程移植說(shuō)明
- vivado版本不一致處理
- FPGA型號(hào)不一致處理
- 其他注意事項(xiàng)
- 6、上板調(diào)試驗(yàn)證并演示
- 靜態(tài)演示
- 動(dòng)態(tài)演示
- 7、福利:工程源碼獲取
1、前言
沒(méi)玩過(guò)圖像拼接都不好意思說(shuō)自己玩兒過(guò)FPGA,這是CSDN某大佬說(shuō)過(guò)的一句話,鄙人深信不疑。。。
圖像拼接在實(shí)際項(xiàng)目中應(yīng)用廣泛,特別是在醫(yī)療和軍工行業(yè),目前市面上的圖像拼接方案主要有Xilinx官方推出的Video Mixer方案和自己手撕代碼的自定義方案;Xilinx官方推出的Video Mixer方案直接調(diào)用IP,通過(guò)SDK配置即可實(shí)現(xiàn),但他的使能難度較高,且對(duì)FPGA資源要求也很高,不太適合小規(guī)模FPGA,在zynq和K7以上平臺(tái)倒是很使用,如果對(duì)Video Mixer方案感興趣,可以參考我之前的博客,博客地址:
點(diǎn)擊直接前往
本文使用Xilinx的Kintex7 FPGA純verilog代碼實(shí)現(xiàn)8路視頻圖像拼接,視頻源有兩種,分別對(duì)應(yīng)開(kāi)發(fā)者手里有沒(méi)有攝像頭的情況,一種是使用廉價(jià)的OV5640攝像頭模組;如果你得手里沒(méi)有攝像頭,或者你得開(kāi)發(fā)板沒(méi)有攝像頭接口,則可使用代碼內(nèi)部生成的靜態(tài)彩條模擬攝像頭視頻;視頻源的選擇通過(guò)代碼頂層的`define宏定義進(jìn)行,默認(rèn)使用ov5640作為視頻源;由于我的手里只有一個(gè)攝像頭,所以fpga采集攝像頭數(shù)據(jù)后,直接復(fù)制多份,用來(lái)模擬多路攝像頭輸入;使用我常用的FDMA方案實(shí)現(xiàn)圖像的三幀緩存,不同的視頻緩存在DDR3中不同的地址,讀視頻時(shí)一次性將視頻緩存區(qū)域讀完,從而實(shí)現(xiàn)視頻拼接的功能;輸出視頻分辨率為1920x1080,實(shí)現(xiàn)8路視頻拼接,所以每路視頻的分辨率就為480x540,這樣剛好8路視頻占滿輸出屏幕,看起來(lái)美觀一些;讀出視頻后,用純verilog顯示的HDMI輸出模塊送顯示器顯示即可;
本博客詳細(xì)描述了FPGA純verilog實(shí)現(xiàn)視頻拼接的設(shè)計(jì)方案,工程代碼可綜合編譯上板調(diào)試,可直接項(xiàng)目移植,適用于在校學(xué)生、研究生項(xiàng)目開(kāi)發(fā),也適用于在職工程師做學(xué)習(xí)提升,可應(yīng)用于醫(yī)療、軍工等行業(yè)的高速接口或圖像處理領(lǐng)域;
提供完整的、跑通的工程源碼和技術(shù)支持;
工程源碼和技術(shù)支持的獲取方式放在了文章末尾,請(qǐng)耐心看到最后;
版本更新說(shuō)明
此版本為第2版,根據(jù)讀者的建議,對(duì)第1版工程做了如下改進(jìn)和更新:
1:增加了輸入視頻靜態(tài)彩條的選擇,有的讀者說(shuō)他手里沒(méi)有OV5640攝像頭或者攝像頭原理圖和我的不一致,導(dǎo)致在移植過(guò)程中困難很大,基于此,增加了靜態(tài)彩條,它由FPGA內(nèi)部產(chǎn)生,不需要外接攝像頭就可以使用,使用方法在后文有說(shuō)明;
2:優(yōu)化了FDMA,之前的FDMA內(nèi)AXI4的數(shù)據(jù)讀寫(xiě)突發(fā)長(zhǎng)度為256,導(dǎo)致在低端FPGA上帶寬不夠,從而圖像質(zhì)量不佳,基于此,將FDMA內(nèi)AXI4的數(shù)據(jù)讀寫(xiě)突發(fā)長(zhǎng)度改為128;
3:優(yōu)化了HDMI輸出模塊,之前用的自定義IP,有讀者說(shuō)IP無(wú)法更新,雖能正常使用,但看源碼不方便,基于此,將HDMI輸出模塊改為純verilog實(shí)現(xiàn)的,直接了當(dāng);
免責(zé)聲明
本工程及其源碼即有自己寫(xiě)的一部分,也有網(wǎng)絡(luò)公開(kāi)渠道獲取的一部分(包括CSDN、Xilinx官網(wǎng)、Altera官網(wǎng)等等),若大佬們覺(jué)得有所冒犯,請(qǐng)私信批評(píng)教育;基于此,本工程及其源碼僅限于讀者或粉絲個(gè)人學(xué)習(xí)和研究,禁止用于商業(yè)用途,若由于讀者或粉絲自身原因用于商業(yè)用途所導(dǎo)致的法律問(wèn)題,與本博客及博主無(wú)關(guān),請(qǐng)謹(jǐn)慎使用。。。
2、我已有的FPGA視頻拼接疊加融合方案
我的主頁(yè)目前有FPGA視頻拼接疊加融合專欄,改專欄收錄了我目前手里已有的FPGA視頻拼接疊加融合方案,從實(shí)現(xiàn)方式分類有基于HSL實(shí)現(xiàn)的視頻拼接、基于純verilog代碼實(shí)現(xiàn)的視頻拼接;從應(yīng)用上分為單路、2路、3路、4路、8路、16路視頻拼接;視頻縮放+拼接;視頻融合疊加;從輸入視頻分類可分為OV5640攝像頭視頻拼接、SDI視頻拼接、CameraLink視頻拼接等等;以下是專欄地址:
點(diǎn)擊直接前往
3、設(shè)計(jì)思路框架
本博客提供1套vivado工程源碼,工程設(shè)計(jì)框圖如下:
視頻源選擇
視頻源有兩種,分別對(duì)應(yīng)開(kāi)發(fā)者手里有沒(méi)有攝像頭的情況,如果你的手里有攝像頭,或者你的開(kāi)發(fā)板有攝像頭接口,則使用攝像頭作為視頻輸入源,我這里用到的是廉價(jià)的OV5640攝像頭模組;如果你得手里沒(méi)有攝像頭,或者你得開(kāi)發(fā)板沒(méi)有攝像頭接口,則可使用代碼內(nèi)部生成的靜態(tài)彩條模擬攝像頭視頻,動(dòng)態(tài)彩條是移動(dòng)的畫(huà)面,完全可以模擬視頻;默認(rèn)使用ov5640作為視頻源;視頻源的選擇通過(guò)代碼頂層的`define宏定義進(jìn)行;如下:
選擇邏輯代碼部分如下:
選擇邏輯如下:
當(dāng)(注釋) define USE_SENSOR時(shí),輸入源視頻是靜態(tài)彩條;
當(dāng)(不注釋) define USE_SENSOR時(shí),輸入源視頻是ov5640攝像頭;
OV5640攝像頭配置及采集
OV5640攝像頭需要i2c配置才能使用,需要將DVP接口的視頻數(shù)據(jù)采集為RGB565或者RGB888格式的視頻數(shù)據(jù),這兩部分均用verilog代碼模塊實(shí)現(xiàn),代碼位置如下:
其中攝像頭配置為分辨率480x540,如下:
攝像頭采集模塊支持RGB565和RGB888格式的視頻輸出,可由參數(shù)配置,如下:
RGB_TYPE=0輸出本RGB565格式;
RGB_TYPE=1輸出本RGB888格式;
設(shè)計(jì)選擇RGB565格式;
靜態(tài)彩條
靜態(tài)彩條可配置為不同分辨率的視頻,視頻的邊框?qū)挾?#xff0c;動(dòng)態(tài)移動(dòng)方塊的大小,移動(dòng)速度等都可以參數(shù)化配置,我這里配置為辨率480x540,動(dòng)態(tài)彩條模塊代碼位置和頂層接口和例化如下:
視頻拼接算法
視頻拼接方案如下:
輸出屏幕分辨率為1920X1080;
輸入攝像頭分辨率為480X540;
8路輸入剛好可以占滿整個(gè)屏幕;
多路視頻的拼接顯示原理如下:
以把 2 個(gè)攝像頭 CAM0 和 CAM1 輸出到同一個(gè)顯示器上為列,為了把 2 個(gè)圖像顯示到 1 個(gè)顯示器,首先得搞清楚以下關(guān)系:
hsize:每 1 行圖像實(shí)際在內(nèi)存中占用的有效空間,以 32bit 表示一個(gè)像素的時(shí)候占用內(nèi)存大小為 hsize4;
hstride:用于設(shè)置每行圖像第一個(gè)像素的地址,以 32bit 表示一個(gè)像素的時(shí)候 v_cnt hstride4;
vsize:有效的行;
因此很容易得出 cam0 的每行第一個(gè)像素的地址也是 v_cnt hstride4;
同理如果我們需要把 cam1 在 hsize 和 vsize 空間的任何位置顯示,我們只要關(guān)心 cam1 每一行圖像第一個(gè)像素的地址,可以用以下公式 v_cnt hstride*4+offset;
uifdma_dbuf 支持 stride 參數(shù)設(shè)置,stride 參數(shù)可以設(shè)置輸入數(shù)據(jù) X(hsize)方向每一行數(shù)據(jù)的第一個(gè)像素到下一個(gè)起始像素的間隔地址,利用 stride 參數(shù)可以非常方便地?cái)[放輸入視頻到內(nèi)存中的排列方式。
關(guān)于uifdma_dbuf,可以參考我之前寫(xiě)的文章點(diǎn)擊查看:FDMA實(shí)現(xiàn)視頻數(shù)據(jù)三幀緩存
根據(jù)以上鋪墊,每路攝像頭緩存的基地址如下:
CAM0:ADDR_BASE=0x80000000;
CAM1:ADDR_BASE=0x80000000+(1920-480X1)X4;
CAM2:ADDR_BASE=0x80000000+(1920-480X2)X4;
CAM3:ADDR_BASE=0x80000000+(1920-480X3)X4;
CAM4:ADDR_BASE=0x80000000+(1080-540)X1920X4;
CAM5:ADDR_BASE=0x80000000+(1080-540)X1920X4+(1920-480X1)X4;
CAM6:ADDR_BASE=0x80000000+(1080-540)X1920X4+(1920-480X2)X4;
CAM7:ADDR_BASE=0x80000000+(1080-540)X1920X4+(1920-480X3)X4;
地址設(shè)置完畢后基本就完事兒了;
圖像緩存
經(jīng)??次也┛偷睦戏蹜?yīng)該都知道,我做圖像緩存的套路是FDMA,他的作用是將圖像送入DDR中做3幀緩存再讀出顯示,目的是匹配輸入輸出的時(shí)鐘差和提高輸出視頻質(zhì)量,關(guān)于FDMA,請(qǐng)參考我之前的博客,博客地址:點(diǎn)擊直接前往
這里8路視頻拼接時(shí),調(diào)用8路FDMA進(jìn)行緩存,具體講就是每一路視頻調(diào)用1路FDMA;
調(diào)用8路FDMA,其中7路配置為寫(xiě)模式,因?yàn)檫@7路視頻在這里只需要寫(xiě)入DDR3,讀出是由另一個(gè)FDMA完成,配置如下:
另外1路FDMA配置為讀寫(xiě)模式,因?yàn)?路視頻需要同時(shí)一并讀出,配置如下:
視頻拼接的關(guān)鍵點(diǎn)在于8路視頻在DDR3中緩存地址的不同,8路FDMA的寫(xiě)地址以此為:
第1路視頻緩存寫(xiě)基地址:0x80000000;
第2路視頻緩存寫(xiě)基地址:0x80000780;
第3路視頻緩存寫(xiě)基地址:0x80000f00;
第4路視頻緩存寫(xiě)基地址:0x80001680;
第5路視頻緩存寫(xiě)基地址:0x803f4800;
第6路視頻緩存寫(xiě)基地址:0x803f4f80;
第7路視頻緩存寫(xiě)基地址:0x803f5700;
第8路視頻緩存寫(xiě)基地址:0x803f5e80;
視頻緩存讀基地址:0x80000000;
視頻輸出
視頻從FDMA讀出后,經(jīng)過(guò)VGA時(shí)序模塊和HDMI發(fā)送模塊后輸出顯示器,代碼位置如下:
VGA時(shí)序配置為1920X1080,HDMI發(fā)送模塊采用verilog代碼手寫(xiě),可以用于FPGA的HDMI發(fā)送應(yīng)用,關(guān)于這個(gè)模塊,請(qǐng)參考我之前的博客,博客地址:點(diǎn)擊直接前往
4、vivado工程詳解
開(kāi)發(fā)板FPGA型號(hào):Xilinx–Kintex7–xc7k325tffg676-2;
開(kāi)發(fā)環(huán)境:Vivado2019.1;
輸入:OV5640攝像頭或動(dòng)態(tài)彩條,分辨率480x540;
輸出:HDMI,1080P分辨率下的8塊480x540有效區(qū)域顯示;
工程作用:FPGA純verilog實(shí)現(xiàn)8路視頻拼接顯示;
工程BD如下:
因?yàn)檫@里用了8路FDMA,7路配置為只寫(xiě)模式,另一路配置為讀寫(xiě)模式;
工程代碼架構(gòu)如下:
工程的資源消耗和功耗如下:
5、工程移植說(shuō)明
vivado版本不一致處理
1:如果你的vivado版本與本工程vivado版本一致,則直接打開(kāi)工程;
2:如果你的vivado版本低于本工程vivado版本,則需要打開(kāi)工程后,點(diǎn)擊文件–>另存為;但此方法并不保險(xiǎn),最保險(xiǎn)的方法是將你的vivado版本升級(jí)到本工程vivado的版本或者更高版本;
3:如果你的vivado版本高于本工程vivado版本,解決如下:
打開(kāi)工程后會(huì)發(fā)現(xiàn)IP都被鎖住了,如下:
此時(shí)需要升級(jí)IP,操作如下:
FPGA型號(hào)不一致處理
如果你的FPGA型號(hào)與我的不一致,則需要更改FPGA型號(hào),操作如下:
更改FPGA型號(hào)后還需要升級(jí)IP,升級(jí)IP的方法前面已經(jīng)講述了;
其他注意事項(xiàng)
1:由于每個(gè)板子的DDR不一定完全一樣,所以MIG IP需要根據(jù)你自己的原理圖進(jìn)行配置,甚至可以直接刪掉我這里原工程的MIG并重新添加IP,重新配置;
2:根據(jù)你自己的原理圖修改引腳約束,在xdc文件中修改即可;
3:純FPGA移植到Zynq需要在工程中添加zynq軟核;
6、上板調(diào)試驗(yàn)證并演示
靜態(tài)演示
8路ov5640攝像頭480x540拼接輸出效果如下:
動(dòng)態(tài)演示
動(dòng)態(tài)視頻演示如下:
FPGA-8路視頻拼接
7、福利:工程源碼獲取
福利:工程代碼的獲取
代碼太大,無(wú)法郵箱發(fā)送,以某度網(wǎng)盤(pán)鏈接方式發(fā)送,
資料獲取方式:私,或者文章末尾的V名片。
網(wǎng)盤(pán)資料如下: