1,图像放大
本设计实现图像1.0到4.0倍放大;本设计基于分辨率640*512实现。
(1)计算相关参数
输入:放大倍率;
输出:图像放大后行列坐标;图像在新坐标中的分布位置;
比如:图像分辨率640*512 放大1.5倍后;理论分辨率为960*768;
针对960*768分辨率的图像经行中心点640*512切割;后得到放大后的640*512的图像;
输入: 1.5
输出:960*768 列有效: 160~800 行有效 :128~640
具体代码如下:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/09/07 08:49:45
// Design Name: xy
// Module Name: param_generate
//
//
module scale_param_generate(
input sys_clk,
input sys_rst,
input param_update_en,
input [7:0] param_update_data,
output param_update_end,
output [15:0] param_line_len,
output [15:0] param_line_num,
output [15:0] param_valid_len_start,
output [15:0] param_valid_num_start,
output [15:0] param_valid_len_stop,
output [15:0] param_valid_num_stop
);
reg param_update_en_r0 = 0;
reg param_update_en_r1 = 0;
reg param_update_en_pose = 0;
reg param_update_end_reg = 0;
reg [15:0] param_line_len_reg = 640;
reg [15:0] param_line_num_reg = 512;
reg [15:0] param_len_start_reg = 0;
reg [15:0] param_num_start_reg = 0;
reg [15:0] param_len_stop_reg = 0;
reg [15:0] param_num_stop_reg = 0;
assign param_line_len = param_line_len_reg;
assign param_line_num = param_line_num_reg;
assign param_valid_len_start = param_len_start_reg;
assign param_valid_num_start = param_num_start_reg;
assign param_valid_len_stop = param_len_stop_reg;
assign param_valid_num_stop = param_num_stop_reg;
assign param_update_end = param_update_end_reg;
//----------------------------------------------------
always @ (posedge sys_clk) begin
param_update_en_r0 <= param_update_en;
param_update_en_r1 <= param_update_en_r0;
param_update_en_pose <= !param_update_en_r1 && param_update_en_r0;
param_update_end_reg <= param_update_en_pose;
end
always @ (posedge sys_clk) begin
if(sys_rst) begin
param_line_len_reg <= 640;
param_len_start_reg <= 0;
param_len_stop_reg <= 0;
param_line_num_reg <= 512;
param_num_start_reg <= 0;
param_num_stop_reg <= 0;
end
else if(param_update_en_pose) begin
case(param_update_data)
10 : begin param_line_len_reg <= 640; param_len_start_reg <= 0; param_len_stop_reg <= 640; param_line_num_reg <= 512; param_num_start_reg <= 0; param_num_stop_reg <= 512; end
11 : begin param_line_len_reg <= 704; param_len_start_reg <= 32; param_len_stop_reg <= 672; param_line_num_reg <= 563; param_num_start_reg <= 26; param_num_stop_reg <= 538; end
12 : begin param_line_len_reg <= 768; param_len_start_reg <= 64; param_len_stop_reg <= 704; param_line_num_reg <= 614; param_num_start_reg <= 51; param_num_stop_reg <= 563; end
13 : begin param_line_len_reg <= 832; param_len_start_reg <= 96; param_len_stop_reg <= 736; param_line_num_reg <= 666; param_num_start_reg <= 77; param_num_stop_reg <= 589; end
14 : begin param_line_len_reg <= 896; param_len_start_reg <= 128; param_len_stop_reg <= 768; param_line_num_reg <= 717; param_num_start_reg <= 102; param_num_stop_reg <= 614; end
15 : begin param_line_len_reg <= 960; param_len_start_reg <= 160; param_len_stop_reg <= 800; param_line_num_reg <= 768; param_num_start_reg <= 128; param_num_stop_reg <= 640; end
16 : begin param_line_len_reg <= 1024; param_len_start_reg <= 192; param_len_stop_reg <= 832; param_line_num_reg <= 819; param_num_start_reg <= 154; param_num_stop_reg <= 666; end
17 : begin param_line_len_reg <= 1088; param_len_start_reg <= 224; param_len_stop_reg <= 864; param_line_num_reg <= 870; param_num_start_reg <= 179; param_num_stop_reg <= 691; end
18 : begin param_line_len_reg <= 1152; param_len_start_reg <= 256; param_len_stop_reg <= 896; param_line_num_reg <= 922; param_num_start_reg <= 205; param_num_stop_reg <= 717; end
19 : begin param_line_len_reg <= 1216; param_len_start_reg <= 288; param_len_stop_reg <= 928; param_line_num_reg <= 973; param_num_start_reg <= 230; param_num_stop_reg <= 742; end
20 : begin param_line_len_reg <= 1280; param_len_start_reg <= 320; param_len_stop_reg <= 960; param_line_num_reg <= 102; param_num_start_reg <= 256; param_num_stop_reg <= 768; end
21 : begin param_line_len_reg <= 1344; param_len_start_reg <= 352; param_len_stop_reg <= 992; param_line_num_reg <= 1075; param_num_start_reg <= 282; param_num_stop_reg <= 794; end
22 : begin param_line_len_reg <= 1408; param_len_start_reg <= 384; param_len_stop_reg <= 1024; param_line_num_reg <= 1126; param_num_start_reg <= 307; param_num_stop_reg <= 819; end
23 : begin param_line_len_reg <= 1472; param_len_start_reg <= 416; param_len_stop_reg <= 1056; param_line_num_reg <= 1178; param_num_start_reg <= 333; param_num_stop_reg <= 845; end
24 : begin param_line_len_reg <= 1536; param_len_start_reg <= 448; param_len_stop_reg <= 1088; param_line_num_reg <= 1229; param_num_start_reg <= 358; param_num_stop_reg <= 870; end
25 : begin param_line_len_reg <= 1600; param_len_start_reg <= 480; param_len_stop_reg <= 1120; param_line_num_reg <= 1280; param_num_start_reg <= 384; param_num_stop_reg <= 896; end
26 : begin param_line_len_reg <= 1664; param_len_start_reg <= 512; param_len_stop_reg <= 1152; param_line_num_reg <= 1331; param_num_start_reg <= 410; param_num_stop_reg <= 922; end
27 : begin param_line_len_reg <= 1728; param_len_start_reg <= 544; param_len_stop_reg <= 1184; param_line_num_reg <= 1382; param_num_start_reg <= 435; param_num_stop_reg <= 947; end
28 : begin param_line_len_reg <= 1792; param_len_start_reg <= 576; param_len_stop_reg <= 1216; param_line_num_reg <= 1434; param_num_start_reg <= 461; param_num_stop_reg <= 973; end
29 : begin param_line_len_reg <= 1856; param_len_start_reg <= 608; param_len_stop_reg <= 1248; param_line_num_reg <= 1485; param_num_start_reg <= 486; param_num_stop_reg <= 998; end
30 : begin param_line_len_reg <= 1920; param_len_start_reg <= 640; param_len_stop_reg <= 1280; param_line_num_reg <= 1536; param_num_start_reg <= 512; param_num_stop_reg <= 1024; end
31 : begin param_line_len_reg <= 1984; param_len_start_reg <= 672; param_len_stop_reg <= 1312; param_line_num_reg <= 1587; param_num_start_reg <= 538; param_num_stop_reg <= 1050; end
32 : begin param_line_len_reg <= 2048; param_len_start_reg <= 704; param_len_stop_reg <= 1344; param_line_num_reg <= 1638; param_num_start_reg <= 563; param_num_stop_reg <= 1075; end
33 : begin param_line_len_reg <= 2112; param_len_start_reg <= 736; param_len_stop_reg <= 1376; param_line_num_reg <= 1690; param_num_start_reg <= 589; param_num_stop_reg <= 1101; end
34 : begin param_line_len_reg <= 2176; param_len_start_reg <= 768; param_len_stop_reg <= 1408; param_line_num_reg <= 1741; param_num_start_reg <= 614; param_num_stop_reg <= 1126; end
35 : begin param_line_len_reg <= 2240; param_len_start_reg <= 800; param_len_stop_reg <= 1440; param_line_num_reg <= 1792; param_num_start_reg <= 640; param_num_stop_reg <= 1152; end
36 : begin param_line_len_reg <= 2304; param_len_start_reg <= 832; param_len_stop_reg <= 1472; param_line_num_reg <= 1843; param_num_start_reg <= 666; param_num_stop_reg <= 1178; end
37 : begin param_line_len_reg <= 2368; param_len_start_reg <= 864; param_len_stop_reg <= 1504; param_line_num_reg <= 1894; param_num_start_reg <= 691; param_num_stop_reg <= 1203; end
38 : begin param_line_len_reg <= 2432; param_len_start_reg <= 896; param_len_stop_reg <= 1536; param_line_num_reg <= 1946; param_num_start_reg <= 717; param_num_stop_reg <= 1229; end
39 : begin param_line_len_reg <= 2496; param_len_start_reg <= 928; param_len_stop_reg <= 1568; param_line_num_reg <= 1997; param_num_start_reg <= 742; param_num_stop_reg <= 1254; end
40 : begin param_line_len_reg <= 2560; param_len_start_reg <= 960; param_len_stop_reg <= 1600; param_line_num_reg <= 2048; param_num_start_reg <= 768; param_num_stop_reg <= 1280; end
default : begin param_line_len_reg <= 640; param_len_start_reg <= 0; param_len_stop_reg <= 640; param_line_num_reg <= 512; param_num_start_reg <= 0; param_num_stop_reg <= 512; end
endcase
end
else begin
param_line_len_reg <= param_line_len_reg;
param_len_start_reg <= param_len_start_reg;
param_len_stop_reg <= param_len_stop_reg;
param_line_num_reg <= param_line_num_reg;
param_num_start_reg <= param_num_start_reg;
param_num_stop_reg <= param_num_stop_reg;
end
end
endmodule
(2) 计算行列放大地址表;
原图为640*512的数据放大为960*768后;
960*768理论对应640*512为:行地址1~9分别为 1 2 2 3 4 4 5 6 6
由上一步骤得到960*768参数,计算行列地址表;
列:(0~959)/ 放大倍率 = 取整(对应位640中的坐标)
行:(0~767)/ 放大倍率 = 取整(对应位512中的坐标)
3,输入图像数据流统计坐标进入对应地址表判断选择;形成新的视频流。
代码实现如下:
`timescale 1ns / 1ps
module image_scale_control(
input sys_clk,
input sys_rst,
input param_update_en,
input [7:0] param_update_data,
output [9:0] ot_line_num_cnt,
output [9:0] ot_line_len_cnt,
output [9:0] ot_line_num_data,
output [9:0] ot_line_len_data,
output axis_s_ready,
input axis_s_valid,
input axis_s_last,
input [15:0] axis_s_data,
input [15:0] axis_s_user,
input axis_m_ready,
output axis_m_valid,
output axis_m_last,
output [15:0] axis_m_data,
output [15:0] axis_m_user
);
reg [3:0] scale_state = 0;
reg [15:0] rx_line_reg = 0;
reg wr_image_en = 0;
reg [9:0] wr_image_addr_cnt = 0;
reg [9:0] wr_image_addr = 0;
reg [15:0] wr_image_data = 0;
reg [9:0] rd_image_addr = 0;
reg rd_image_en = 0;
reg rd_image_end = 0;
wire [15:0] rd_image_data;
reg [9:0] line_num_cnt = 0;
reg [9:0] line_len_cnt = 0;
wire [9:0] line_num_data;
wire [9:0] line_len_data;
reg tx_valid_reg = 0;
reg tx_last_reg = 0;
reg [15:0] tx_data_reg = 0;
reg [15:0] tx_user_reg = 0;
assign axis_s_ready = (scale_state == 0) ? 1 : 0;
assign axis_m_valid = tx_valid_reg;
assign axis_m_last = tx_last_reg;
assign axis_m_data = tx_data_reg;
assign axis_m_user = tx_user_reg;
assign ot_line_num_cnt = line_num_cnt;
assign ot_line_len_cnt = line_len_cnt;
assign ot_line_num_data = line_num_data;
assign ot_line_len_data = line_len_data;
//--------------------------------------------------------------
image_data_ram image_data_ram_inst(
.a (wr_image_addr),
.d (wr_image_data),
.we (wr_image_en ),
.clk (sys_clk),
.dpra (rd_image_addr),
.dpo (rd_image_data)
);
scale_image_addr scale_image_addr_inst(
.sys_clk (sys_clk),
.sys_rst (sys_rst),
.param_update_en (param_update_en ),
.param_update_data (param_update_data),
.rd_line_num_addr (line_num_cnt ),
.rd_line_num_data (line_num_data),
.rd_line_len_addr (line_len_cnt ),
.rd_line_len_data (line_len_data)
);
//-----------------------------------------------------------------------------------------------
always @ (posedge sys_clk) begin
if(sys_rst)
rx_line_reg <= 0;
else if(axis_s_ready && axis_s_valid && axis_s_last)
rx_line_reg <= axis_s_user;
else
rx_line_reg <= rx_line_reg;
end
always @ (posedge sys_clk) begin
if(sys_rst) begin
wr_image_en <= 0;
wr_image_addr <= 0;
wr_image_data <= 0;
wr_image_addr_cnt <= 0;
end
else if(axis_s_ready && axis_s_valid && axis_s_last) begin
wr_image_en <= 1;
wr_image_addr <= wr_image_addr_cnt;
wr_image_data <= axis_s_data;
wr_image_addr_cnt <= 0;
end
else if(axis_s_ready && axis_s_valid) begin
wr_image_en <= 1;
wr_image_addr <= wr_image_addr_cnt;
wr_image_data <= axis_s_data;
wr_image_addr_cnt <= wr_image_addr_cnt + 1;
end
else begin
wr_image_en <= 0;
wr_image_addr <= wr_image_addr;
wr_image_data <= wr_image_data;
wr_image_addr_cnt <= wr_image_addr_cnt;
end
end
always @ (posedge sys_clk) begin
if(sys_rst)
scale_state <= 0;
else case(scale_state)
0 : if(axis_s_ready && axis_s_valid && axis_s_last)
scale_state <= 1;
else
scale_state <= 0;
1 : if(line_num_data == rx_line_reg)
scale_state <= 2;
else
scale_state <= 0;
2 : if(axis_m_ready && line_len_cnt >= 639)
scale_state <= 3;
else
scale_state <= 2;
3 : scale_state <= 1;
default : scale_state <= 0;
endcase
end
always @ (posedge sys_clk) begin
if(sys_rst) begin
line_num_cnt <= 0;
line_len_cnt <= 0;
rd_image_addr <= 0;
rd_image_en <= 0;
rd_image_end <= 0;
end
else case(scale_state)
0 : begin
line_num_cnt <= line_num_cnt;
line_len_cnt <= 0;
rd_image_addr <= 0;
rd_image_en <= 0;
rd_image_end <= 0;
end
1 : begin
line_num_cnt <= line_num_cnt;
line_len_cnt <= 0;
rd_image_addr <= 0;
rd_image_en <= 0;
rd_image_end <= 0;
end
2 : begin
line_num_cnt <= line_num_cnt;
line_len_cnt <= axis_m_ready ? line_len_cnt + 1 : line_len_cnt;
rd_image_addr <= line_len_data;
rd_image_en <= (line_len_cnt <= 639) ? 1: 0;
rd_image_end <= (line_len_cnt == 639) ? 1: 0;
end
3 : begin
line_num_cnt <= (line_num_cnt >= 511) ? 0 : line_num_cnt + 1;
line_len_cnt <= 0;
rd_image_addr <= 0;
rd_image_en <= 0;
rd_image_end <= 0;
end
endcase
end
always @ (posedge sys_clk) begin
if(sys_rst) begin
tx_valid_reg <= 0;
tx_last_reg <= 0;
tx_data_reg <= 0;
tx_user_reg <= 0;
end
else begin
tx_valid_reg <= rd_image_en;
tx_last_reg <= rd_image_end;
tx_data_reg <= rd_image_data;
tx_user_reg <= line_num_cnt;
end
end
endmodule