跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

FPGA 任意角度图像旋转实现原理

基于 FPGA 实现任意角度图像旋转的原理与设计思路。主要利用 CORDIC 算法获取正余弦值,通过坐标变换公式计算旋转后像素位置。设计包含四级流水线:计算新图像尺寸、确定有效显示区域、行场计数、坐标映射及 ROM 数据读取。最终在 LCD 屏幕上实现了不同角度的图像旋转效果,验证了算法的正确性。

极光发布于 2026/4/5更新于 2026/10/26111 浏览

概述

图像旋转的本质是实现坐标变换公式。基于 CORDIC 算法获取正余弦数值后,即可进行旋转计算。

图像旋转代码设计思路

2.1 旋转后的图像尺寸

图像旋转后像素位置发生变化,总像素面积不变但显示范围需调整。通常以原始图像对角线长度作为旋转后图像的显示范围,确保完整显示。

reg [12:0] row_size ; reg [12:0] col_size ; assign Pixel_X = row_size ; assign Pixel_Y = col_size ; wire [31:0] cosout_abs = (cosout[31]) ? -cosout : cosout; wire [31:0] sinout_abs = (sinout[31]) ? -sinout : sinout; always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) begin row_size <= 'd0 ; col_size <= 'd0 ; end else begin // h --> row // w --> col row_size <= (ROW*cosout_abs + COL*sinout_abs) >>14 ; // h col_size <= (COL*cosout_abs + ROW*sinout_abs) >>14 ; // w end end 

2.2 旋转后图像的有效位置

旋转后的有效位置可自由设定,此处设定为屏幕中心位置。具体设计如下:

//parameter define localparam H_SYNC = 11'd41 , //行同步 H_BACK = 11'd2 , //行时序后沿 H_LEFT = 11'd0 , //行时序左边框 H_VALID = 11'd480 , //行有效数据 H_RIGHT = 11'd0 , //行时序右边框 H_FRONT = 11'd2 , //行时序前沿 H_TOTAL = 11'd525 ; //行扫描周期 localparam V_SYNC = 11'd10 , //场同步 V_BACK = 11'd2 , //场时序后沿 V_TOP = 11'd0 , //场时序左边框 V_VALID = 11'd272 , //场有效数据 V_BOTTOM = 11'd0 , //场时序右边框 V_FRONT = 11'd2 , //场时序前沿 V_TOTAL = 11'd286 ; //场扫描周期 //cnt_h:行扫描计数器 //cnt_v:场扫描计数器 //data_req:数据请求信号 wire data_req = (((cnt_h >= (((H_VALID - Pixel_X)>>1) + H_SYNC + H_BACK - 'd5)) && (cnt_h < (((H_VALID - Pixel_X)>>1) + Pixel_X + H_SYNC + H_BACK - 'd5))) &&((cnt_v >= ((V_VALID - Pixel_Y)>>1) + V_SYNC + V_BACK - 'd5) && ((cnt_v < (((V_VALID - Pixel_Y)>>1) + Pixel_Y + V_SYNC + V_BACK - 'd5)))));

2.3 第一级流水线

在图像有效信号有效时进行行场计数。

always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) r_rotate_valid <= 1'b0 ; else r_rotate_valid <= data_req ; end always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) r_rotate_end <= 'd0 ; else if (r_rotate_valid && (vcnt == row_abs - 1) && (hcnt == col_abs - 2)) r_rotate_end <= 'd1 ; else r_rotate_end <= 'd0 ; end always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) hcnt <= 'd0 ; else if (r_rotate_valid && (r_rotate_end || (hcnt == col_abs - 1))) hcnt <= 'd0 ; else if (r_rotate_valid) hcnt <= hcnt + 'd1 ; end always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) vcnt <= 'd0 ; else if (r_rotate_valid && r_rotate_end) vcnt <= 'd0 ; else if (r_rotate_valid && (hcnt == col_abs - 1)) vcnt <= vcnt + 'd1 ; end

2.4 第二级流水线

计算图像旋转公式。以中心点为起始坐标,相当于坐标系的 (0,0) 点,四个象限的所有坐标点均可表示。按照公式组合起来即可,最终右移 14 位。

reg signed [12:0] x_cos ; reg signed [12:0] y_sin ; reg signed [12:0] y_cos ; reg signed [12:0] x_sin ; assign row_abs = row_size; assign col_abs = col_size; // 得到旋转后图片的中点 assign row1 = row_abs >> 1 ; assign col1 = col_abs >> 1 ; always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) x_cos <= 'd0 ; else if(r_rotate_valid_1d) x_cos <= ((hcnt - col1 ) * cosout) >>>14; else x_cos <= x_cos ; end always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) y_sin <= 'd0 ; else if(r_rotate_valid_1d) y_sin <= ((vcnt-row1 ) * sinout) >>>14; else y_sin <= y_sin ; end always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) y_cos <= 'd0 ; else if(r_rotate_valid_1d) y_cos <= ((vcnt - row1 ) * cosout) >>>14; else y_cos <= y_cos ; end always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) x_sin <= 'd0 ; else if(r_rotate_valid_1d) x_sin <= ((hcnt - col1 ) * sinout) >>>14; else x_sin <= x_sin ; end

