免费建站建设网站搭建网站,建立一个网站需要什么,佛山微信网站推广多少钱,网站快排是怎么做的#xff08;1#xff09;图像平移的基本原理#xff1a;计算每个像素点的移动向量#xff0c;并将这些像素按照指定的方向和距离进行移动。 #xff08;2#xff09;平移向量包括水平和垂直分量#xff0c;可以表示为#xff08;dx#xff0c;dy#xff09;#xff… 1图像平移的基本原理计算每个像素点的移动向量并将这些像素按照指定的方向和距离进行移动。 2平移向量包括水平和垂直分量可以表示为dxdy其中dx表示水平方向上的移动距离dy表示垂直方向上的移动距离。 3经过平移后新图像中的每个像素点在原图像中都有对应的像素点。图像平移使用软件开发语言实现很容易但在FGPA中实现需要考虑缓存。 4matlab实现代码
% 读取图像
% 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(变换后的图像); 5FPGA仿真实现
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 12d0;else if(h_cnt img_x_start img_width - 1)h_cnt 12d0;else h_cnt h_cnt 12d1;always(posedge clk or negedge reset_n)if(!reset_n) v_cnt 12d0;else if((v_cnt img_y_start img_height - 1) (h_cnt img_x_start img_width - 1))v_cnt 12d0;else if(h_cnt img_x_start img_width - 1)v_cnt v_cnt 12d1;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 1d0;else if((h_cnt img_width) (v_cnt img_height))valid_o 1d1;else valid_o 1d0;always(posedge clk or negedge reset_n)if(!reset_n)img_data_o 24d0;else if((h_cnt img_width) (v_cnt img_height) (wr_ready))img_data_o img_data_i;else img_data_o 24d0;endmodule微调读写测试文件后仿真出来的图像与matlab仿真结果一致 6FPGA实现
查看配置进程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 (1d0 ),.ui_clk (ui_clk ),.ui_rst (ui_rst ),.wr_b_addr (32d0 ),.wr_e_addr (IMG_LENGTH*IMG_WIDE*4 ),.wr_clk (clk ),.data_wren (data_wren ),.data_wr (data_wr ),.wr_rst (1d0 ),.rd_b_addr (32d0 ),.rd_e_addr (IMG_LENGTH*(IMG_WIDE-Y_OFFSET1)*4 ),.rd_clk (clk_vga_2 ),.data_rden (lie Y_OFFSET ),.data_rd (data_rd ),.rd_rst (1d0 ),.read_enable (1d1 ),.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 (1d1 ), .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 16d0;buf_wr_addr 11d0;reading 1b0;line_buffer 24d0;endelse beginif(lie Y_OFFSET) beginif(!reading) begin // 第一次读取last_data_rd data_rd;reading 1b1;endelse begin // 第二次读取line_buffer {last_data_rd, data_rd[15:8]};buf_wr_addr buf_wr_addr 11d1;reading 1b0;endendelse beginbuf_wr_addr 11d0;reading 1d0;endend
end// 行缓存读取控制在这里实现偏移
always (posedge clk_vga or negedge init_rst_n) beginif(!init_rst_n) buf_rd_addr 11d0;else beginif(display_valid)buf_rd_addr buf_rd_addr 1d1;else buf_rd_addr 11d0;end
endassign display_valid (hang X_OFFSET)(lie Y_OFFSET); 最终现象如下