FPGA图像处理之自动白平衡(附源码)

FPGA图像处理之自动白平衡(附源码)

概要

白平衡(White Balance)是图像处理中的一种基本技术,用于调整图像的颜色表现,使其在不同光照条件下能够呈现出真实的色彩。白平衡的核心目标是校正图像中的色偏,使图像中的白色物体在各种光源下都能显现为真实的白色,同时保证其他颜色的准确性。
在FPGA(现场可编程门阵列)上实现白平衡处理是一种高效的硬件加速方法,特别适用于需要实时处理的场景,例如数字相机、监控摄像头和工业视觉系统。FPGA通过并行处理的能力,可以以极高的速度完成白平衡算法的计算。

FPGA图像处理白平衡实现方法详解

这个白平衡模块是基于灰度世界法实现自动白平衡(AWB),通过AXI-Stream接口接收像素数据,实时调整RGB通道增益,输出校正后的图像。

1.输入流水线与数据同步
流水线延迟:输入数据通过多级寄存器(I_tdata_d0、I_tdata_d1、I_tdata_d2)延迟3个周期,确保后续处理时序对齐。
信号同步:I_tvalid和I_tuser等控制信号同步延迟,避免时序冲突。
2. RGB通道累加
累加器复位:帧开始信号I_tuser有效时,复位累加器sum_r、sum_g、sum_b,开始新一帧的累加。
实时累加:在I_tvalid_r0有效时,将每个像素的RGB值分别累加,统计整帧的总和。
3. 增益计算(存在问题)
除法器调用:通过IP核div_gen_awb计算G/R和G/B的比值,将sum_g左移16位作为被除数,提高计算精度。
增益截断:检查除法结果高位,防止溢出,保留20位定点数(Q16.4格式)表示增益。
问题点:除法器在I_tvalid_r1(即每像素有效)时触发,导致基于部分累加值的错误增益,正确做法应在帧结束时触发。
4. 增益应用与数据校正
乘法操作:延迟后的像素数据与增益相乘,R和B通道分别调整,G通道保持原值。
溢出处理:若乘法结果超出8位范围,截断为0xFF,保留最大值。
5. 输出同步
信号对齐:通过多级寄存器延迟tlast和tuser信号,确保输出信号与校正数据同步。
AXI-Stream接口:输出数据拼接为24位像素,O_tvalid和O_tready控制流传输。

源码

module awb  #(   
    parameter IMG_HEIGHT = 1080,   // 图像高度参数,默认值为1080
    parameter IMG_WIDTH  = 1920    // 图像宽度参数,默认值为1920
) 
(
    input                   I_clk  ,    // 输入时钟信号
    input                   I_rst_n,    // 输入复位信号,低电平有效

    input                   I_tlast  ,  // 行结束信号
    input                   I_tuser  ,  // 帧开始信号
    input [23:0]            I_tdata  ,  // 输入数据,总共包含4个像素的RGB值,每个像素24位,4*24=96位
    input                   I_tvalid ,  // 输入数据有效信号
    output                  I_tready ,  // 输入数据准备好信号

    output                  O_tlast  ,  // 输出行结束信号
    output                  O_tuser  ,  // 输出帧开始信号
    output [23:0]           O_tdata  ,  // 输出数据
    output                  O_tvalid ,  // 输出数据有效信号
    input                   O_tready    // 输出数据准备好信号
);



reg         I_tvalid_r0,I_tvalid_r1,I_tvalid_r2;          // 输入有效信号的寄存
reg  [23:0] I_tdata_d0,I_tdata_d1,I_tdata_d2; // 输入数据的寄存

// 累加RGB通道的数值,用于计算平均值
reg  [31:0]         sum_r;
reg  [31:0]         sum_g;
reg  [31:0]         sum_b;

wire  [23:0]        data_d0 ;     // 延时后的数据
wire                valid_d0;     // 延时后的有效信号


reg   [23:0]        data_d1 ;     // 再次延时后的数据
reg                 valid_d1;     // 再次延时后的有效信号

wire  [7:0]         rgb888_r_d0; 
wire  [7:0]         rgb888_g_d0;
wire  [7:0]         rgb888_b_d0;

// 对输入数据和有效信号进行寄存,形成流水线
always @(posedge I_clk or negedge I_rst_n) begin
    if (!I_rst_n) begin
        I_tdata_d0  <= 0;
        I_tdata_d1  <= 0;
        I_tdata_d2  <= 0;
        {I_tvalid_r0,I_tvalid_r1} <= 0;
    end else begin
        I_tdata_d0  <= I_tdata   ;
        I_tdata_d1  <= I_tdata_d0;
        I_tdata_d2  <= I_tdata_d1;
        I_tvalid_r0 <= I_tvalid;
        I_tvalid_r1 <= I_tvalid_r0;
    end
end


assign  rgb888_r_d0 = I_tdata_d0[16+:8];
assign  rgb888_g_d0 = I_tdata_d0[8+:8];
assign  rgb888_b_d0 = I_tdata_d0[0+:8];

// 对每个通道的值进行累加,用于计算平均值
always @(posedge I_clk or negedge I_rst_n) begin
    if (!I_rst_n || I_tuser) begin
        // 复位或行开始信号有效时,清零累加器
        sum_r <= 0;
        sum_g <= 0;
        sum_b <= 0;
    end else if (I_tvalid_r0) begin
        // 当输入有效时,累加RGB分量的值
        sum_r <= sum_r + rgb888_r_d0;
        sum_g <= sum_g + rgb888_g_d0;
        sum_b <= sum_b + rgb888_b_d0;
    end
end



// 定义除法器的输出信号
wire  [79:0]   dout_R ;
wire  [79:0]   dout_B ;

wire             done ;

// 为了保证合理的延迟,这里使用了除法器IP核
    // 调用除法器IP核,计算G/R的比值
    div_gen_awb div_gen_G_R_r1 (
      .aclk(I_clk),                                      // input wire aclk
      .s_axis_divisor_tvalid(I_tvalid_r1),               // 输入除数有效信号
      .s_axis_divisor_tdata(sum_r),                   // 输入除数数据,R通道的累加值
      .s_axis_dividend_tvalid(I_tvalid_r1),              // 输入被除数有效信号
      .s_axis_dividend_tdata({s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FPGA工程狮-阿水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值