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,可以自行修改,选择从外部传入参数,控制旋转角度
五、上板验证
视频旋转效果图如下



相关文章:
FPGA实现任意角度视频旋转(完结)视频任意角度旋转实现
本文主要介绍如何基于FPGA实现视频的任意角度旋转,关于视频180度实时旋转、90/270度视频无裁剪旋转,请见本专栏前面的文章,旋转效果示意图如下: 为了实时对比旋转效果,采用分屏显示进行处理,左边代表旋转…...
openlayer getLayerById 根据id获取layer图层
背景: 在项目中使用getLayerById获取图层,这个getLayerById()方法不是openlayer官方文档自带的,而是自己封装的一个方法,这个封装的方法的思路是:遍历所有的layer,根据唯一标识【可能是id,也可能…...
【Jave全栈】Java与JavaScript比较
文章目录 前言一、Java1、 历史与背景2、语言特点3、应用场景4、生态系统 二、JavaScript1、历史与背景2、语言特点3、应用场景4、 生态系统 三、相同点四、不同点1、语言类型2、用途3、语法和结构4、性能5、生态系统6、开发模式 前言 Java和JavaScript是两种不同的编程语言&a…...
设计模式-建造者模式、原型模式
目录 建造者模式 定义 类图 优缺点 角色 建造者模式和工厂模式比较 使用案例 原型模式 定义 类图 优缺点 应用场景 应用类型 浅克隆 深克隆 建造者模式 定义 将一个复杂的对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,…...
PTMD2.0-疾病相关的翻译后修饰数据库
翻译后修饰(PTMs,post-translational modifications)通过调节蛋白质功能参与了几乎所有的生物学过程,而 PTMs 的异常状态常常与人类疾病相关。在此,PTMD 2.0展示与疾病相关的 PTMs 综合数据库,其中包含 93 …...
【Git版本控制器--3】Git的远程操作
目录 理解分布式版本控制系统 创建远程仓库 仓库被创建后的配置信息 克隆远程仓库 https克隆仓库 ssh克隆仓库 向远程仓库推送 拉取远程仓库 忽略特殊文件 为什么要忽略特殊文件? 如何配置忽略特殊文件? 配置命令别名 标签管理 理…...
批量创建ES索引
7.x from elasticsearch import Elasticsearch# 配置 Elasticsearch 连接 # 替换为你的 Elasticsearch 地址、端口、用户名和密码 es Elasticsearch([http://10.10.x.x:43885],basic_auth(admin, XN272G9THEAPYD5N5QORX3PB1TSQELLB) )# # 测试连接 # try: # # 尝试获取集…...
模块初阶学习
当我们在过去想要实现一个功能时,例如Swap交换函数时,我们需要不断考虑参数的正确与否。如果是在c语言,我们还需要不断更改函数名字,以防止函数名重复。在c我们可以通过函数名重载解决这个问题,但还是有一些小问题&…...
rust学习-rust中的保留字
rust学习-rust中的保留字 已使用的保留字未来可能使用的保留字 保留字是语言中预定义的标识符,不能用作变量名、函数名或其他自定义标识符,Rust的保留字大致可以分为两类:已使用的保留字和未来可能使用的保留字 已使用的保留字 as࿱…...
MySQL中的读锁与写锁:概念与作用深度剖析
MySQL中的读锁与写锁:概念与作用深度剖析 在MySQL数据库的并发控制机制中,读锁和写锁起着至关重要的作用。它们是确保数据在多用户环境下能够正确、安全地被访问和修改的关键工具。 一、读锁(共享锁)概念 读锁,也称为…...
专利申请的价值
独占市场 一种产品只要授权专利权,等于在市场上拥有独占权。 政策奖励 各地方政府均出台响应文件, 对专利申请者进行奖励或者补助。 申报项目 申报高新技术企业、创新基金等 各类计划、项目的必要前提条件 专利申请 技术保护 防止新的技术与产品被他人 抄…...
使用 OpenCV 和 Python 轻松实现人脸检测
目录 一、准备工作 二、加载人脸检测模型 三、读取图像并进行人脸检测 四、处理视频中的人脸检测 五、优化人脸检测效果 六、总结 在人工智能和计算机视觉领域,人脸检测是一项非常基础且重要的技术。通过人脸检测,我们可以在图像或视频中识别并定位人脸,进而进行后续的…...
自然语言处理——从原理、经典模型到应用
1. 概述 自然语言处理(Natural Language Processing,NLP)是一门借助计算机技术研究人类语言的科学,是人工智能领域的一个分支,旨在让计算机理解、生成和处理人类语言。其核心任务是将非结构化的自然语言转换为机器可以…...
kotlin内联函数——runCatching
1.runCatching作用 代替try{}catch{}异常处理,用于捕获异常。 2.runCatching函数介绍 参数:上下文引用对象为参数返回值:lamda表达式结果 调用runCatching函数,如果调用成功则返回其封装的结果,并可回调onSuccess函…...
2025年新开局!谁在引领汽车AI风潮?
汽车AI革命已来。 在2025年伊始开幕的CES展上,AI汽车、AI座舱无疑成为了今年汽车行业的最大热点。其中不少车企在2025年CES上展示了其新一代AI座舱,为下一代智能汽车的人机交互、场景创新率先打样。 其中,东软集团也携带AI驱动、大数据支撑…...
YOLO目标检测3
一. 参考资料 《YOLO目标检测》 by 杨建华博士 本篇文章的主要内容来自于这本书,只是作为学习记录进行分享。 二. 搭建YOLOv1的网络 2.1 YOLOv1的网络结构 作者带我们构建的YOLOv1网络是一个全卷积结构,其中不包含任何全连接层,这一点可以…...
css3 svg制作404页面动画效果HTML源码
源码介绍 css3 svg制作404页面动画效果HTML源码,源码由HTMLCSSJS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果 效果预览 源码如下 <!doctype html> <html> <head> <meta charse…...
LINUX 平台最快子网路由转发,内核使能选项配置
阅读本文之间,可线性参考以下文献。 Linux 命令行配置为单臂旁路由。_linux单臂路由-CSDN博客 Linux 软路由命令行配置(参考)_linux软路由-CSDN博客 VGW在 Windows 平台上局域网就绪的旁路由器程序_windows旁路由-CSDN博客 本文介绍 LINUX…...
「 机器人 」扑翼飞行器混合控制策略缺点浅谈
前言 将基于模型的控制与强化学习策略融合在扑翼飞行器中,虽然能够兼顾系统稳定性与极限机动能力,但也面临了更高的系统复杂性、对硬件算力与可靠性的额外要求,以及难以回避的能量效率等方面挑战。以下从四个方面进行归纳与分析。 1. 系统复杂性增加 1.1 两种控制方法的并存…...
RNN实现阿尔茨海默症的诊断识别
本文为为🔗365天深度学习训练营内部文章 原作者:K同学啊 一 导入数据 import torch.nn as nn import torch.nn.functional as F import torchvision,torch from sklearn.preprocessing import StandardScaler from torch.utils.data import TensorDatase…...
HackTheBox靶机:Sightless;NodeJS模板注入漏洞,盲XSS跨站脚本攻击漏洞实战
HackTheBox靶机:Sightless 渗透过程1. 信息收集常规探测深入分析 2. 漏洞利用(CVE-2022-0944)3. 从Docker中提权4. 信息收集(michael用户)5. 漏洞利用 Froxlor6. 解密Keepass文件 漏洞分析SQLPad CVE-2022-0944 靶机介…...
docker安装elk6.7.1-搜集java日志
docker安装elk6.7.1-搜集java日志 如果对运维课程感兴趣,可以在b站上、A站或csdn上搜索我的账号: 运维实战课程,可以关注我,学习更多免费的运维实战技术视频 0.规划 192.168.171.130 tomcat日志filebeat 192.168.171.131 …...
XML实体注入漏洞攻与防
JAVA中的XXE攻防 回显型 无回显型 cve-2014-3574...
Flutter 与 React 前端框架对比:深入分析与实战示例
Flutter 与 React 前端框架对比:深入分析与实战示例 在现代前端开发中,Flutter 和 React 是两个非常流行的框架。Flutter 是 Google 推出的跨平台开发框架,支持从一个代码库生成 iOS、Android、Web 和桌面应用;React 则是 Facebo…...
使用 Docker Compose 一键启动 Redis、MySQL 和 RabbitMQ
目录 一、Docker Compose 简介 二、服务配置详解 1. Redis 配置 2. MySQL 配置 3. RabbitMQ 配置 三、数据持久化与时间同步 四、部署与管理 五、总结 目录挂载与卷映射的区别 现代软件开发中,微服务架构因其灵活性和可扩展性而备受青睐。为了支持微服务的…...
【问题解决】el-upload数据上传成功后不显示成功icon
el-upload数据上传成功后不显示成功icon 原因 由于后端返回数据与要求形式不符,使用el-upload默认方法调用onSuccess钩子失败,上传文件的状态并未发生改变,因此数据上传成功后并未显示成功的icon标志。 解决方法 点击按钮,调用…...
spring框架之IoC学习与梳理(1)
目录 一、spring-IoC的基本解释。 二、spring-IoC的简单demo(案例)。 (1)maven-repository官网中找依赖坐标。 (2).pom文件中通过标签引入。 (3)使用lombok帮助快速开发。 ÿ…...
MQ的可靠消息投递机制
确保消息在发送、传递和消费过程中不会丢失、重复消费或错乱。 1. 消息的可靠投递 消息持久化: 消息被发送到队列后会存储在磁盘上,即使消息队列崩溃,消息也不会丢失。例如:Kafka、RabbitMQ等都支持持久化消息。Kafka通过将消息存…...
Mono里运行C#脚本35—加载C#语言基类的过程
前面大体地分析了整个Mono运行过程,主要从文件的加载,再到EXE文件的入口点, 然后到方法的编译,机器代码的生成,再到函数调用的跳板转换,进而解析递归地实现JIT。 但是还有很多功能没有解析的,就是C#语言相关最多的,就是类的加载,以及类语言设计的实现属性, 比如类的…...
location+rewrite实现隐性域名配置
隐性域名:访问www.a.com 则跳转到www.b.com的页面,但是地址栏还是显示www.a.com 1、配置基于根目录的隐性域名(就是nginx反向代理) 访问http://www.bbb.org:8002, 跳转http://www.accp.org:8001的页面,地址…...
