首页 > 其他分享 >FPGA图像处理(直方图均衡化)

FPGA图像处理(直方图均衡化)

时间:2024-02-08 11:11:39浏览次数:23  
标签:pre addr FPGA 均衡化 ram1 rd 直方图 reg

      图像处理领域中利用图像直方图对对比度进行调整的方法。 对比度是画面黑与白的比值,也就是从黑到白的渐变层次。比值越大,从黑到白的渐变层次就越多,从而色彩表现越丰富。对比度对视觉效果的影响非常关键,一般来说对比度越大,图像越清晰醒目,色彩也越鲜明艳丽;而对比度小,则会让整个画面都灰的不清楚。
直方图均衡化分为真均衡化和伪均衡化,由于FPGA不方便实现真均衡化,所以采用伪均衡化,即前一帧的图像进行统计、帧间隙进行累计和与归一化、当前帧做归一化后的映射输出。不过仿真的话,前一帧和当前帧是同一张图片,就是真均衡化。

      建立直方图,在FPGA中可以用256个计数器对每个灰度进行计数,不过这样做代码代码量太大,使用的资源也很多,不太现实。
像素是一个个来的,因此任何时钟周期都只有一个计数器在增加,意味着累加器可以在存储器中实现,首先需要读取相关存储单元,然后加一再写回,这需要用到双端口ram,一个读端口一个写端口。不过需要注意,因为读出数据需要一拍,图中灰度I需要打一拍再送入写入端口的地址端。因为ram在读写冲突时读出的是旧数据,所以当连续相同像素到来时,会出现统计丢失,不过对结果影响很小,视觉上难以辨别。

 

  1. 第一帧统计直方图存入ram1
  2. 帧间隙读出ram1中数据进行计算,将计算结果存入ram2,同时对ram1进行清零
  3. 第二帧根据映射表进行输出

 

      H(i)为第 i 级灰度的像素个数,A0为图像的面积(即分辨率),Dmax为灰度最大值,即255。
帧间隙时,设计一个计数器,从0计数到255,将ram1中的数据读出来,同时对ram1进行清零。读出的数据会通过流水线计算,得出直方图均衡化后的灰度级映射,再写入ram2。第一级进行累加,第二级乘以255,第三级除以分辨率。
第二帧只需读出ram2中的数据进行映射输出即可得到直方图均衡化后的图像。

module histgram_equ(
    input           clk,
    input           rst_n,
    
    // input
    input           pre_vsync,
    input           pre_href,
    input           pre_clken,
    input   [7:0]   pre_img_Y,

    // output
    output  reg     post_vsync,
    output  reg     post_href,
    output  reg     post_clken,
    output  [7:0]   post_img_Y
);
//----------------------信号声明--------------------------
    // ram1读地址总线
    wire    [7:0]   rd_addr_bus;
    // ram1读数据
    wire    [31:0]  rd_data;
    // ram1写使能总线
    wire            wren_bus;
    // ram1写地址总线
    wire    [7:0]   wr_addr_bus;
    // ram1写数据总线
    wire    [31:0]  wr_data_bus;
    // 输入灰度打一拍
    reg [7:0]       pre_img_Y_r;
    // 数据有效打一拍
    reg             pre_clken_r;
    // pre_vsync打一拍检测下降沿
    reg             pre_vsync_r;
    // 读出直方图地址计数器
    reg [7:0]       rd_addr_cnt;
    // 读出直方图地址计数器使能
    reg             rd_addr_cnt_en;
    // 计数器使能打4拍,ram1读出数据需要1时钟周期,第一拍用于累加的使能,累加消耗1时钟周期,乘除消耗2时钟周期
    reg [3:0]       cnt_en_lag4;
    // 计数器打4拍作为ram2的写入地址
    reg [7:0]       rd_addr_cnt_r1;
    reg [7:0]       rd_addr_cnt_r2;
    reg [7:0]       rd_addr_cnt_r3;
    reg [7:0]       rd_addr_cnt_r4;
    // 直方图累加和
    reg [31:0]      sum;
    // 直方图累加和 * 255
    reg [31:0]      sum_x_255;
    // 累加 * 255 / 307200,图像分辨率为640*480=307200
    reg [7:0]      sum_x_255_div_307200;
    // vsync高电平期间ram1统计直方图,低电平期间读出ram1直方图,并清零
    assign rd_addr_bus = pre_vsync ? pre_img_Y     : rd_addr_cnt;
    assign wren_bus    = pre_vsync ? pre_clken_r   : rd_addr_cnt_en;
    assign wr_addr_bus = pre_vsync ? pre_img_Y_r   : rd_addr_cnt;
    assign wr_data_bus = pre_vsync ? (rd_data + 1) : 8'd0;

