商務(wù)型網(wǎng)站seo專員招聘
目錄
- 1、前言
- 版本更新說明
- 免責(zé)聲明
- 2、相關(guān)方案推薦
- FPGA圖像縮放方案推薦
- FPGA視頻拼接方案推薦
- 3、設(shè)計(jì)思路框架
- 視頻源選擇
- IT6802解碼芯片配置及采集
- 動態(tài)彩條
- 緩沖FIFO
- 圖像縮放模塊詳解
- 設(shè)計(jì)框圖
- 代碼框圖
- 2種插值算法的整合與選擇
- 視頻拼接算法
- 圖像緩存
- 視頻輸出
- 4、vivado工程1:2路視頻縮放拼接
- 5、vivado工程2:4路視頻縮放拼接
- 6、工程移植說明
- vivado版本不一致處理
- FPGA型號不一致處理
- 其他注意事項(xiàng)
- 7、上板調(diào)試驗(yàn)證并演示
- 準(zhǔn)備工作
- 靜態(tài)演示
- 動態(tài)演示
- 8、福利:工程源碼獲取
FPGA 多路視頻處理:圖像縮放+視頻拼接顯示,HDMI采集,提供2套工程源碼和技術(shù)支持
1、前言
沒玩過圖像縮放和視頻拼接都不好意思說自己玩兒過FPGA,這是CSDN某大佬說過的一句話,鄙人深信不疑。。。本文使用Xilinx的Kintex7 FPGA的圖像縮放多路視頻拼接方案,視頻源有兩種,分別對應(yīng)開發(fā)者手里有沒有攝像頭的情況,一種是使用板載的HDMI輸入接口(筆記本電腦模擬HDMI輸入),使用IT6802解碼芯片將TMDS的差分HDMI視頻解碼為24位的RGB視頻數(shù)據(jù)供FPGA使用;如果你的FPGA開發(fā)板沒有HDMI輸入接口,則可使用代碼內(nèi)部生成的動態(tài)彩條模擬攝像頭視頻;視頻源的選擇通過代碼頂層的`define宏定義進(jìn)行選擇,上電默認(rèn)使用HDMI輸入作為視頻源;提供2套vivado2019.1版本的工程源碼,2套工程源碼的不同點(diǎn)在于圖像縮放后的分辨率不同和視頻拼接的方式不同,工程1將輸入的1920x1080分辨率視頻通過圖像縮放模塊縮小到960x1080,然后將視頻復(fù)制兩份,用以模擬兩路視頻輸入,做兩路視頻拼接后在1920x1080分辨率的輸出視頻上做2分屏拼接顯示;工程2將輸入的1920x1080分辨率視頻通過圖像縮放模塊縮小到960x480,然后將視頻復(fù)制4份,用以模擬4路視頻輸入,做4路視頻拼接后在1920x1080分辨率的輸出視頻上做4分屏拼接顯示;FPGA縮放后的視頻,用我常用的FDMA套路進(jìn)行圖像緩存,緩存的介質(zhì)為DDR3,然后讀出視頻,生成標(biāo)準(zhǔn)的1920x1080分辨率的VGA時(shí)序,再用純verilog實(shí)現(xiàn)的RGB轉(zhuǎn)HDMI模塊將視頻輸出到顯示器顯示;
本博客詳細(xì)描述了FPGA 圖像縮放多路視頻拼接的設(shè)計(jì)方案,工程代碼可綜合編譯上板調(diào)試,可直接項(xiàng)目移植,適用于在校學(xué)生、研究生項(xiàng)目開發(fā),也適用于在職工程師做學(xué)習(xí)提升,可應(yīng)用于醫(yī)療、軍工等行業(yè)的高速接口或圖像處理領(lǐng)域;
提供完整的、跑通的工程源碼和技術(shù)支持;
工程源碼和技術(shù)支持的獲取方式放在了文章末尾,請耐心看到最后;
版本更新說明
此版本為第2版,根據(jù)讀者的建議,對第1版工程做了如下改進(jìn)和更新:
1:增加了輸入視頻靜態(tài)彩條的選擇,有的讀者說他的FPGA開發(fā)板沒有HDMI輸入接口,導(dǎo)致在移植過程中困難很大,基于此,增加了靜態(tài)彩條,它由FPGA內(nèi)部產(chǎn)生,不需要外接攝像頭就可以使用,使用方法在后文有說明;
2:優(yōu)化了FDMA,之前的FDMA內(nèi)AXI4的數(shù)據(jù)讀寫突發(fā)長度為256,導(dǎo)致在低端FPGA上帶寬不夠,從而圖像質(zhì)量不佳,基于此,將FDMA內(nèi)AXI4的數(shù)據(jù)讀寫突發(fā)長度改為128;
3:優(yōu)化了HDMI輸出模塊,之前用的自定義IP,有讀者說IP無法更新,雖能正常使用,但看源碼不方便,基于此,將HDMI輸出模塊改為純verilog實(shí)現(xiàn)的,直接了當(dāng);
免責(zé)聲明
本工程及其源碼即有自己寫的一部分,也有網(wǎng)絡(luò)公開渠道獲取的一部分(包括CSDN、Xilinx官網(wǎng)、Altera官網(wǎng)等等),若大佬們覺得有所冒犯,請私信批評教育;基于此,本工程及其源碼僅限于讀者或粉絲個(gè)人學(xué)習(xí)和研究,禁止用于商業(yè)用途,若由于讀者或粉絲自身原因用于商業(yè)用途所導(dǎo)致的法律問題,與本博客及博主無關(guān),請謹(jǐn)慎使用。。。
2、相關(guān)方案推薦
本工程是圖像縮放和視頻拼接的整合版,在此之前,我分別推出過FPGA圖像縮放方案和FPGA視頻拼接方案,所以推薦如下:
FPGA圖像縮放方案推薦
該方案使用純verilog代碼實(shí)現(xiàn)任意尺寸圖像縮放,詳細(xì)請參考我之前的博客,博客鏈接如下:
直接點(diǎn)擊前往
FPGA視頻拼接方案推薦
該方案使用純verilog代碼實(shí)現(xiàn)多路視頻拼接,詳細(xì)請參考我之前的博客,博客鏈接如下:
4路視頻拼接方案參考博客鏈接如下:直接點(diǎn)擊前往
8路視頻拼接方案參考博客鏈接如下:直接點(diǎn)擊前往
16路視頻拼接方案參考博客鏈接如下:直接點(diǎn)擊前往
3、設(shè)計(jì)思路框架
視頻源有兩種,分別對應(yīng)開發(fā)者手里有沒有攝像頭的情況,一種是使用板載的HDMI輸入接口(筆記本電腦模擬HDMI輸入),使用IT6802解碼芯片將TMDS的差分HDMI視頻解碼為24位的RGB視頻數(shù)據(jù)供FPGA使用;如果你的FPGA開發(fā)板沒有HDMI輸入接口,則可使用代碼內(nèi)部生成的動態(tài)彩條模擬攝像頭視頻;視頻源的選擇通過代碼頂層的`define宏定義進(jìn)行選擇,上電默認(rèn)使用HDMI輸入作為視頻源;提供2套vivado2019.1版本的工程源碼,2套工程源碼的不同點(diǎn)在于圖像縮放后的分辨率不同和視頻拼接的方式不同,工程1將輸入的1920x1080分辨率視頻通過圖像縮放模塊縮小到960x1080,然后將視頻復(fù)制兩份,用以模擬兩路視頻輸入,做兩路視頻拼接后在1920x1080分辨率的輸出視頻上做2分屏拼接顯示;工程2將輸入的1920x1080分辨率視頻通過圖像縮放模塊縮小到960x480,然后將視頻復(fù)制4份,用以模擬4路視頻輸入,做4路視頻拼接后在1920x1080分辨率的輸出視頻上做4分屏拼接顯示;FPGA縮放后的視頻,用我常用的FDMA套路進(jìn)行圖像緩存,緩存的介質(zhì)為DDR3,然后讀出視頻,生成標(biāo)準(zhǔn)的1920x1080分辨率的VGA時(shí)序,再用純verilog實(shí)現(xiàn)的RGB轉(zhuǎn)HDMI模塊將視頻輸出到顯示器顯示;
工程1設(shè)計(jì)框圖如下:
工程2設(shè)計(jì)框圖如下:
視頻源選擇
視頻源有兩種,分別對應(yīng)開發(fā)者手里有沒有攝像頭的情況,一種是使用板載的HDMI輸入接口(筆記本電腦模擬HDMI輸入),使用IT6802解碼芯片將TMDS的差分HDMI視頻解碼為24位的RGB視頻數(shù)據(jù)供FPGA使用;如果你的FPGA開發(fā)板沒有HDMI輸入接口,則可使用代碼內(nèi)部生成的動態(tài)彩條模擬攝像頭視頻;視頻源的選擇通過代碼頂層的宏定義進(jìn)行選擇,上電默認(rèn)使用HDMI輸入作為視頻源;視頻源的選擇通過代碼頂層的`define宏定義進(jìn)行;如下:
視頻源選擇邏輯代碼部分如下:
選擇邏輯如下:
當(dāng)(注釋) define USE_SENSOR時(shí),輸入源視頻是動態(tài)彩條;
當(dāng)(不注釋) define USE_SENSOR時(shí),輸入源視頻是HDMI;
IT6802解碼芯片配置及采集
IT6802解碼芯片需要i2c配置才能使用,關(guān)于IT6802解碼芯片的配置和使用,請參考我往期的博客,博客地址:點(diǎn)擊直接前往
IT6802解碼芯片配置及采集這兩部分均用verilog代碼模塊實(shí)現(xiàn),代碼位置如下:
代碼中配置為1920x1080分辨率;
動態(tài)彩條
動態(tài)彩條可配置為不同分辨率的視頻,視頻的邊框?qū)挾?#xff0c;動態(tài)移動方塊的大小,移動速度等都可以參數(shù)化配置,我這里配置為辨率1280x720,動態(tài)彩條模塊代碼位置和頂層接口和例化如下:
緩沖FIFO
緩沖FIFO的作用是為了解決跨時(shí)鐘域的問題,當(dāng)視頻不進(jìn)行縮放時(shí)不存在視頻跨時(shí)鐘域問題,但當(dāng)視頻縮小或放大時(shí)就存在此問題,用FIFO緩沖可以使圖像縮放模塊每次讀到的都是有效的輸入數(shù)據(jù),注意,原視頻的輸入時(shí)序在這里就已經(jīng)被打亂了;
圖像縮放模塊詳解
設(shè)計(jì)框圖
本設(shè)計(jì)將常用的雙線性插值和鄰域插值算法融合為一個(gè)代碼中,通過輸入?yún)?shù)選擇某一種算法;代碼使用純verilog實(shí)現(xiàn),沒有任何ip,可在Xilinx、Intel、國產(chǎn)FPGA間任意移植;代碼以ram和fifo為核心進(jìn)行數(shù)據(jù)緩存和插值實(shí)現(xiàn),設(shè)計(jì)架構(gòu)如下:
視頻輸入時(shí)序要求如下:
輸入像素?cái)?shù)據(jù)在dInValid和nextDin同時(shí)為高時(shí)方可改變;
視頻輸出時(shí)序要求如下:
輸出像素?cái)?shù)據(jù)在dOutValid 和nextdOut同時(shí)為高時(shí)才能輸出;
代碼框圖
代碼使用純verilog實(shí)現(xiàn),沒有任何ip,可在Xilinx、Intel、國產(chǎn)FPGA間任意移植;
圖像縮放的實(shí)現(xiàn)方式很多,最簡單的莫過于Xilinx的HLS方式實(shí)現(xiàn),用opencv的庫,以c++語言幾行代碼即可完成,關(guān)于HLS實(shí)現(xiàn)圖像縮放請參考我之前寫的文章HLS實(shí)現(xiàn)圖像縮放
網(wǎng)上也有其他圖像縮放例程代碼,但大多使用了IP,導(dǎo)致在其他FPGA器件上移植變得困難,通用性不好;相比之下,本設(shè)計(jì)代碼就具有通用性;代碼架構(gòu)如圖;
其中頂層接口部分如下:
2種插值算法的整合與選擇
本設(shè)計(jì)將常用的雙線性插值和鄰域插值算法融合為一個(gè)代碼中,通過輸入?yún)?shù)選擇某一種算法;
具體選擇參數(shù)如下:
input wire i_scaler_type //0-->bilinear;1-->neighbor
通過輸入i_scaler_type 的值即可選擇;
輸入0選擇雙線性插值算法;
輸入1選擇鄰域插值算法;
關(guān)于這兩種算法的數(shù)學(xué)差異,請參考我之前寫的文章HLS實(shí)現(xiàn)圖像縮放
視頻拼接算法
視頻拼接方案如下:以工程2的4路OV5640攝像頭拼接為例;
輸出屏幕分辨率為1920X1080;
輸入攝像頭分辨率為960X540;
4路輸入剛好可以占滿整個(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,可以參考我之前寫的文章點(diǎn)擊查看:FDMA實(shí)現(xiàn)視頻數(shù)據(jù)三幀緩存
根據(jù)以上鋪墊,每路攝像頭緩存的基地址如下:
CAM0:ADDR_BASE=0x80000000;
CAM1:ADDR_BASE=0x80000000+(1920-960)X4;
CAM2:ADDR_BASE=0x80000000+(1080-540)X1920X4;
CAM3:ADDR_BASE=0x80000000+(1080-540)X1920X4+(1920-960)X4;
地址設(shè)置完畢后基本就完事兒了;
圖像緩存
經(jīng)??次也┛偷睦戏蹜?yīng)該都知道,我做圖像緩存的套路是FDMA,他的作用是將圖像送入DDR中做3幀緩存再讀出顯示,目的是匹配輸入輸出的時(shí)鐘差和提高輸出視頻質(zhì)量,關(guān)于FDMA,請參考我之前的博客,博客地址:點(diǎn)擊直接前往
這里多路視頻拼接時(shí),調(diào)用多路FDMA進(jìn)行緩存,具體講就是每一路視頻調(diào)用1路FDMA,以4路視頻拼接為例:
調(diào)用4路FDMA,其中三路配置為寫模式,因?yàn)檫@三路視頻在這里只需要寫入DDR3,讀出是由另一個(gè)FDMA完成,配置如下:
另外1路FDMA配置為讀寫模式,因?yàn)?路視頻需要同時(shí)一并讀出,配置如下:
視頻拼接的關(guān)鍵點(diǎn)在于4路視頻在DDR3中緩存地址的不同,還是以4路視頻拼接為例,4路FDMA的寫地址以此為:
第一路視頻緩存寫基地址:0x80000000;
第二路視頻緩存寫基地址:0x80000f00;
第三路視頻緩存寫基地址:0x803f4800;
第四路視頻緩存寫基地址:0x803f5700;
視頻緩存讀基地址:0x80000000;
視頻輸出
視頻從FDMA讀出后,經(jīng)過VGA時(shí)序模塊和HDMI發(fā)送模塊后輸出顯示器,代碼位置如下:
VGA時(shí)序配置為1280X720,HDMI發(fā)送模塊采用verilog代碼手寫,可以用于FPGA的HDMI發(fā)送應(yīng)用,關(guān)于這個(gè)模塊,請參考我之前的博客,博客地址:點(diǎn)擊直接前往
4、vivado工程1:2路視頻縮放拼接
開發(fā)板FPGA型號:Xilinx–Kintex7–xc7k325tffg676-2;
開發(fā)環(huán)境:Vivado2019.1;
輸入:HDMI(IT6802解碼)或動態(tài)彩條,分辨率1920x1080;
輸出:HDMI,1080P分辨率下的顯示2路拼接視頻;
工程應(yīng)用:FPGA 圖像縮放多路視頻拼接;
工程BD如下:
工程代碼架構(gòu)如下:
工程的資源消耗和功耗如下:
5、vivado工程2:4路視頻縮放拼接
開發(fā)板FPGA型號:Xilinx–Kintex7–xc7k325tffg676-2;
開發(fā)環(huán)境:Vivado2019.1;
輸入:HDMI(IT6802解碼)或動態(tài)彩條,分辨率1920x1080;
輸出:HDMI,1080P分辨率下的顯示4路拼接視頻;
工程應(yīng)用:FPGA 圖像縮放多路視頻拼接;
工程BD如下:
工程代碼架構(gòu)如下:
工程的資源消耗和功耗如下:
6、工程移植說明
vivado版本不一致處理
1:如果你的vivado版本與本工程vivado版本一致,則直接打開工程;
2:如果你的vivado版本低于本工程vivado版本,則需要打開工程后,點(diǎn)擊文件–>另存為;但此方法并不保險(xiǎn),最保險(xiǎn)的方法是將你的vivado版本升級到本工程vivado的版本或者更高版本;
3:如果你的vivado版本高于本工程vivado版本,解決如下:
打開工程后會發(fā)現(xiàn)IP都被鎖住了,如下:
此時(shí)需要升級IP,操作如下:
FPGA型號不一致處理
如果你的FPGA型號與我的不一致,則需要更改FPGA型號,操作如下:
更改FPGA型號后還需要升級IP,升級IP的方法前面已經(jīng)講述了;
其他注意事項(xiàng)
1:由于每個(gè)板子的DDR不一定完全一樣,所以MIG IP需要根據(jù)你自己的原理圖進(jìn)行配置,甚至可以直接刪掉我這里原工程的MIG并重新添加IP,重新配置;
2:根據(jù)你自己的原理圖修改引腳約束,在xdc文件中修改即可;
3:純FPGA移植到Zynq需要在工程中添加zynq軟核;
7、上板調(diào)試驗(yàn)證并演示
準(zhǔn)備工作
你需要有以下裝備才能移植并測試該工程代碼:
1:FPGA開發(fā)板;
2:板載的HDMI輸入接口,如果沒有也可以,就選擇動態(tài)彩條;
3:HDMI傳輸線;
4:HDMI顯示,要求分辨率支持1920x1080;
靜態(tài)演示
工程1:HDMI(IT6802解碼)1920x1080輸入縮放到960x1080后2路視頻拼接2分屏輸出如下:
工程1:動態(tài)彩條1920x1080輸入縮放到960x1080后2路視頻拼接2分屏輸出如下:
工程2:HDMI(IT6802解碼)1920x1080輸入縮放到960x540后4路視頻拼接4分屏輸出如下:
工程2:動態(tài)彩條1920x1080輸入縮放到960x540后4路視頻拼接4分屏輸出如下:
動態(tài)演示
動態(tài)視頻演示如下:
FPGA-視頻縮放拼接-HDMI-2023
8、福利:工程源碼獲取
福利:工程代碼的獲取
代碼太大,無法郵箱發(fā)送,以某度網(wǎng)盤鏈接方式發(fā)送,
資料獲取方式:私,或者文章末尾的V名片。
網(wǎng)盤資料如下: