FPGA 多路视频处理:图像缩放+视频拼接显示,HDMI采集,提供2套工程源码和技术支持

news2024/12/30 2:31:32

目录

  • 1、前言
    • 版本更新说明
    • 免责声明
  • 2、相关方案推荐
    • FPGA图像缩放方案推荐
    • FPGA视频拼接方案推荐
  • 3、设计思路框架
    • 视频源选择
    • IT6802解码芯片配置及采集
    • 动态彩条
    • 缓冲FIFO
    • 图像缩放模块详解
      • 设计框图
      • 代码框图
      • 2种插值算法的整合与选择
    • 视频拼接算法
    • 图像缓存
    • 视频输出
  • 4、vivado工程1:2路视频缩放拼接
  • 5、vivado工程2:4路视频缩放拼接
  • 6、工程移植说明
    • vivado版本不一致处理
    • FPGA型号不一致处理
    • 其他注意事项
  • 7、上板调试验证并演示
    • 准备工作
    • 静态演示
    • 动态演示
  • 8、福利:工程源码获取

FPGA 多路视频处理:图像缩放+视频拼接显示,HDMI采集,提供2套工程源码和技术支持

1、前言

没玩过图像缩放和视频拼接都不好意思说自己玩儿过FPGA,这是CSDN某大佬说过的一句话,鄙人深信不疑。。。本文使用Xilinx的Kintex7 FPGA的图像缩放多路视频拼接方案,视频源有两种,分别对应开发者手里有没有摄像头的情况,一种是使用板载的HDMI输入接口(笔记本电脑模拟HDMI输入),使用IT6802解码芯片将TMDS的差分HDMI视频解码为24位的RGB视频数据供FPGA使用;如果你的FPGA开发板没有HDMI输入接口,则可使用代码内部生成的动态彩条模拟摄像头视频;视频源的选择通过代码顶层的`define宏定义进行选择,上电默认使用HDMI输入作为视频源;提供2套vivado2019.1版本的工程源码,2套工程源码的不同点在于图像缩放后的分辨率不同和视频拼接的方式不同,工程1将输入的1920x1080分辨率视频通过图像缩放模块缩小到960x1080,然后将视频复制两份,用以模拟两路视频输入,做两路视频拼接后在1920x1080分辨率的输出视频上做2分屏拼接显示;工程2将输入的1920x1080分辨率视频通过图像缩放模块缩小到960x480,然后将视频复制4份,用以模拟4路视频输入,做4路视频拼接后在1920x1080分辨率的输出视频上做4分屏拼接显示;FPGA缩放后的视频,用我常用的FDMA套路进行图像缓存,缓存的介质为DDR3,然后读出视频,生成标准的1920x1080分辨率的VGA时序,再用纯verilog实现的RGB转HDMI模块将视频输出到显示器显示;

本博客详细描述了FPGA 图像缩放多路视频拼接的设计方案,工程代码可综合编译上板调试,可直接项目移植,适用于在校学生、研究生项目开发,也适用于在职工程师做学习提升,可应用于医疗、军工等行业的高速接口或图像处理领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后;

版本更新说明

此版本为第2版,根据读者的建议,对第1版工程做了如下改进和更新:
1:增加了输入视频静态彩条的选择,有的读者说他的FPGA开发板没有HDMI输入接口,导致在移植过程中困难很大,基于此,增加了静态彩条,它由FPGA内部产生,不需要外接摄像头就可以使用,使用方法在后文有说明;
2:优化了FDMA,之前的FDMA内AXI4的数据读写突发长度为256,导致在低端FPGA上带宽不够,从而图像质量不佳,基于此,将FDMA内AXI4的数据读写突发长度改为128;
3:优化了HDMI输出模块,之前用的自定义IP,有读者说IP无法更新,虽能正常使用,但看源码不方便,基于此,将HDMI输出模块改为纯verilog实现的,直接了当;

免责声明

本工程及其源码即有自己写的一部分,也有网络公开渠道获取的一部分(包括CSDN、Xilinx官网、Altera官网等等),若大佬们觉得有所冒犯,请私信批评教育;基于此,本工程及其源码仅限于读者或粉丝个人学习和研究,禁止用于商业用途,若由于读者或粉丝自身原因用于商业用途所导致的法律问题,与本博客及博主无关,请谨慎使用。。。

2、相关方案推荐

本工程是图像缩放和视频拼接的整合版,在此之前,我分别推出过FPGA图像缩放方案和FPGA视频拼接方案,所以推荐如下:

FPGA图像缩放方案推荐

该方案使用纯verilog代码实现任意尺寸图像缩放,详细请参考我之前的博客,博客链接如下:
直接点击前往

FPGA视频拼接方案推荐

该方案使用纯verilog代码实现多路视频拼接,详细请参考我之前的博客,博客链接如下:
4路视频拼接方案参考博客链接如下:直接点击前往
8路视频拼接方案参考博客链接如下:直接点击前往
16路视频拼接方案参考博客链接如下:直接点击前往

3、设计思路框架

视频源有两种,分别对应开发者手里有没有摄像头的情况,一种是使用板载的HDMI输入接口(笔记本电脑模拟HDMI输入),使用IT6802解码芯片将TMDS的差分HDMI视频解码为24位的RGB视频数据供FPGA使用;如果你的FPGA开发板没有HDMI输入接口,则可使用代码内部生成的动态彩条模拟摄像头视频;视频源的选择通过代码顶层的`define宏定义进行选择,上电默认使用HDMI输入作为视频源;提供2套vivado2019.1版本的工程源码,2套工程源码的不同点在于图像缩放后的分辨率不同和视频拼接的方式不同,工程1将输入的1920x1080分辨率视频通过图像缩放模块缩小到960x1080,然后将视频复制两份,用以模拟两路视频输入,做两路视频拼接后在1920x1080分辨率的输出视频上做2分屏拼接显示;工程2将输入的1920x1080分辨率视频通过图像缩放模块缩小到960x480,然后将视频复制4份,用以模拟4路视频输入,做4路视频拼接后在1920x1080分辨率的输出视频上做4分屏拼接显示;FPGA缩放后的视频,用我常用的FDMA套路进行图像缓存,缓存的介质为DDR3,然后读出视频,生成标准的1920x1080分辨率的VGA时序,再用纯verilog实现的RGB转HDMI模块将视频输出到显示器显示;
工程1设计框图如下:
在这里插入图片描述
工程2设计框图如下:
在这里插入图片描述