//----------------------直方图统计--------------------------
    // 输入灰度和数据有效打一拍,与读出数据同步
    always @(posedge clk, negedge rst_n) begin
        if(!rst_n) begin
            pre_img_Y_r <= 0;
            pre_clken_r <= 1'b0;
        end else begin
            pre_img_Y_r <= pre_img_Y;
            pre_clken_r <= pre_clken;
        end
    end

    // 统计直方图,读写冲突会导致连续重复像素的统计丢失,但结果和实际直方图均衡近似,只是视觉上稍微暗一点
    ram_32x256 inst_ram_32x256(
        .clock     (clk),
        .data      (wr_data_bus),
        .rdaddress (rd_addr_bus),
        .wraddress (wr_addr_bus),
        .wren      (wren_bus),
        .q         (rd_data)
    );

//--------------------------直方图累加----------------------
    // pre_vsync打一拍用于检测下降沿
    always @(posedge clk, negedge rst_n) begin
        if(!rst_n)
            pre_vsync_r <= 0;
        else
            pre_vsync_r <= pre_vsync;
    end

    // 读地址计数器使能
    always @(posedge clk, negedge rst_n) begin
        if(!rst_n)
            rd_addr_cnt_en <= 1'b0;
        else if(~pre_vsync & pre_vsync_r)           // 检测pre_vsync的下降沿开始计数
            rd_addr_cnt_en <= 1'b1;
        else if(rd_addr_cnt == 8'd255)              // 计数256时钟周期即停止
            rd_addr_cnt_en <= 1'b0;
    end

    // 读地址计数器
    always @(posedge clk, negedge rst_n) begin
        if(!rst_n)
            rd_addr_cnt <= 0;
        else if(rd_addr_cnt_en)
            rd_addr_cnt <= rd_addr_cnt + 8'd1;
    end

    // 直方图累加,消耗一时钟周期
    always @(posedge clk, negedge rst_n) begin
        if(!rst_n)
            sum <= 0;
        else if(cnt_en_lag4[0])// 计数器使能打一拍用于累加,因为读出数据延迟一时钟周期
            sum <= sum + rd_data;
        else
            sum <= 0;
    end

    // 累加 * 255,即sum * 256 - sum,消耗一时钟周期
    always @(posedge clk, negedge rst_n) begin
        if(!rst_n)
            sum_x_255 <= 0;
        else
            sum_x_255 <= (sum << 8) - sum;
    end

    // 累加 * 255 / 307200,消耗一时钟周期
    always @(posedge clk, negedge rst_n) begin
        if(!rst_n)
            sum_x_255_div_307200 <= 0;
        else
            sum_x_255_div_307200 <= sum_x_255 / 307200;
    end

    // 计数器使能打4拍,读出数据消耗一时钟周期,累加、乘、除消耗三时钟周期
    always @(posedge clk, negedge rst_n) begin
        if(!rst_n)
            cnt_en_lag4 <= 0;
        else
            cnt_en_lag4 <= {cnt_en_lag4[2:0], rd_addr_cnt_en};
    end

    // 计数器打4拍作为ram2的写入地址,读出数据消耗一时钟周期,累加、乘、除消耗三时钟周期
    always @(posedge clk, negedge rst_n) begin
        if(!rst_n) begin
            rd_addr_cnt_r1 <= 0;
            rd_addr_cnt_r2 <= 0;
            rd_addr_cnt_r3 <= 0;
            rd_addr_cnt_r4 <= 0;
        end else begin
            rd_addr_cnt_r1 <= rd_addr_cnt;
            rd_addr_cnt_r2 <= rd_addr_cnt_r1;
            rd_addr_cnt_r3 <= rd_addr_cnt_r2;
            rd_addr_cnt_r4 <= rd_addr_cnt_r3;
        end
    end

    // 直方图均衡化映射表
    ram_8x256 inst_ram_8x256(
        .clock     (clk),
        .data      (sum_x_255_div_307200),
        .rdaddress (pre_img_Y),
        .wraddress (rd_addr_cnt_r4),
        .wren      (cnt_en_lag4[3]),
        .q         (post_img_Y)
    );

    // ram2读出数据消耗1时钟周期,所以其他信号打一拍输出
    always @(posedge clk, negedge rst_n) begin
        if(!rst_n) begin
            post_vsync <= 1'b0;
            post_href  <= 1'b0;
            post_clken <= 1'b0;
        end else begin
            post_vsync <= pre_vsync;
            post_href  <= pre_href;
            post_clken <= pre_clken;
        end
    end
endmodule
View Code

 

标签:pre,addr,FPGA,均衡化,ram1,rd,直方图,reg
From: https://www.cnblogs.com/shiningleo007/p/18011662

相关文章

  • 高级FPGA开发之基础协议之PCIe(二)
    高级FPGA开发之基础协议之PCIe(二)一、TLP报文类型在PCIe总线中,存储器读写、I/O读写和配置读写请求TLP主要由以下几类报文组成:1.1存储器读请求TLP和读完成TLP当PCIe主设备(RC或者EP)访问目标设备的存储器空间时,使用non-posted总线事务向目标设备发出存储器读请求TLP,目标设备收到这个存......
  • 全国产T3+FPGA的SPI与I2C通信方案分享
    近年来,随着中国新基建、中国制造2025规划的持续推进,单ARM处理器越来越难胜任工业现场的功能要求,特别是如今能源电力、工业控制、智慧医疗等行业,往往更需要ARM+FPGA架构的处理器平台来实现例如多路/高速AD采集、多路网口、多路串口、多路/高速并行DI/DO、高速数据并行处理等特定......
  • 基于FPGA的图像RGB转CMYK实现,包含testbench和MATLAB辅助验证程序
    1.算法运行效果图预览 将仿真结果导入到matlab中,得到如下对比结果: 2.算法运行软件版本matlab2022a,vivado2019.2 3.算法理论概述       基于FPGA的图像RGB转CMYK实现是一种将RGB图像转换为CMYK图像的硬件实现方法。下面将详细介绍其原理和数学公式。 3.1、......
  • 通过LINUX驱动控制FPGA端PWM外设(LED) 通过应用程序命令传参随意修改寄存器的值(PWM波频
    用法:先下发下面的命令让kernel信息打印到串口:echo7417>/proc/sys/kernel/printk然后增加程序可执行性:chmod777pwmdriver_app  先执行./pwmdriver_app/dev/pwm400000200然后执行./pwm_driver_app/dev/pwm400000200,可以发现LED[1]......
  • 国产RK3568J基于FSPI的ARM+FPGA通信方案分享
    近年来,随着中国新基建、中国制造2025规划的持续推进,单ARM处理器越来越难胜任工业现场的功能要求,特别是如今能源电力、工业控制、智慧医疗等行业,往往更需要ARM+FPGA架构的处理器平台来实现例如多路/高速AD采集、多路网口、多路串口、多路/高速并行DI/DO、高速数据......
  • m基于FPGA和IP核的RS编译码verilog实现,包含testbench测试文件
    1.算法仿真效果本系统进行了Vivado2019.2平台的开发,测试结果如下:    2.算法涉及理论知识概要       在现代通信系统中,为了确保数据传输的可靠性,经常需要使用各种纠错编码技术。其中,里德-所罗门(Reed-Solomon,RS)码是一种非常强大的线性纠错码,特别适用于纠正多......
  • 基于FPGA的图像RGB转HSV实现,包含testbench和MATLAB辅助验证程序
    1.算法运行效果图预览 将FPGA的仿真结果导入到matlab中:   2.算法运行软件版本vivado2019.2 matlab2022a 3.算法理论概述       在数字图像处理中,色彩空间的转换是常见的操作。其中,RGB和HSV是两种经常使用的色彩空间。RGB基于红、绿、蓝三种颜色的组合......
  • 基于FPGA的图像RGB转HLS实现,包含testbench和MATLAB辅助验证程序
    1.算法运行效果图预览 将FPGA结果导入到MATLAB显示效果: 2.算法运行软件版本Vivado2019.2 matlab2022a 3.算法理论概述       在数字图像处理中,RGB和HLS是两种常见的颜色空间。RGB基于红绿蓝三种基本颜色的叠加来定义其他颜色,而HLS则代表色调、亮度和饱和......
  • 新品来袭,全国产ARM+FPGA--"RK3568J+Logos-2"工业核心板,让您的硬件设计“更简单”!
    如需选购,请登录创龙科技天猫旗舰店:tronlong.tmall.com!欢迎加入RK3568J技术交流群:567208221欢迎加入Logos-2技术交流群:311416997更多产品详情以及购买咨询可添加如下客服人员微信(即刻添加,马上咨询) 更多RK3568J+Logos-2产品资料可长按二维码识别下载  ......
  • m基于FPGA的Hamming汉明编译码verilog实现,包含testbench测试文件,不使用IP核
    1.算法仿真效果本系统进行了Vivado2019.2平台的开发,测试结果如下:2.算法涉及理论知识概要在现代数字通信和存储系统中,错误检测和纠正(ErrorDetectionandCorrection,EDC)机制是至关重要的。Hamming码,以其发明者RichardHamming命名,是一种线性错误检测和纠正码,广泛应用于这些系......