2.5 第三级流水线

按照公式进行排列组合得出旋转后图像映射到原始图像的坐标位置。原始屏幕坐标转换到中心坐标系 -> 应用旋转公式 -> 转换回屏幕坐标系。

always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) r_rotate_valid_2d <= 'd0 ; else r_rotate_valid_2d <= r_rotate_valid_1d ; end always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) hcnt_rotate <= 'd0 ; else if(r_rotate_valid_2d==1'b1) hcnt_rotate <= x_cos - y_sin + (COL>>1 ) ; else hcnt_rotate <= 'd0 ; end always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) vcnt_rotate <= 'd0 ; else if(r_rotate_valid_2d==1'b1) vcnt_rotate <= y_cos + x_sin + (ROW>>1) ; else vcnt_rotate <= 'd0 ; end

2.6 第四级流水线

  • hcnt_rotate在 0 到 COL-1 之间(在原图像列范围内)
  • vcnt_rotate在 0 到 ROW-1 之间(在原图像行范围内)
  • 已读取的像素数小于图像总像素数(ROW*COL)
  • 每行有 COL 个像素,所以第 vcnt_rotate 行的起始地址是 COL*vcnt_rotate
  • 再加上该行内的列偏移 hcnt_rotate

data_cnt计数器用于限制读取的像素总数不超过原图像的总像素数。最后连接一个 ROM IP 核,里面存放着预先处理好的图像数据,生成地址和使能信号读就可以了。ROM 读出数据是延迟一个时钟,所以第五级流水就是为了对齐而已。

always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) r_rotate_valid_3d <= 'd0 ; else r_rotate_valid_3d <= r_rotate_valid_2d ; end always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) begin rden <= 'd0 ; addra <= 'd0 ; end else if(r_rotate_valid_3d==1'b1) begin if((hcnt_rotate>='d0)&&(hcnt_rotate<COL)&&(vcnt_rotate>='d0)&&(vcnt_rotate<ROW)&&data_cnt<ROW*COL) begin // start_dly3 rden <= 1'b1 ; addra<= COL*vcnt_rotate + hcnt_rotate ; end else begin rden <= 1'b0 ; addra<= 'd0 ; end end else begin rden <= 'd0 ; addra <= 'd0 ; end end always @(posedge clk_i, negedge rstn_i) begin if (!rstn_i) data_cnt <= 'd0 ; else if (data_cnt == ROW*COL - 1) data_cnt <= 'd0 ; else if (r_rotate_valid_3d && (hcnt_rotate>='d0)&&(hcnt_rotate<COL)&&(vcnt_rotate>='d0)&&(vcnt_rotate<ROW)) data_cnt <= data_cnt + 'd1 ; end img_mem_gen img_mem_gen_inst ( .address ( addra ), .clock ( clk_i ), .rden ( rden ), .q ( rom_data ) );

仿真结果

30°旋转

30 度旋转

图片横着看,逆时钟旋转 30°的。

负 30 度

-30°

228 度

228 度 2

228°

228 度 3

228 度 4

任意角度,任意方向,功能正常。

目录

  1. 概述
  2. 图像旋转代码设计思路
  3. 2.1 旋转后的图像尺寸
  4. 2.2 旋转后图像的有效位置
  5. 2.3 第一级流水线
  6. 2.4 第二级流水线
  7. 2.5 第三级流水线
  8. 2.6 第四级流水线
  9. 仿真结果

更多推荐文章

查看全部
  • 统信 UOS V2500 服务器 OpenClaw AI Agent 安装部署指南
  • LLaMA Factory 在国产 DCU 上微调 Llama 3 模型实战
  • Discord 机器人创建流程指南
  • 在 Cursor 中从零安装 Manim 制作数学动画
  • FPGA 简介及开发流程
  • Nanbeige4.1-3B 多场景落地实践:教育问答、代码辅助与智能写作
  • 网络安全入门:黑客必须掌握的核心技术与技能体系
  • 5 款好用的免费在线代码编辑器
  • Vue Router 进阶使用指南:导航守卫与状态管理
  • 积木报表快速入门指南:从零开始创建数据可视化报表
  • DeepSeek 与通义万相结合制作 AI 视频实战指南
  • API 设计的 7 个常见错误及最佳实践指南
  • Xilinx Vivado 付费 IP 核 License 状态解读与获取
  • Windows 本地部署 OpenClaw 并配置 Telegram 机器人及网页搜索功能
  • Electron 一小时快速上手指南:前端桌面应用开发教程
  • 向日葵 MCP 接入 AI:无需额外设备支持多平台远程控制
  • Unity-MCP 使用指南:让 AI 连接并控制 Unity 编辑器
  • 基于动态反演和扩展状态观测器的无人机鲁棒反馈线性化自适应姿态控制器
  • AI 编程工具选型指南:Copilot、Cursor 与 Trae 实战对比
  • Dell R 系列服务器硬件整合后开机报错解决方案

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online