数字图像处理(15):图像平移
(1)图像平移的基本原理:计算每个像素点的移动向量,并将这些像素按照指定的方向和距离进行移动。
(2)平移向量包括水平和垂直分量,可以表示为(dx,dy),其中dx表示水平方向上的移动距离,dy表示垂直方向上的移动距离。
(3)经过平移后,新图像中的每个像素点在原图像中都有对应的像素点。图像平移使用软件开发语言实现很容易,但在FGPA中实现需要考虑缓存。
(4)matlab实现代码:
% 读取图像
% imread函数用于读取图像文件,支持多种格式如BMP、PNG、JPG等
img = imread('1_1920x1080.bmp');% 获取图像尺寸信息
% size函数返回矩阵的维度,对于彩色图像返回[高度 宽度 通道数]
[rows, cols, channels] = size(img);% 创建仿射变换矩阵
% 这里创建的是一个2x3的变换矩阵,用于定义图像的变换方式
% [1 0 300; - 第一行表示x方向的变换:x'= 1*x + 0*y + 300
% 0 1 200] - 第二行表示y方向的变换:y'= 0*x + 1*y + 200
% 这个矩阵表示将图像向右平移300像素,向下平移200像素
M = single([1, 0, 300; 0, 1, 200]);% 执行仿射变换
% affine2d函数用于创建二维仿射变换对象
tform = affine2d(M'); % 注意MATLAB中需要转置变换矩阵
% imwarp函数执行图像变换
% OutputView选项指定输出图像的大小,这里保持与原图相同
res = imwarp(img, tform, 'OutputView', imref2d([rows cols]));% 保存变换后的图像
% imwrite函数将图像保存到文件
% 第一个参数是图像数据,第二个参数是文件名
imwrite(res, 'result.bmp');% 显示结果图像
% figure创建新的图形窗口
figure;
% subplot用于创建子图,这里创建1x2的子图布局
subplot(1,2,1);
imshow(img); % 显示原图
title('原始图像');
subplot(1,2,2);
imshow(res); % 显示变换后的图像
title('变换后的图像');

(5)FPGA仿真实现:
module move
(input wire clk ,input wire reset_n ,input wire [10:0] img_width ,input wire [10:0] img_height ,input wire [10:0] img_x_start ,input wire [10:0] img_y_start ,input wire [23:0] img_data_i ,output wire wr_ready ,output reg valid_o ,output reg [23:0] img_data_o);reg [11:0] h_cnt,v_cnt;always@(posedge clk or negedge reset_n)if(!reset_n)h_cnt <= 12'd0;else if(h_cnt == img_x_start + img_width - 1)h_cnt <= 12'd0;else h_cnt <= h_cnt + 12'd1;always@(posedge clk or negedge reset_n)if(!reset_n) v_cnt <= 12'd0;else if((v_cnt == img_y_start + img_height - 1) && (h_cnt == img_x_start + img_width - 1))v_cnt <= 12'd0;else if(h_cnt == img_x_start + img_width - 1)v_cnt <= v_cnt + 12'd1;else v_cnt <= v_cnt;assign wr_ready = (h_cnt >= img_x_start) && (v_cnt >= img_y_start);always@(posedge clk or negedge reset_n)if(!reset_n)valid_o <= 1'd0;else if((h_cnt < img_width) && (v_cnt < img_height))valid_o <= 1'd1;else valid_o <= 1'd0;always@(posedge clk or negedge reset_n)if(!reset_n)img_data_o <= 24'd0;else if((h_cnt < img_width) && (v_cnt < img_height) && (wr_ready))img_data_o <= img_data_i;else img_data_o <= 24'd0;endmodule
微调读写测试文件后,仿真出来的图像(与matlab仿真结果一致):

(6)FPGA实现
- 查看配置进程:report_property -all [get_runs impl_1]
- 写入DDR3部分不需要修改,可以沿用,但是读取部分需要修改,首先是结束地址,需要适配新的y轴偏移量
axi_ddr3_top axi_ddr3_top_inst (.ddr3_clk (clk_320M ),.reset_n (rst_n ),.pingpang (1'd0 ),.ui_clk (ui_clk ),.ui_rst (ui_rst ),.wr_b_addr (32'd0 ),.wr_e_addr (IMG_LENGTH*IMG_WIDE*4 ),.wr_clk (clk ),.data_wren (data_wren ),.data_wr (data_wr ),.wr_rst (1'd0 ),.rd_b_addr (32'd0 ),.rd_e_addr (IMG_LENGTH*(IMG_WIDE-Y_OFFSET+1)*4 ),.rd_clk (clk_vga_2 ),.data_rden (lie >= Y_OFFSET ),.data_rd (data_rd ),.rd_rst (1'd0 ),.read_enable (1'd1 ),.rd_data_valid (),.ddr3_addr (ddr3_addr ),.ddr3_ba (ddr3_ba ),.ddr3_cas_n (ddr3_cas_n ),.ddr3_ck_n (ddr3_ck_n ),.ddr3_ck_p (ddr3_ck_p ),.ddr3_cke (ddr3_cke ),.ddr3_ras_n (ddr3_ras_n ),.ddr3_reset_n (ddr3_reset_n ),.ddr3_we_n (ddr3_we_n ),.ddr3_dq (ddr3_dq ),.ddr3_dqs_n (ddr3_dqs_n ),.ddr3_dqs_p (ddr3_dqs_p ),.init_calib_complete (init_calib_complete ),.ddr3_cs_n (ddr3_cs_n ),.ddr3_dm (ddr3_dm ),.ddr3_odt (ddr3_odt ) ); -
缓存行数据,使用一个24位,深度位2048的双口RAM去存储从DDR3中读出来的数据,然后在VGA模块扫描到对应位置时输出,即可。
hang_ram_2048 hang_ram_2048_inst (.clka (clk_vga_2 ), .ena (1'd1 ), .wea (lie >= Y_OFFSET && reading ), .addra (buf_wr_addr ), .dina (line_buffer ), .clkb (clk_vga ), .enb (hang >= X_OFFSET ), .addrb (buf_rd_addr ), .doutb (ram_dout ) );always @(posedge clk_vga_2 or negedge init_rst_n) beginif(!init_rst_n) beginlast_data_rd <= 16'd0;buf_wr_addr <= 11'd0;reading <= 1'b0;line_buffer <= 24'd0;endelse beginif(lie >= Y_OFFSET) beginif(!reading) begin // 第一次读取last_data_rd <= data_rd;reading <= 1'b1;endelse begin // 第二次读取line_buffer <= {last_data_rd, data_rd[15:8]};buf_wr_addr <= buf_wr_addr + 11'd1;reading <= 1'b0;endendelse beginbuf_wr_addr <= 11'd0;reading <= 1'd0;endend end// 行缓存读取控制,在这里实现偏移 always @(posedge clk_vga or negedge init_rst_n) beginif(!init_rst_n) buf_rd_addr <= 11'd0;else beginif(display_valid)buf_rd_addr <= buf_rd_addr + 1'd1;else buf_rd_addr <= 11'd0;end endassign display_valid = (hang >= X_OFFSET)&&(lie >= Y_OFFSET); -
最终现象如下:

相关文章:
数字图像处理(15):图像平移
(1)图像平移的基本原理:计算每个像素点的移动向量,并将这些像素按照指定的方向和距离进行移动。 (2)平移向量包括水平和垂直分量,可以表示为(dx,dy)ÿ…...
高级java每日一道面试题-2024年12月08日-JVM篇-什么是类加载器?
如果有遗漏,评论区告诉我进行补充 面试官: 什么是类加载器? 我回答: 在Java高级面试中,类加载器(ClassLoader)是一个重要的概念,它涉及到Java类的加载和初始化机制。以下是对类加载器的详细解释: 定义与作用 类加…...
JAVA子类的无参构造器中第一行的super
在 Java 中,子类的构造器是否需要显式调用 super 取决于父类(超类)的构造器。 如果父类有一个无参构造器: 如果父类有一个无参构造器,那么子类的构造器可以不显式调用 super。在这种情况下,如果子类构造器的…...
mysql程序介绍,选项介绍(常用选项,指定选项的方式,特性),命令介绍(查看,部分命令),从sql文件执行sql语句的两种方法
目录 mysql程序 介绍 选项 介绍 常用选项 指定选项的方式 编辑配置文件 环境变量 选项特性 指定选项 选项名 选项值 命令 介绍 查看客户端命令 tee/notee prompt source system help contents 从.sql文件执行sql语句 介绍 方式 source 从外部直接导入…...
Unity教程(十九)战斗系统 受击反馈
Unity开发2D类银河恶魔城游戏学习笔记 Unity教程(零)Unity和VS的使用相关内容 Unity教程(一)开始学习状态机 Unity教程(二)角色移动的实现 Unity教程(三)角色跳跃的实现 Unity教程&…...
lanqiaoOJ 3744:小蓝的智慧拼图购物 ← pair+优先队列
【题目来源】https://www.lanqiao.cn/problems/3744/learning/【题目描述】 在小蓝的生日那天,他得到了一个由神秘人赠送的拼图游戏,每个拼图都有其特定的价值和相应的优惠券。小蓝决定要买下所有的拼图,但他希望能尽可能地节省花费。小蓝手中…...
Spring Boot教程之二十一:文件处理
Spring Boot – 文件处理 Spring Boot 是一种流行的、基于 Spring 的开源框架,用于开发强大的 Web 应用程序和微服务。由于它建立在 Spring 框架之上,因此它不仅具有 Spring 的所有功能,而且还包括某些特殊功能,例如自动配置、健康…...
【Linux】Linux的基本常识+指令
目录 1. 整体学习思维导图 2. 常见快捷键操作 3. 基本指令 pwd指令 whoami指令 ls 指令 touch指令 cd 指令 Stat 指令 mkdir 指令 alias指令 nano 指令 rmdir 和 rm 指令 man 指令手册 cp 命令 cat/echo/tac 指令 mv 指令 less 指令 head/tail 指令 date…...
Rocky Linux 9.3系统搭建Slurm环境【笔记】
实践环境:Rocky Linux 9.3 [root@m1 ~]# cat /etc/redhat-release Rocky Linux release 9.3 (Blue Onyx) [root@m1 ~]# uname -r 5.14.0-362.8.1.el9_3.x86_64 [root@m1 ~]#主机名和IP ● 控制节点m1:10.1.1.10 ● 计算节点c1:10.1.1.11 ● 计算节点c2:10.1.1.12 一、…...
原生微信小程序使用原子化tailwindcss
这里使用了第三方库来实现:https://weapp-tw.icebreaker.top/ 官方配置步骤一: https://weapp-tw.icebreaker.top/docs/quick-start/native/install 官方配置步骤二:https://weapp-tw.icebreaker.top/docs/quick-start/native/install-plugin 我下面的操作步骤跟官方步骤…...
《掌握Nmap:全面解析网络扫描与安全检测的终极指南》
nmap # 简介(帮助) 用法:nmap [扫描类型] [选项] {目标指定内容} 简介(帮助) 用法:nmap [扫描类型] [选项] {目标指定内容} 一、目标指定: 可以传入主机名、IP 地址、网络等。 例如&a…...
k8s-Informer概要解析(2)
Client-go 主要用在 k8s 控制器中 什么是 k8s Informer Informer 负责与 kubernetes APIServer 进行 Watch 操作,Watch 的资源,可以是 kubernetes 内置资源对象,也可以 CRD。 Informer 是一个带有本地缓存以及索引机制的核心工具包&#x…...
UE5基本数据类型
bool: 表示布尔值,只有两个取值:true 或 false,用于表示逻辑条件。int8: 表示 8 位的有符号整数,范围是 −128−128 到 127127。uint8: 表示 8 位的无符号整数,范围是 00 到 255255。int16: 表示 16 位的有符号整数&am…...
Next.js 系统性教学:中间件与国际化功能深入剖析
更多有关Next.js教程,请查阅: 【目录】Next.js 独立开发系列教程-CSDN博客 目录 一、Next.js 中间件 (Middleware) 功能解析 1.1 什么是中间件? 1.2 Next.js 中间件的工作机制 1.3 中间件的功能应用 身份验证与授权 请求重定向 修改请…...
鸿蒙HarmonyOS元服务应用开发实战完全指导
内容提要 元服务概述 元服务开发流程 第一个元服务开发 元服务部署与运行 一、服务概述 1、什么是元服务 在万物互联时代,人均持有设备量不断攀升,设备种类和使用场景更加多样,使得应用开发、应用入口变得更加复杂。在此背景下&#x…...
CT中的2D、MPR、VR渲染、高级临床功能
CT中的2D、MPR、VR渲染 在CT(计算机断层扫描)中,2D、MPR(多平面重建)、VR(体积渲染)是不同的图像显示和处理技术,它们各自有独特的用途和优势。下面分别介绍这三种技术:…...
利用docker-compose来搭建flink集群
1.前期准备 (1)把docker,docker-compose,kafka集群安装配置好 参考文章: 利用docker搭建kafka集群并且进行相应的实践-CSDN博客 这篇文章里面有另外两篇文章的链接,点进去就能够看到 (2&…...
力扣打卡10:K个一组翻转链表
链接:25. K 个一组翻转链表 - 力扣(LeetCode) 这道题需要在链表上,每k个为一组,翻转,链接。 乍一看好像比较容易,其实有很多细节。比如每一组反转后怎么找到上一组的新尾,怎么找到…...
深度学习详解
深度学习(Deep Learning,DL)是机器学习(Machine Learning,ML)中的一个子领域,利用多层次(深层)神经网络来自动从数据中提取特征和规律,模仿人脑的神经系统来进…...
鸿蒙分享(一):添加模块,修改app名称图标
码仓库:https://gitee.com/linguanzhong/share_harmonyos 鸿蒙api:12 新建公共模块common 在entry的oh-package.json5添加dependencies,引入common模块 "dependencies": {"common": "file:../common" } 修改app名称&…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
沙箱虚拟化技术虚拟机容器之间的关系详解
问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西,但是如果把三者放在一起,它们之间到底什么关系?又有什么联系呢?我不是很明白!!! 就比如说: 沙箱&#…...
