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

ops/2025/2/4 2:06:53/

本文主要介绍如何基于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.ppmy.cn/ops/155444.html

相关文章

TypeScript 学习 -代码检查工具 eslint

代码检查工具 尽管 TypeScript 提供了类型检查和静态分析功能,使用 ESLint 仍然能带来很多好处,特别是当需要确保代码质量、遵循一致的代码风格、避免潜在的错误和提高团队协作时。ESLint 和 TypeScript 是互补的工具,它们共同帮助你保持高质…

浅析服务器虚拟化技术

服务器虚拟化技术是现代信息技术领域的一项重要创新,通过将物理服务器的硬件资源(如CPU、内存、存储和网络)抽象化,实现多个虚拟服务器(虚拟机,VMs)的运行。这种技术不仅提高了资源利用率,还简化了管理流程,降低了成本,并为云计算和大数据发展提供了坚实的基础。以下…

深度学习 DAY3:NLP发展史(全网最全)

NLP发展史 NLP发展脉络简要梳理如下: (远古模型,上图没有但也可以算NLP) 1940 - BOW(无序统计模型) 1950 - n-gram(基于词序的模型) (近代模型) 2001 - Neural language models&am…

Mask R-CNN与YOLOv8的区别

Mask R-CNN与YOLOv8虽然都是深度学习在计算机视觉领域的应用,但它们属于不同类型的视觉框架,各有特点和优势。 以下是关于 Mask R-CNN 和 YOLOv8 的详细对比分析,涵盖核心原理、性能差异、应用场景和选择建议: 1. 核心原理与功能…

系统URL整合系列视频一(需求方案)

视频 系统URL整合系列视频一(需求方案) 视频介绍 (全国)某大型分布式系统Web资源URL整合需求实现方案讲解。当今社会各行各业对软件系统的web资源访问权限控制越来越严格,控制粒度也越来越细。安全级别提高的同时也增…

如何配置Java JDK

步骤1:点击资源,点击Java下载 https://www.oracle.com/ 步骤2:点击java下载、JDK23下载,下载第一行第一个 步骤3:解压到一个空文件夹下,复制lib地址 步骤4:在设置里面搜索“高级系统设置”;点击…

Python NumPy(7):连接数组、分割数组、数组元素的添加与删除

1 连接数组 函数描述concatenate连接沿现有轴的数组序列stack沿着新的轴加入一系列数组。hstack水平堆叠序列中的数组(列方向)vstack竖直堆叠序列中的数组(行方向) 1.1 numpy.concatenate numpy.concatenate 函数用于沿指定轴连…

ARM嵌入式学习--第十二天(WDOG,RTC)

--WDOG -介绍 WatchDog是为了能够防止程序跑飞而使用的一种硬件模块,如果你的程序没有跑飞,那么你的程序会定时的去喂看门狗;如果你的程序跑飞了,那么就不会再去喂狗了,如果超过了喂狗时间,那么狗就会自己…