Zynq7020 使用 Video Processing Subsystem 实现图像缩放
1、前言
没玩过图像缩放都不好意思说自己玩儿过 FPGA,这是 CSDN 某大佬说过的一句话,鄙人深信不疑。。。
目前市面上主流的 FPGA 图像缩放方案如下:1:Xilinx 的 HLS 方案,该方案简单,易于实现,但只能用于 Xilinx 自家的 FPGA;2:非纯 Verilog 方案,大部分代码使用 Verilog 实现,但中间的 fifo 或 ram 等使用了 IP,导致移植性变差,难以在 Xilinx、Altera 和国产 FPGA 之间自由移植;3:纯 Verilog 方案;
本文使用 Xilinx Zynq7000 系列 FPGA Zynq7020 实现 Video Processing Subsystem 图像缩放,输入视频源采用 OV5640 摄像头模组;FPGA 采集 OV5640 摄像头视频 DVP 转 RGB888,调用 Zynq 软核的片内 i2c 控制器将 OV5640 配置为 1280x720@30Hz 分辨率;然后调用 Xilinx 官方的 Video In to AXI4-Stream IP 核将 RGB 视频流转换为 AXI4-Stream 视频流;然后调用 Xilinx 官方的 Video Processing Subsystem IP 核将输入视频进行任意尺寸图像缩放操作,该操作通过 Zynq 软核 SDK 软件配置,其本质为通过 AXI_Lite 做寄存器配置;然后调用 Xilinx 官方的 VDMA IP 将视频做 PS 侧 DDR3 的视频缓存操作,调用 Zynq 将 VDMA 配置为三帧缓存,其本质为通过 AXI_Lite 做寄存器配置;然后调用 Xilinx 官方的 Video Timing Controller IP 和 AXI4-Stream to Video Out IP 将 AXI4-Stream 视频流转换为 RGB 视频流;然后添加自定义的 HDMI 发送 IP 将 RGB 视频转换为 TMDS 的差分视频送显示器显示;提供一套 vivado2019.1 版本的工程源码和技术支持;
本博客详细描述了 Zynq-7000 系列 FPGA 使用 Video Processing Subsystem 实现图像缩放的设计方案,工程代码可综合编译上板调试,可直接项目移植,适用于在校学生、研究生项目开发,也适用于在职工程师做学习提升,可应用于医疗、军工等行业的高速接口或图像处理领域;整个工程调用 Zynq 软核做 IP 的配置,Zynq 的配置在 SDK 里以 C 语言软件代码的形式运行,所以整个工程包括 FPGA 逻辑设计和 SDK 软件设计两部分,需要具备 FPGA 和嵌入式 C 语言的综合能力,不适合初学者或者小白;
2、相关方案推荐
FPGA 图像处理方案
我的主页目前有 FPGA 图像处理专栏,改专栏收录了我目前手里已有的 FPGA 图像处理方案,包括图像缩放、图像识别、图像拼接、图像融合、图像去雾、图像叠加、图像旋转、图像增强、图像字符叠加等等;以下是专栏地址:点击直接前往
FPGA 图像缩放方案
我的主页目前有 FPGA 图像缩放专栏,改专栏收录了我目前手里已有的 FPGA 图像缩放方案,从实现方式分类有基于 HSL 实现的图像缩放、基于纯 verilog 代码实现的图像缩放;从应用上分为单路视频图像缩放、多路视频图像缩放、多路视频图像缩放拼接;从输入视频分类可分为 OV5640 摄像头视频缩放、SDI 视频缩放、MIPI 视频缩放等等;以下是专栏地址:点击直接前往
HLS 图像缩放方案
之前写过一篇自己写的 HLS 图像缩放的博客,该方案与官方的 Video Processing Subsystem 区别在于手写的看得到;以下是博客地址:点击直接前往
3、设计思路详解
本文使用 Xilinx Zynq7000 系列 FPGA Zynq7020 实现 Video Processing Subsystem 图像缩放,输入视频源采用 OV5640 摄像头模组;FPGA 采集 OV5640 摄像头视频 DVP 转 RGB888,调用 Zynq 软核的片内 i2c 控制器将 OV5640 配置为 1280x720@30Hz 分辨率;然后调用 Xilinx 官方的 Video In to AXI4-Stream IP 核将 RGB 视频流转换为 AXI4-Stream 视频流;然后调用 Xilinx 官方的 Video Processing Subsystem IP 核将输入视频进行任意尺寸图像缩放操作,该操作通过 Zynq 软核 SDK 软件配置,其本质为通过 AXI_Lite 做寄存器配置;然后调用 Xilinx 官方的 VDMA IP 将视频做 PS 侧 DDR3 的视频缓存操作,调用 Zynq 将 VDMA 配置为三帧缓存,其本质为通过 AXI_Lite 做寄存器配置;然后调用 Xilinx 官方的 Video Timing Controller IP 和 AXI4-Stream to Video Out IP 将 AXI4-Stream 视频流转换为 RGB 视频流;然后添加自定义的 HDMI 发送 IP 将 RGB 视频转换为 TMDS 的差分视频送显示器显示;提供一套 vivado2019.1 版本的工程源码和技术支持;工程源码设计框图如下:
框图解释:箭头表示数据流向,箭头内文字表示数据格式,箭头外数字表示数据柳巷的步骤;
Video Processing Subsystem 介绍
由于工程所用到的 IP 都是常用 IP,所以这里重点介绍一下 Video Processing Subsystem;Video Processing Subsystem 有缩放、去隔行、颜色空间转换等功能,这里仅使用图像缩放功能;其特点如下:适用于 Xilinx 所有系列的 FPGA 器件;支持最大分辨率:8K,即可以处理高达 8K 的视频;输入视频格式:AXI4-Stream;输出视频格式:AXI4-Stream;需要 SDK 软件配置,其本质为通过 AXI_Lite 做寄存器配置;提供自定义的配置 API,通过调用该库函数即可轻松使用,具体参考 SDK 代码;模块占用的 FPGA 逻辑资源更小,相比于自己写的 HLS 图像缩放而言,官方的 Video Processing Subsystem 资源占用大约减小 30%左右,且更高效:Video Processing Subsystem 逻辑资源如下,请谨慎评估你的 FPGA 资源情况;
Video Processing Subsystem IP 配置如下:这里配置为双线性插值图像缩放算法;
4、工程代码详解
PL 端 FPGA 逻辑设计
开发板 FPGA 型号:Xilinx--Zynq7020--xc7z020clg400-2;开发环境:Vivado2019.1;输入:OV5640 摄像头,分辨率 1280x720p;输出:HDMI,1080P 分辨率下的有效区域显示;工程作用:Zynq-7000 系列 FPGA 使用 Video Processing Subsystem 实现图像缩放, HDMI 输出;工程 BD 如下:
工程代码架构如下:
工程的资源消耗和功耗如下:
PS 端 SDK 软件设计
PS 端 SDK 软件工程代码架构如下:
主函数通过如下的五个宏定义设计了五种不同的图像缩放方案:ov5640 输入分辨率 1280x720,HDMI 输出分辨率 1280x720;ov5640 输入分辨率 1280x720,HDMI 输出分辨率 640x480;ov5640 输入分辨率 1280x720,HDMI 输出分辨率 300x300;ov5640 输入分辨率 1280x720,HDMI 输出分辨率 1600x800;ov5640 输入分辨率 1280x720,HDMI 输出分辨率 1920x1080;
主函数进行相应的图像缩放操作,并打印相关信息,代码如下:
5、工程移植说明
vivado 版本不一致处理
1:如果你的 vivado 版本与本工程 vivado 版本一致,则直接打开工程;
2:如果你的 vivado 版本低于本工程 vivado 版本,则需要打开工程后,点击文件-->另存为;但此方法并不保险,最保险的方法是将你的 vivado 版本升级到本工程 vivado 的版本或者更高版本;
3:如果你的 vivado 版本高于本工程 vivado 版本,解决如下:
打开工程后会发现 IP 都被锁住了,如下:
此时需要升级 IP,操作如下:
FPGA 型号不一致处理
如果你的 FPGA 型号与我的不一致,则需要更改 FPGA 型号,操作如下:
更改 FPGA 型号后还需要升级 IP,升级 IP 的方法前面已经讲述了;
其他注意事项
1:由于每个板子的 DDR 不一定完全一样,所以 MIG IP 需要根据你自己的原理图进行配置,甚至可以直接删掉我这里原工程的 MIG 并重新添加 IP,重新配置;2:根据你自己的原理图修改引脚约束,在 xdc 文件中修改即可;3:纯 FPGA 移植到 Zynq 需要在工程中添加 zynq 软核;
6、上板调试验证并演示
准备工作
Zynq7000 系列开发板;OV5640 摄像头;HDMI 显示器或者 LCD 显示屏,我用到的 LCD 显示屏为 4.3 寸分辨率 800x480;
输出静态演示
ov5640 输入分辨率 1280x720,HDMI 输出分辨率 1280x720;HDMI 显示输出和串口打印分别如下:
ov5640 输入分辨率 1280x720,HDMI 输出分辨率 640x480;HDMI 显示输出和串口打印分别如下:
ov5640 输入分辨率 1280x720,HDMI 输出分辨率 300x300;HDMI 显示输出和串口打印分别如下:
ov5640 输入分辨率 1280x720,HDMI 输出分辨率 1600x800;HDMI 显示输出和串口打印分别如下:
ov5640 输入分辨率 1280x720,HDMI 输出分辨率 1920x1080;HDMI 显示输出和串口打印分别如下:
版权声明: 本文为 InfoQ 作者【攻城狮Wayne】的原创文章。
原文链接:【http://xie.infoq.cn/article/fc6aa77433df74675541cce45】。文章转载请联系作者。
评论