视频源选择

视频源有两种,分别对应开发者手里有没有摄像头的情况,一种是使用板载的HDMI输入接口(笔记本电脑模拟HDMI输入),使用IT6802解码芯片将TMDS的差分HDMI视频解码为24位的RGB视频数据供FPGA使用;如果你的FPGA开发板没有HDMI输入接口,则可使用代码内部生成的动态彩条模拟摄像头视频;视频源的选择通过代码顶层的宏定义进行选择,上电默认使用HDMI输入作为视频源;视频源的选择通过代码顶层的`define宏定义进行;如下:
在这里插入图片描述
视频源选择逻辑代码部分如下:
在这里插入图片描述
选择逻辑如下:
当(注释) define USE_SENSOR时,输入源视频是动态彩条;
当(不注释) define USE_SENSOR时,输入源视频是HDMI;

IT6802解码芯片配置及采集

IT6802解码芯片需要i2c配置才能使用,关于IT6802解码芯片的配置和使用,请参考我往期的博客,博客地址:点击直接前往
IT6802解码芯片配置及采集这两部分均用verilog代码模块实现,代码位置如下:
在这里插入图片描述
代码中配置为1920x1080分辨率;

动态彩条

动态彩条可配置为不同分辨率的视频,视频的边框宽度,动态移动方块的大小,移动速度等都可以参数化配置,我这里配置为辨率1280x720,动态彩条模块代码位置和顶层接口和例化如下:
在这里插入图片描述
在这里插入图片描述

缓冲FIFO

缓冲FIFO的作用是为了解决跨时钟域的问题,当视频不进行缩放时不存在视频跨时钟域问题,但当视频缩小或放大时就存在此问题,用FIFO缓冲可以使图像缩放模块每次读到的都是有效的输入数据,注意,原视频的输入时序在这里就已经被打乱了;

图像缩放模块详解

设计框图

本设计将常用的双线性插值和邻域插值算法融合为一个代码中,通过输入参数选择某一种算法;代码使用纯verilog实现,没有任何ip,可在Xilinx、Intel、国产FPGA间任意移植;代码以ram和fifo为核心进行数据缓存和插值实现,设计架构如下:
在这里插入图片描述
视频输入时序要求如下:
在这里插入图片描述
输入像素数据在dInValid和nextDin同时为高时方可改变;
视频输出时序要求如下:
在这里插入图片描述
输出像素数据在dOutValid 和nextdOut同时为高时才能输出;

代码框图

代码使用纯verilog实现,没有任何ip,可在Xilinx、Intel、国产FPGA间任意移植;
图像缩放的实现方式很多,最简单的莫过于Xilinx的HLS方式实现,用opencv的库,以c++语言几行代码即可完成,关于HLS实现图像缩放请参考我之前写的文章HLS实现图像缩放
网上也有其他图像缩放例程代码,但大多使用了IP,导致在其他FPGA器件上移植变得困难,通用性不好;相比之下,本设计代码就具有通用性;代码架构如图;
在这里插入图片描述
其中顶层接口部分如下:
在这里插入图片描述

2种插值算法的整合与选择

本设计将常用的双线性插值和邻域插值算法融合为一个代码中,通过输入参数选择某一种算法;
具体选择参数如下:

input  wire i_scaler_type //0-->bilinear;1-->neighbor

通过输入i_scaler_type 的值即可选择;

输入0选择双线性插值算法;
输入1选择邻域插值算法;

关于这两种算法的数学差异,请参考我之前写的文章HLS实现图像缩放

视频拼接算法

视频拼接方案如下:以工程2的4路OV5640摄像头拼接为例;
在这里插入图片描述
输出屏幕分辨率为1920X1080;
输入摄像头分辨率为960X540;
4路输入刚好可以占满整个屏幕;
多路视频的拼接显示原理如下:
在这里插入图片描述
以把 2 个摄像头 CAM0 和 CAM1 输出到同一个显示器上为列,为了把 2 个图像显示到 1 个显示器,首先得搞清楚以下关系:
hsize:每 1 行图像实际在内存中占用的有效空间,以 32bit 表示一个像素的时候占用内存大小为 hsize4;
hstride:用于设置每行图像第一个像素的地址,以 32bit 表示一个像素的时候 v_cnt
hstride4;
vsize:有效的行;
因此很容易得出 cam0 的每行第一个像素的地址也是 v_cnt
hstride4;
同理如果我们需要把 cam1 在 hsize 和 vsize 空间的任何位置显示,我们只要关心 cam1 每一行图像第一个像素的地址,可以用以下公式 v_cnt
hstride*4+offset;
uifdma_dbuf 支持 stride 参数设置,stride 参数可以设置输入数据 X(hsize)方向每一行数据的第一个像素到下一个起始像素的间隔地址,利用 stride 参数可以非常方便地摆放输入视频到内存中的排列方式。
关于uifdma_dbuf,可以参考我之前写的文章点击查看:FDMA实现视频数据三帧缓存
根据以上铺垫,每路摄像头缓存的基地址如下:
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;
地址设置完毕后基本就完事儿了;

图像缓存

经常看我博客的老粉应该都知道,我做图像缓存的套路是FDMA,他的作用是将图像送入DDR中做3帧缓存再读出显示,目的是匹配输入输出的时钟差和提高输出视频质量,关于FDMA,请参考我之前的博客,博客地址:点击直接前往
这里多路视频拼接时,调用多路FDMA进行缓存,具体讲就是每一路视频调用1路FDMA,以4路视频拼接为例:
调用4路FDMA,其中三路配置为写模式,因为这三路视频在这里只需要写入DDR3,读出是由另一个FDMA完成,配置如下:
在这里插入图片描述
另外1路FDMA配置为读写模式,因为4路视频需要同时一并读出,配置如下:
在这里插入图片描述
视频拼接的关键点在于4路视频在DDR3中缓存地址的不同,还是以4路视频拼接为例,4路FDMA的写地址以此为:
第一路视频缓存写基地址:0x80000000;
第二路视频缓存写基地址:0x80000f00;
第三路视频缓存写基地址:0x803f4800;
第四路视频缓存写基地址:0x803f5700;
视频缓存读基地址:0x80000000;

视频输出

视频从FDMA读出后,经过VGA时序模块和HDMI发送模块后输出显示器,代码位置如下:
在这里插入图片描述
VGA时序配置为1280X720,HDMI发送模块采用verilog代码手写,可以用于FPGA的HDMI发送应用,关于这个模块,请参考我之前的博客,博客地址:点击直接前往

4、vivado工程1:2路视频缩放拼接

开发板FPGA型号:Xilinx–Kintex7–xc7k325tffg676-2;
开发环境:Vivado2019.1;
输入:HDMI(IT6802解码)或动态彩条,分辨率1920x1080;
输出:HDMI,1080P分辨率下的显示2路拼接视频;
工程应用:FPGA 图像缩放多路视频拼接;
工程BD如下:
在这里插入图片描述
工程代码架构如下:
在这里插入图片描述
工程的资源消耗和功耗如下:
在这里插入图片描述

5、vivado工程2:4路视频缩放拼接

开发板FPGA型号:Xilinx–Kintex7–xc7k325tffg676-2;
开发环境:Vivado2019.1;
输入:HDMI(IT6802解码)或动态彩条,分辨率1920x1080;
输出:HDMI,1080P分辨率下的显示4路拼接视频;
工程应用:FPGA 图像缩放多路视频拼接;
工程BD如下:
在这里插入图片描述
工程代码架构如下:
在这里插入图片描述
工程的资源消耗和功耗如下:
在这里插入图片描述

6、工程移植说明

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软核;

7、上板调试验证并演示

准备工作

你需要有以下装备才能移植并测试该工程代码:
1:FPGA开发板;
2:板载的HDMI输入接口,如果没有也可以,就选择动态彩条;
3:HDMI传输线;
4:HDMI显示,要求分辨率支持1920x1080;

静态演示

工程1:HDMI(IT6802解码)1920x1080输入缩放到960x1080后2路视频拼接2分屏输出如下:
在这里插入图片描述
工程1:动态彩条1920x1080输入缩放到960x1080后2路视频拼接2分屏输出如下:
在这里插入图片描述
工程2:HDMI(IT6802解码)1920x1080输入缩放到960x540后4路视频拼接4分屏输出如下:
在这里插入图片描述
工程2:动态彩条1920x1080输入缩放到960x540后4路视频拼接4分屏输出如下:
在这里插入图片描述

动态演示

动态视频演示如下:

FPGA-视频缩放拼接-HDMI-2023

8、福利:工程源码获取

福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:私,或者文章末尾的V名片。
网盘资料如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1049911.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PIE:1979-2018年中国气温数据产品(空间分辨率为0.1º)

简介 中国气温数据产品包含1979-2018年期间中国的近地表气温数据(单位为摄氏度),时间分辨率为每日,空间分辨率为0.1。本产品集成了再分析数据(ERA5、CMFD)、遥感数据(MODIS)、原位数…

RISC-V架构的函数调用规范和栈布局

1、函数调用中寄存器规范 2、函数调用规范 (1)函数的前8个参数使用a0-a7寄存器传递,如果传参多于8个,则除前8个参数使用寄存器来传递之外,后面的参数使用栈传递; (2)如果传递的参数小…

《学术小白学习之路10》论文常见方法:Doc2vec-句向量模型实现

1. 数据 用于文献的摘要的相似度的计算 ## 导包 import pandas as pd import jieba import gensim from gensim.models import Doc2Vec from gensim.models.doc2vec import TaggedDocument再定义停用词典,用于分词,还可以自己定义一个分词词典 ## 读入数据 papers = pd.&l…

TensorFlow入门(一、环境搭建)

一、下载安装Anaconda 下载地址:http://www.anaconda.comhttp://www.anaconda.com 下载完成后运行exe进行安装 二、下载cuda 下载地址:http://developer.nvidia.com/cuda-downloadshttp://developer.nvidia.com/cuda-downloads 下载完成后运行exe进行安装 安装后winR cmd进…

解密PDF密码

PDF文件有两种密码,一个打开密码、一个限制编辑密码,因为PDF文件设置了密码,那么打开、编辑PDF文件就会受到限制。忘记了PDF密码该如何解密? PDF和office一样,可以对文件进行加密,但是没有提供恢复密码的功…

解决craco启动react项目卡死在Starting the development server的问题

现象: 原因:craco.config.ts配置文件有问题 经过排查发现Dev开发模式下不能有splitChunk的配置, 解决办法: 加一个生产模式的判断,开发模式不加载splitChunk的配置,仅在生产模式才加载 判断条件代码&#…

基于微信小程的流浪动物领养小程序设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能:具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

安防监控产品经营商城小程序的作用是什么

安防监控产品覆盖面较大,监控器、门禁、对讲机、烟感等都有很高用途,家庭、办公单位各场景往往用量不少,对商家来说,市场高需求背景下也带来了众多生意,但线下门店的局限性,导致商家想要进一步增长不容易。…

进阶指针(二)

#国庆发生的那些事儿# ✨博客主页:小钱编程成长记 🎈博客专栏:进阶C语言 🎈推荐相关博文:进阶指针(一) 进阶指针(二) 6.函数指针数组6.1例子 7.指向函数指针数组的指针8.…

OpenHarmony自定义组件介绍

一、创建自定义组件 在ArkUI中,UI显示的内容均为组件,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。在进行 UI 界面开发时,通常不是简单的将系统组件进行组合使用,而是需要考虑代码可复用性、业务逻辑…

四、YApi的安装和配置

YApi是去哪儿网的前端技术中心的一个开源可视化接口管理平台。 创建接口项目 创建接口 编写接口

中文读唇总动员:CNVSRC 2023 视觉语音识别挑战赛启动

由 NCMMSC 2023 组委会发起,清华大学、北京邮电大学、海天瑞声、语音之家共同主办的 CNVSRC 2023 中文连续视觉语音识别挑战赛即日启动,诚邀参与报名。 赛事官网:http://cnceleb.org/competition 视觉语音识别,也称唇语识别&…

为什么我的Windows 10笔记本电脑明明什么软件都没开,风扇却一直在转?

2023年9月29日,周五上午 这两天我的笔记本电脑一开机,风扇就一直在转,而且还没停过,挺吵的 即使什么软件都没开,还在那转,莫名其妙的。 后来我去任务管理器按照CPU使用情况来排序,发现原来是W…

如何自动转发接收的请求报头?

了解OpenTelemetry的朋友应该知道,为了将率属于同一个请求的多个操作(Span)串起来,上游应用会生成一个唯一的TraceId。在进行跨应用的Web调用时,这个TraceId和代表跟踪操作标识的SpanID一并发给目标应用,W3…

经过认证的工具链对安全关键型应用意味着什么?

作者:IAR 安全关键型应用,在很多人看来是个专业的词汇,但其实它离我们的日常生活很近,比如汽车驾驶系统、飞机控制系统、电梯运行系统、医疗设备等与我们息息相关的事物都可以纳入安全关键型应用的范畴。 对于这类应用&#xff…

SAP入门到放弃系列之QM检验计划-Part1

文章目录 一、概述1.1、检验计划抬头1.2、检验计划工序 二、系统操作2.1、测试数据准备:2.2、创建检验计划 一、概述 检验计划是用来描述如何对一种或多种物料进行质量检验操作的主数据。在检验计划中,可以定义检验的工序顺序以及可用于检验特征的数据规…

排序:归并(Merge)排序算法分析

1.归并操作 归并:把两个或多个已经有序的序列合并成一个。 2路归并:二合一k路归并:k合一结论:m路归并,每选出一个元素需要对比关键字m-1次。 2.算法思想 核心操作:把数组内的两个有序序列归并为一个。 例如: 3.代码实现 将…

数据集笔记: Porto

数据来源:Taxi Trajectory Data_数据集-阿里云天池 (aliyun.com) 1 数据介绍 葡萄牙波尔图市运行的所有442辆出租车的全年轨迹(从2013年7月1日至2014年6月30日) 2 读取数据 import pandas as pdtrapd.read_csv(C:/Users/16000/Download…

C语言中动态内存管理

前言:为什么存在动态内存分配,为什么要用动态内存分配,动态内存分配的意义。鸡汤:有了坚持不一定成功,但没有坚持,就注定失败,各位也要努力坚持提升自己! 动态内存分配 动态内存函数&#xff1a…

【Linux】 du 命令使用

问题 No space left on device 请求接口返回 java.io.IOException: No space left on device 设备上没有剩余空间 怎么解决问题: 查看这篇文章:一次 linux 服务器磁盘使用情况排查 我们提到命令:du -sh * 到底这个命令是干什么的咱们…