目录

  • 1、前言
  • 2、理论基础
  • 3、设计思路和框架
  • 图像输入和采集
  • 图像旋转处理
  • 图像缓存
  • 图像输出
  • 4、vivado工程详解
  • 5、上板调试验证
  • 6、福利:工程代码的获取


1、前言

图像旋转是一种常用的图像处理技术,其基本原理就是指图像以某一点为中心旋转一定的角度,形成一幅新的图像的过程。当然这个点通常就是图像的中心。图像的旋转是图像几何变换的一种,旋转前后的图像的像素的 RGB 都是没有改变的,改变的只是每一个像素的所在位置,这个就是旋转的本质。
本设计采用OV5640摄像头作为输入,分辨率为640x480,也可配置为其他分辨率,输出HDMI,分辨率为1024x768@60Hz。图像缓存至DDR做旋转变换,旋转角度由串口命令控制,实用性很强,高度贴近真实项目,希望对你有用。
本文详细描述了设计方案,工程代码编译通过后上板调试验证,可直接项目移植,适用于在校学生、研究生项目开发,也适用于在职工程师做项目开发,可应用于医疗、军工等行业的数字成像和图像传输领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后;

2、理论基础

图像旋转是指图像以某一点为中心旋转一定的角度,形成一幅新的图像的过程。当然这个点通常就是图像的中心。既然是按照中心旋转,自然会有这样一个属性:旋转前和旋转后的点离中心的位置不变。

根据这个属性,我们可以得到旋转后的点的坐标与原坐标的对应关系。由于原图像的坐标是以左上角为原点的,所以我们先把坐标转换为以图像中心为原点。假设原图像的宽为 w,高为 h,(x0,y0)为原坐标内的一点,转换坐标后的点为(x1,y1)。那么不难得到:

x1 = x0 - w/2;y1 = -y0 + h/2;

在新的坐标系下,假设点(x0,y0)距离原点的距离为 r,点与原点之间的连线与 x 轴的夹角为 b,旋转的角度为 a,旋转后的点为(x1,y1),如下图所示。

Cordic旋转迭代verilog代码 verilog图像翻转_图像旋转


那么有以下结论:

x0=rcosb;y0=rsinb

x1 = rcos(b-a) = rcosbcosa+rsinbsina=x0cosa+y0sina;

y1=rsin(b-a)=rsinbcosa-rcosbsina=-x0sina+y0cosa;

得到了转换后的坐标,我们只需要把这些坐标再转换为原坐标系即可。这里还有一点要注意,旋转后的图像的长和宽会发生变化,因此要计算新图像的长和宽。

3、设计思路和框架

设计思路和框架如下:

Cordic旋转迭代verilog代码 verilog图像翻转_图像旋转_02

图像输入和采集

本设计采用OV5640摄像头作为输入,分辨率为640x480,也可配置为其他分辨率,OV5640需要i2c配置才能使用,代码里包含了纯verilog的i2c配置,图像采集输出RGB565格式图像数据,图像采集顶层接口如下:

module uiSensorRGB565(
	input         cmos_clk_i  ,//cmos senseor clock.
	input         rst_n_i     ,//system reset.active low.
	input         cmos_pclk_i ,//input pixel clock.
	input         cmos_href_i ,//input pixel hs signal.
	input         cmos_vsync_i,//input pixel vs signal.
	input [7:0]   cmos_data_i ,//data.
	output        cmos_xclk_o ,//output clock to cmos sensor.
    output [15:0] rgb_o       ,
    output        de_o        ,
    output        vs_o        ,
    output        hs_o        
    );

图像旋转处理

本小节内容包括串口解析、旋转参数切换和图像旋转前处理等模块内容。

首先,本设计暂时只支持90°、180°、270°和360°旋转,不支持任意角度旋转;

旋转角度由串口命令控制,控制命令如下:

串口发送0xaa 0xbb 0x00 0x00 0x00 0x01 0x01 0xcc 0xdd 旋转90°;

串口发送0xaa 0xbb 0x00 0x00 0x00 0x02 0x02 0xcc 0xdd 旋转180°;

串口发送0xaa 0xbb 0x00 0x00 0x00 0x04 0x04 0xcc 0xdd 旋转270°;

串口发送0xaa 0xbb 0x00 0x00 0x00 0x08 0x08 0xcc 0xdd 旋转360°;

视频演示使用的串口调试助手配置和指令如下:

Cordic旋转迭代verilog代码 verilog图像翻转_HDMI_03


关于串口指令和解析,请参考我之前写的文章点击查看:串口解析 参数切换模块:根据切换信号来切换输出到各个模块的参数。

图像旋转前处理模块:根据切换信号对 ram 中的数据进行调度,以方便 ddr 控制器模块的使用。

图像缓存

调用MIG实现图像到DDR3的乒乓缓存,这里用到的是纯净的MIG,并未用到我常用的FDMA+AXI MIG方案,直接调用MIG更为简单;
想了解FDMA+AXI MIG图像缓存方案的可以参考我之前写的文章点击查看:FDMA+AXI MIG

图像输出

图像输出采用HDMI发送,分辨率为1024x768@60Hz,HDMI由silicon9134芯片编码,silicon9134需要i2c配置才能使用,代码里包含了纯verilog的i2c配置,想了解silicon9134芯片配置的可以参考我之前写的文章点击查看:silicon9134

4、vivado工程详解

开发板:Xilinx Artix7-35T开发板;

开发环境:vivado2019.1;

输入:OV5640摄像头,分辨率640x480;

输出:HDMI,辨率为1024x768@60Hz,silicon9134编码;

工程代码架构如下:

Cordic旋转迭代verilog代码 verilog图像翻转_图像旋转_04


FPGA资源消耗和功耗预估如下:

Cordic旋转迭代verilog代码 verilog图像翻转_Cordic旋转迭代verilog代码_05

5、上板调试验证

Cordic旋转迭代verilog代码 verilog图像翻转_fpga开发_06


演示视频如下:

FPGA图像视频旋转