十五、基于FPGA的图像处理算法之放大(一)

 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

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: VGA(Video Graphics Array)是一种视频显示标准,它可以输出分辨率为640x480的图像。如果需要将图像进行放大,可以使用FPGA实现。在FPGA中,可以使用硬件描述语言(如Verilog或VHDL)编写代码来实现图像放大的功能。具体实现可以采用缩放算法(如双线性插值法)对图像进行放大,然后将放大后的图像输出到VGA显示器上。需要注意的是,图像放大会消耗大量的计算资源,因此需要考虑FPGA的计算能力和资源利用效率。 ### 回答2: VGA是一种通用的视频接口标准,用于连接计算机和显示器,可实现图像传输。FPGA(现场可编程逻辑门阵列)是一种可编程逻辑电路,可以通过重新编程实现不同的功能。 在使用FPGA进行图像放大时,首先需要将图像数据输入到FPGA中。通常情况下,图像数据是以数字形式存储的,因此可以通过外部设备(如计算机)将数据传输到FPGA内部的存储器中。 在FPGA内部,可以使用一些算法和技术对图像进行放大,其中一种常见的方法是插值算法。插值算法可以通过计算图像中每个像素的邻近像素,然后根据计算结果来生成新的像素值。这样可以使图像放大过程中保持较好的清晰度和细节。 在FPGA处理完图像数据后,可以通过VGA接口将处理后的图像数据输出到显示器上进行显示。由于VGA支持的分辨率通常较高,因此可以保证放大后的图像在显示器上得到良好的呈现效果。 总的来说,使用FPGA进行图像放大可以通过插值算法等技术实现,然后将处理后的图像数据通过VGA接口输出到显示器上。这种方法可以提供高质量的放大效果,适用于各种图像放大应用场景。 ### 回答3: VGA(视频图形适配器)是一种常见的视频接口标准,用于连接显示器和图形输出设备。FPGA(现场可编程门阵列)是可编程逻辑器件,它可以实现各种数字逻辑功能。 在进行图像放大时,VGA接口通常用于将数字图像信号转换为模拟信号,然后通过连接到显示器进行显示。然而,VGA信号输出的分辨率通常是固定的,这会限制图像放大的效果。 使用FPGA可以处理并改变VGA信号,实现图像放大功能。首先,FPGA可以接收来自VGA接口的数字信号,并对其进行处理。然后,FPGA可以通过使用插值算法或其他数字图像处理技术,将输入图像进行放大FPGA还可以调节图像的亮度、对比度和色彩等参数,从而进一步优化放大后的图像。另外,FPGA还可以在图像处理过程中添加滤波器、边缘增强等功能,以提高图像质量。 通过使用FPGA进行图像放大,我们可以根据实际需求和应用场景,灵活地调整放大倍率和图像处理算法。这种灵活性和可编程性是FPGA的优势之一,使得它成为图像处理领域中一个强大的工具。 总之,通过结合VGA接口和FPGA的特点,我们可以实现对图像进行放大的功能。FPGA可以接收和处理VGA信号,并通过适当的算法实现图像放大和优化,从而得到更好的视觉效果。这使得图像处理和显示技术在不同领域中有着广泛的应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值