当前位置: 首页 > news >正文

FPGA实现任意角度视频旋转(完结)视频任意角度旋转实现

本文主要介绍如何基于FPGA实现视频的任意角度旋转,关于视频180度实时旋转、90/270度视频无裁剪旋转,请见本专栏前面的文章,旋转效果示意图如下:
在这里插入图片描述

为了实时对比旋转效果,采用分屏显示进行处理,左边代表旋转前的视频在屏幕中的位置,右边代表旋转后的视频在屏幕中的位置。 分屏显示的实现方式见本专栏前面的文章详解。

本旋转方案不仅仅适用于国产安路FPGA,只有板卡上带有支持AXI4总线操作DDR的IP核,均可以进行方案移植

关于FPGA实现视频180度实时旋转,点击跳转文章链接

关于FPGA实现视频90度/270度无裁剪旋转,点击跳转文章链接

一、前言

  • 后续文章的工程代码不在免费上传至Github,方案是开源的,工程代码可以私信我或者是评论区留言,有偿提供(价格不贵,此文章对应的工程文件为 ¥88)。前面已经发布的文章方案和代码均是开源的,可以直接去github下载。

  • 免费内容太容易被剽窃了,付费是某种意义上的版权保护

  • 付费即意味着责任,有利于提高文章质量、同时也能提高更新动力。

二、设计概述

除去DDR3控制器、FIFO等常用IP,本设计所用到的主要的IP模块如下。

IP功能来源
uidbuf基于FDMA信号时序的缓存控制器
适合用于基于RGB时序的视频数据或者数据流传输
米联客
uiFDMA基于AXI总线的自定义内存控制器
简化AXI总线的控制,完成数据的搬运
米联客
coor_trans旋转坐标计算模块
该模块使用查找表的方式存储了不同角度的sin、cos值
公众号:数字积木
uidbuf_r_active_rotate在uidbuf的基础上进行更改
用于视频任意角度旋转
个人开发
uivtc_video_rotate在uivtc的基础上进行更改
读取两路视频,一路是旋转之前的视频,一路是旋转之后的视频
个人开发
uivtc_reduce_frame_rate在uivtc的基础上进行更改
视频降帧处理,在不改变时钟频率的情况下,通过调整参数改变视频数据读写帧率
个人开发

三、系统实现方案

3.1 理论分析

前文提到对于90/270度比较有规律的旋转,我们可以采用正向映射的方案进行处理,把输入进的待旋转视频数据依次写入旋转后对应的像素点位置。

而对于任意角度旋转,不可以采用正向映射,因为如果采用正向映射,由于计算误差以及像素对应的DDR地址都是一个一个的整数,会导致有些地址没有被填充数据,从而产生空洞。

而逆向映射便不会有这种现象产生,因为我们拿旋转后的图像坐标去对应原图像的像素坐标,即便有计算误差的存在,但是总是可以对应到的,无非就是对应的不是绝对的精确。所以便可以保证旋转后的图像每个地址都被填充了像素数据。

下图给出正向旋转和逆向旋转的区别,实际上板验证和这个结果类似。(该图来自于一篇硕士论文)
在这里插入图片描述

在使用安路的板卡时,其DDR3 IP控制器从发起写请求到一个像素点完全写入需要的时间比从发起读请求到一个像素点数据被读出需要的时间要短很多。所以在相同的分辨率情况下,正向映射可以达到的帧率比逆向映射要高。 在进行移植时,能达到多高的帧率需要自行分析一下。

3.2 数据流

在这里插入图片描述

为了处理输入进的60hz的待旋转视频,视频像素点的数据流如上图所示,其经历了二进二出DDR3,最终输出至显示器进行显示。

  • 第一次写DDR3:在前文90/270度旋转实现方式中提到,在突发传输长度为1的情况下,为了保证每一次只传输一个像素数据,我们把DDR3中存储的128bit数据全部设置为某一个像素点的数据,所以第一次写DDR3的目的是先把视频像素点数据写入DDR3,并且保证一个像素点的数据(16bit)对应DDR3中存储的128bit数据,方便后续一个一个读取像素点。
  • 第一次读DDR3:以一个较低的帧率,根据旋转后的图像坐标去对应原图中的图像坐标,一个一个读取原图中的像素点,如果该像素点对应不到原图像中的坐标,则赋值为16‘hffff,即为白色。
  • 第二次写DDR3:把刚刚经过旋转排列好的像素点再次写入DDR3
  • 第二次读DDR3:以正常的帧率把视频像素数据读出即可。

上述处理的核心在于旋转模块的实现。

3.3 uidbuf_r_active_rotate模块

此模块采用逆向映射的方法,依次计算旋转后的像素点坐标在原图像中的位置,然后通过FDMA读取原图像的数据,实现任意角度的旋转功能,相比于uibuf模块,不同的部分用红框圈出。
在这里插入图片描述
此方案中,使用AXI4总线读写DDR时,AXI4总线的数据宽度为128,像素点的数据位宽为16,由于DDR3采用的是8-bit预取,DDR3的位宽配置为16bit,所以在突发长度为1的情况下,一次可以读出8个16bit数据(128bit),在常规情况下,一次能读出8个像素点数据。

然而,在进行旋转时,为了保证每一次只传输一个像素数据,我们把这128bit全部设置为某一个像素点的数据即可。

该模块中核心的部分在于地址计算以及像素点数据的赋值,详见源代码。

四、移植注意事项

1、本工程视频源输入的视频分辨率为1280×720@60hz

2、此模块实现的是视频自动旋转,每四帧后旋转角度+1,可以自行修改,选择从外部传入参数,控制旋转角度

五、上板验证

视频旋转效果图如下
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

http://www.lryc.cn/news/526491.html

相关文章:

  • CPU 缓存基础知识
  • 微信小程序date picker的一些说明
  • Vue3 + TS 实现批量拖拽 文件夹和文件 组件封装
  • 【Kubernetes】Pod生命周期、初始化容器、主容器
  • 2025牛客寒假训练营1-M题
  • css3 svg制作404页面动画效果HTML源码
  • 序列标注:从传统到现代,NLP中的标签预测技术全解析
  • 软件测试 —— 性能测试(jmeter)
  • python介绍ransac算法拟合圆
  • WPS计算机二级•表格保护与打印
  • Vue组件开发-使用xlsx库导出Excel文件
  • 使用 Pipeline 提高 Redis 批量操作性能
  • 「 机器人 」利用冲程对称性调节实现仿生飞行器姿态与方向控制
  • 第十五届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组
  • 本地大模型编程实战(02)语义检索(1)
  • 自定义命令执行器:C++中命令封装的深度探索(C/C++实现)
  • C语言程序设计十大排序—选择排序
  • C语言初阶牛客网刷题——HJ73 计算日期到天数转换【难度:简单】
  • MATLAB中alphanumericsPattern函数用法
  • 人工智能在教育领域的创新应用与前景展望
  • 约束布局 ConstraintLayout
  • 校园商铺管理系统设计与实现(代码+数据库+LW)
  • react native在windows环境搭建并使用脚手架新建工程
  • vulnhub DC-1靶机 walkthrough
  • 计算机网络 (58)无线局域网WLAN
  • 基于物联网的风机故障检测装置的设计与实现
  • 【AI日记】25.01.25
  • Sourcetree:一款高效便捷的Git版本控制客户端
  • 图像处理算法研究的程序框架
  • GitLab配置免密登录和常用命令