目录
- 1、前言
- 2、视频叠加模块的功能和性能
- 3、HLS视频叠加融合设计
- 4、vivado工程1--单路同源视频的缩放叠加
- 详细设计方案
- vivado工程详解
- SDK工程详解
- 5、vivado工程2--两路非同源视频的缩放叠加
- 详细设计方案
- vivado工程详解
- SDK工程详解
- 6、上板调试验证
- 7、福利:工程代码的获取
1、前言
视频叠加和融合在FPGA图像处理领域有着广泛应用,但其复杂的内存访问机制和视频叠加透明度的融合,使得实现难度很大,让很多FPGA工程师望而却步,在目前的技术条件下,使用HLS实现视频叠加融合是最简单方便的实现方式,本设计也是基于此实现。
本设计提供2套vivado工程,一套是单路同源视频的缩放叠加,原视频作为底层视频,取原视频的中间部分缩小后作为叠加视频,叠加于底层视频的左上角后输出;另一套是两路非同源视频的缩放叠加,一路视频作为底层视频,取另一路视频的中间部分缩小后作为叠加视频,叠加于底层视频的左上角后输出;代码编译通过后上板调试验证,可直接项目移植,适用于在校学生做毕业设计、研究生项目开发,也适用于在职工程师做项目开发,可应用于医疗、军工等行业的数字成像和图像传输领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式以及上板调试的演示视频放在了文章末尾,请耐心看到最后;
2、视频叠加模块的功能和性能
1:支持多路视频的叠加,前提是FPGA读写内存的带宽得足够宽,本设计使用2路视频叠加;
2:支持叠加视频任意尺寸缩放,因为图像叠加必然是有一个底层视频和叠加层视频,一般情况下叠加层视频尺寸会小于底层视频,而本设计支持叠加视频任意尺寸缩放,通过SDK软件配置;
3:支持任意位置的视频叠加,即叠加层视频在底层视频的叠加位置的坐标是可任意配置的,本设计的叠加位置是在x=0,y=0的位置,即视频左上角,通过SDK软件配置;
4:支持叠加视频透明度的任意配置,即所谓的视频融合,叠加层可以完全覆盖底层视频,也可以完全融合于底层视频,这个是通过透明度参数自由配置的,通过SDK软件配置;
5:通用性较好,zynq系列FPGA均可使用,通过修改HLS工程中的FPGA型号,还可以适配于其他FPGA型号;
6:目前最高支持1920x1080@60Hz的分辨率视频叠加,可以修改HLS工程中视频参数后适应4K分辨率,前提是FPGA的内存读写带宽得足够宽;
7:视频输入输出接口都是AXI4-Sream;
3、HLS视频叠加融合设计
HLS视频叠加融合设计框图如下:
底层视频输入:
AXI4-Sream视频流输入,本设计由VDMA的输出灌入,作为底层视频;
叠加层视频输入:
AXI4-FULL数据流输入,这里的叠加层视频是HLS视频叠加融合模块主动发起的AXI4读操作,所以需要给出读取视频的首地址和分辨率信息,这些参数是通过AXI4-Lite配置的,即SDK配置;
叠加层视频缩放:
调用HLS库函数实现,可以任意尺寸缩放,转为视频叠加设计,高度贴近真实项目,缩放参数通过AXI4-Lite配置的,即SDK配置;
视频输出:
AXI4-FULL数据流输出,输出是叠加后的视频;
配置参数输入:
AXI4-Lite接口,对接SDK软件;
4、vivado工程1–单路同源视频的缩放叠加
详细设计方案
单路视频的缩放叠加设计框图如下:
这里只用到1路视频,采用OV5640摄像头,视频通过VDMA缓存3帧到DDR3,取第一帧作为叠加视频叠加到OV5640摄像头视频流,然后输出;
这个工程的目的是验证同源视频的视频叠加,因为底层视频和叠加层视频都来自于同一个视频源,因为输入只有一个OV5640摄像头;
本工程的叠加层视频截取底层视频中心位置的图像缩小,然后叠加到底层视频的左上角;
vivado工程详解
开发板FPGA型号:FPGA–xc7z100ffg900-2;
开发环境:vivado2019.1;
输入:1路OV5640摄像头,分辨率1280x720@60Hz;
输出:HDMI,分辨率1280x720@60Hz;
Bolck Design设计如下:
综合后的工程代码架构如下:
综合编译完成后的FPGA资源消耗和功耗预估如下:
SDK工程详解
SDK工程代码架构如下:
自定义视频叠加API及其入口参数如下:
//video_width-->原视频宽度
//video_height-->原视频高度
//zoom_x-->提取原视频的x轴起始位置,提取的原视频区域作为叠加的视频
//zoom_y-->提取原视频的y轴起始位置,提取的原视频区域作为叠加的视频
//zoom_w-->叠加的视频宽度
//zoom_h-->叠加的视频高度
//overly_x-->叠加的视频在底层视频中的起始x轴坐标
//overly_y-->叠加的视频在底层视频中的起始y轴坐标
//overly_w-->叠加的视频缩放后的宽度
//overly_h-->叠加的视频缩放后的高度
//overly_alpha-->叠加的视频与底层视频之间的透明度
void helai_mix(u32 video_width,u32 video_height,u32 zoom_x,u32 zoom_y,u32 zoom_w,u32 zoom_h,u32 overly_x,
u32 overly_y,u32 overly_w,u32 overly_h,u32 overly_alpha){
//初始化
XOverlaystream_Initialize(&overlaystreamInstance, XPAR_OVERLAYSTREAM_0_DEVICE_ID);
//取视频的地址,这里取VDMA的第一帧地址
XOverlaystream_Set_pMem(&overlaystreamInstance,VIDEO_BASEADDR0);
//使能
XOverlaystream_EnableAutoRestart(&overlaystreamInstance);
//启动
XOverlaystream_Start(&overlaystreamInstance);
//配置参数
XOverlaystream_Set_cols(&overlaystreamInstance, video_width);
XOverlaystream_Set_rows(&overlaystreamInstance, video_height);
XOverlaystream_Set_zoom_x(&overlaystreamInstance, zoom_x);
XOverlaystream_Set_zoom_y(&overlaystreamInstance, zoom_y);
XOverlaystream_Set_zoom_w(&overlaystreamInstance, zoom_w);
XOverlaystream_Set_zoom_h(&overlaystreamInstance, zoom_h);
XOverlaystream_Set_overly_x(&overlaystreamInstance, overly_x);
XOverlaystream_Set_overly_y(&overlaystreamInstance, overly_y);
XOverlaystream_Set_overly_w(&overlaystreamInstance, overly_w);
XOverlaystream_Set_overly_h(&overlaystreamInstance, overly_h);
XOverlaystream_Set_overly_alpha(&overlaystreamInstance, overly_alpha);
}
主函数如下:
int main(){
init_platform();
I2C_config_init();
helai_vdma();
helai_mix(1280,720,1280/2-200,720/2-200,400,400,0,0,1280/2,720/2,40);
while(1);
cleanup_platform();
return 0;
}
5、vivado工程2–两路非同源视频的缩放叠加
详细设计方案
两路视频的缩放叠加设计框图如下:
这里用到了2路视频,采用OV5640摄像头,摄像头2视频通过VDMA缓存3帧到DDR3,作为底层视频;摄像头1视频通过VDMA缓存3帧到DDR3,作为叠加层视频;两路视频叠加,然后输出;
这个工程的目的是验证非同源视频的视频叠加,因为底层视频和叠加层视频都来自于不同的视频源,因为输入只有2个OV5640摄像头;
本工程的叠加层视频截摄像头1视频中心位置的图像缩小,然后叠加到摄像头2底层视频的左上角;
vivado工程详解
开发板FPGA型号:FPGA–xc7z100ffg900-2;
开发环境:vivado2019.1;
输入:2路OV5640摄像头,分辨率1280x720@60Hz;
输出:HDMI,分辨率1280x720@60Hz;
Bolck Design设计如下:
底层视频的VDMA配置为读写模式,如下:
叠加层视频的VDMA配置为只写模式,如下:
综合后的工程代码架构如下:
综合编译完成后的FPGA资源消耗和功耗预估如下:
SDK工程详解
SDK工程代码架构如下:
自定义视频叠加API及其入口参数如下:
//video_width-->原视频宽度
//video_height-->原视频高度
//zoom_x-->提取原视频的x轴起始位置,提取的原视频区域作为叠加的视频
//zoom_y-->提取原视频的y轴起始位置,提取的原视频区域作为叠加的视频
//zoom_w-->叠加的视频宽度
//zoom_h-->叠加的视频高度
//overly_x-->叠加的视频在底层视频中的起始x轴坐标
//overly_y-->叠加的视频在底层视频中的起始y轴坐标
//overly_w-->叠加的视频缩放后的宽度
//overly_h-->叠加的视频缩放后的高度
//overly_alpha-->叠加的视频与底层视频之间的透明度
void helai_mix(u32 video_width,u32 video_height,u32 zoom_x,u32 zoom_y,u32 zoom_w,u32 zoom_h,u32 overly_x,
u32 overly_y,u32 overly_w,u32 overly_h,u32 overly_alpha){
//初始化
XOverlaystream_Initialize(&overlaystreamInstance, XPAR_OVERLAYSTREAM_0_DEVICE_ID);
//取视频的地址,这里取VDMA的第一帧地址
XOverlaystream_Set_pMem(&overlaystreamInstance,VIDEO1_BASEADDR1);
//使能
XOverlaystream_EnableAutoRestart(&overlaystreamInstance);
//启动
XOverlaystream_Start(&overlaystreamInstance);
//配置参数
XOverlaystream_Set_cols(&overlaystreamInstance, video_width);
XOverlaystream_Set_rows(&overlaystreamInstance, video_height);
XOverlaystream_Set_zoom_x(&overlaystreamInstance, zoom_x);
XOverlaystream_Set_zoom_y(&overlaystreamInstance, zoom_y);
XOverlaystream_Set_zoom_w(&overlaystreamInstance, zoom_w);
XOverlaystream_Set_zoom_h(&overlaystreamInstance, zoom_h);
XOverlaystream_Set_overly_x(&overlaystreamInstance, overly_x);
XOverlaystream_Set_overly_y(&overlaystreamInstance, overly_y);
XOverlaystream_Set_overly_w(&overlaystreamInstance, overly_w);
XOverlaystream_Set_overly_h(&overlaystreamInstance, overly_h);
XOverlaystream_Set_overly_alpha(&overlaystreamInstance, overly_alpha);
}
主函数如下:
int main()
{
init_platform();
I2C_config_init(DeviceId_0);
I2C_config_init(DeviceId_1);
helai_vdma();
helai_mix(1280,720,1280/2-200,720/2-200,400,400,0,0,1280/2,720/2,40);
while(1);
cleanup_platform();
return 0;
}
6、上板调试验证
静态演示如下:
我用到的开发板FPGA型号为xc7z100ffg900-2;板载一路HDMI输出接口,没有HDMI编码芯片,由FPGA逻辑资源驱动;
工程1,即单路同源视频的缩放叠加的输出视频如下:
1路同源视频叠加
工程2,即2路非同源视频的缩放叠加的输出视频如下:
2路非同源视频叠加
7、福利:工程代码的获取
福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式1:私,或者文章末尾的V名片。
网盘资料如下: