openISP学习4-AWB(自动白平衡增益控制)

文章目录

    • 1.AWB算法原理介绍
    • 2.AWB算法的代码
    • [3.AWB 测试代码](#3.AWB 测试代码)
      • ['GRBG' bayer pattern 测试代码](#'GRBG' bayer pattern 测试代码)
      • [R 通道单独拉gain测试代码](#R 通道单独拉gain测试代码)
    • [4.实际平台AWB tuning是怎么做的](#4.实际平台AWB tuning是怎么做的)
      • [如何计算AWB gain表](#如何计算AWB gain表)
      • [AWB 增益是如何应用的?](#AWB 增益是如何应用的?)
        • [实际案例推演:D65 光源下的红苹果](#实际案例推演:D65 光源下的红苹果)

1.AWB算法原理介绍

不同光源(日光、钨丝灯、荧光灯)的色温不同,导致相机捕获的图像存在色偏。AWB 通过对各颜色通道乘以增益系数,使白色物体在输出图像中呈现为白色。

openISP的AWB模块实现的是增益应用阶段(Gain Apply),增益值由上游的白平衡算法(如灰世界算法、完美反射算法)预先计算好,这里只做乘法。

复制代码
数学公式
R_out  = R_in  × r_gain
Gr_out = Gr_in × gr_gain
Gb_out = Gb_in × gb_gain
B_out  = B_in  × b_gain

Gr 和 Gb 分别有独立增益,用于校正镜头渐晕(Lens Shading)造成的绿色通道不均匀。

2.AWB算法的代码

这里只是简单的根据bayer patter的格式,分别应用不同通道的gain, 这里我们需要提前知道这个gain表,关于如何tuning出gain表,在文章最后有介绍. 此时算法只是简单的对各通道加权.

python 复制代码
class WBGC:
    'Auto White Balance Gain Control'

    def __init__(self, img, parameter, bayer_pattern, clip):
        self.img = img
        self.parameter = parameter
        self.bayer_pattern = bayer_pattern
        self.clip = clip

    def clipping(self):
        np.clip(self.img, 0, self.clip, out=self.img)
        return self.img

    def execute(self):
        r_gain = self.parameter[0]
        gr_gain = self.parameter[1]
        gb_gain = self.parameter[2]
        b_gain = self.parameter[3]
        raw_h = self.img.shape[0]
        raw_w = self.img.shape[1]
        awb_img = np.empty((raw_h, raw_w), np.int16)
        if self.bayer_pattern == 'rggb':
            r = self.img[::2, ::2] * r_gain
            b = self.img[1::2, 1::2] * b_gain
            gr = self.img[::2, 1::2] * gr_gain
            gb = self.img[1::2, ::2] * gb_gain
            awb_img[::2, ::2] = r
            awb_img[::2, 1::2] = gr
            awb_img[1::2, ::2] = gb
            awb_img[1::2, 1::2] = b
        elif self.bayer_pattern == 'bggr':
            b = self.img[::2, ::2] * b_gain
            r = self.img[1::2, 1::2] * r_gain
            gb = self.img[::2, 1::2] * gb_gain
            gr = self.img[1::2, ::2] * gr_gain
            awb_img[::2, ::2] = b
            awb_img[::2, 1::2] = gb
            awb_img[1::2, ::2] = gr
            awb_img[1::2, 1::2] = r
        elif self.bayer_pattern == 'gbrg':
            b = self.img[::2, 1::2] * b_gain
            r = self.img[1::2, ::2] * r_gain
            gb = self.img[::2, ::2] * gb_gain
            gr = self.img[1::2, 1::2] * gr_gain
            awb_img[::2, ::2] = gb
            awb_img[::2, 1::2] = b
            awb_img[1::2, ::2] = r
            awb_img[1::2, 1::2] = gr
        elif self.bayer_pattern == 'grbg':
            r = self.img[::2, 1::2] * r_gain
            b = self.img[1::2, ::2] * b_gain
            gr = self.img[::2, ::2] * gr_gain
            gb = self.img[1::2, 1::2] * gb_gain
            awb_img[::2, ::2] = gr
            awb_img[::2, 1::2] = r
            awb_img[1::2, ::2] = b
            awb_img[1::2, 1::2] = gb
        self.img = awb_img
        return self.clipping()

3.AWB 测试代码

'GRBG' bayer pattern 测试代码

测试代码创建8x8的图像,其中R和B通道的值分别为100和200.其中3.0, 1.0, 1.0, 1.0,这个参数分别为R,Gr,Gb,B通道的增益.

python 复制代码
    def test_bayer_pattern_grbg(self):
        """grbg 模式:Gr 在偶行偶列,R 在偶行奇列。"""
        img = np.zeros((8, 8), dtype=np.uint16)
        img[0::2, 1::2] = 100  # R 位置
        img[1::2, 0::2] = 200  # B 位置
        awb = WBGC(img.copy(), [3.0, 1.0, 1.0, 1.0], 'grbg', clip=2000)
        out = awb.execute()
        show_bayer_images('grbg', img, out, "left", "right-grgb-bayer")
        #self.assertEqual(int(out[0, 1]), 300)   # R×3
        #self.assertEqual(int(out[1, 0]), 200)   # B×1
  • 测试效果
    因为代码中的R通道的gain较大,我们可以知道,图像肯定是偏红的.

R 通道单独拉gain测试代码

生成一张8x8,pattern为RggB, 各通道值均为100的灰度图. 其中2.0, 1.0, 1.0, 1.0,这个参数分别为R,Gr,Gb,B通道的增益.

python 复制代码
    def test_r_gain_applied(self):
        """r_gain=2 时,R 通道(rggb 偶行偶列)值应翻倍。"""
        img = make_bayer_rggb(8, 8, r_val=100, g_val=100, b_val=100)
        awb = WBGC(img.copy().astype(np.uint16), [2.0, 1.0, 1.0, 1.0], 'rggb', clip=1023)
        out = awb.execute()
        show_bayer_images('rggb', img, out, "left", "right-rggb-AWB(r_gain)")
  • 效果图
    同理R通道相对于其它通道打了1被,可以理解图像偏红的.

4.实际平台AWB tuning是怎么做的

Tuning人员需要在标准灯箱中,使用不同色温的光源(如 D75、D65、D50、CW、TL84、A、H 等七种光源)拍摄 18% 灰卡 或24色色卡 。通过计算每张图片颜色的 R/G 和 B/G 比值,将这些数据点在坐标轴上作为参考点(锚点)。这些参考点用于帮助算法估计当前场景的相关色温(CCT)。

我们知道灰色的RGB各分量都是一样的,一般我们以G通道的值来作为基准,来计算R和B通道相对G通道的增益值.

如何计算AWB gain表

在灯箱环境下,拍摄灰卡图像,然后使用tuning工具计算gain表, 为了降低运算量,工具一般不会给每个像素点计算一个gain,而是在 RAW 域会将整张图像切分为固定大小的网格区块(Block)。工具只对这些区块进行统计,而不是逐像素处理。

  • 高通平台:通常支持将图像划分为如 17×13 的网格(接近 4:3 比例),每个区块负责采样并统计其对应区域的亮度与色彩信息。
  • 联发科(MTK)平台:AWB 统计值通常是记录每个 Block 输出中心像素的 R/G/B 值,用于后续的色温估计。
  • 通用做法:将拜尔(Bayer)图像分离为 R、GR、GB、B 通道,根据指定尺寸划分区块,并计算每个区块的平均 R、G、B 值。

计算gain的方式有2种

  • 全局增益 (Global Gain):在传统的灰度世界假设(Gray World)或完美反射体算法中,算法会汇总所有有效区块的 R/G 和 B/G 比例,计算出一组全局的 。这组增益随后会应用到整幅图像的所有像素上。

    这种情况我的理解是,在进行camera sensor选型的时候,模组厂会提供一组golden模组, 这时候需要tuning人员根据不同光源测算出golden模组的R_gain,G_gain(1.0),B_gain, 然后研发人员会将此值写入sensor OTP区域,以供sensor一开始能输出一个较好的图片.

  • ROI 约束白平衡(ROI-based WB):在复杂场景下,算法会选定具有已知色彩特性的局部区域(如中性灰区域、人脸肤色区域,或用户手动点击的区域)作为 ROI。算法仅对这些 ROI 内的区块进行统计分析,计算出增益后,再将其作为基准应用到整幅图像,从而避免大面积单色背景导致的偏色。

这里比如灰卡拍出来的图像是8x8的,且我们的**ROI是4x4的,**那么分别计算每个区域的平局R,G,B值,

然后根据如下公式计算.

R_gain = R/G

G_gain = 1.0

B_gain = B/G

这样得到的是一个2x2的gain表,

AWB 增益是如何应用的?

AWB 的本质是改变 RGB 感光电路信号的放大比例。在 Bayer 域(RAW 数据阶段),算法会对图像中的每一个像素点,根据其所在的颜色通道,乘以对应的增益系数。

假设在 D65 光源下,通过灰卡计算出的 AWB 增益为 R_gain, G_gain( 通常设置为1.0),B_gain,对于图像中的任意一个像素点(无论是灰卡还是红苹果),其校正后的像素值( R',G',B')计算公式为:

复制代码
>R′ = R × R_gain
G' = G x G_gain
B' = B x B_gain​
实际案例推演:D65 光源下的红苹果

在 D65(高色温,偏蓝)光源下,环境光中蓝光成分较多,红光成分较少。

假设通过灰卡标定,ISP 计算出的增益为: R_gain = 1.5, G_gain = 1.0, B_gain = 0.8.

  • 对于灰卡(中性色):
    原始 RGB 值为 (100, 100, 100)。
    应用增益后:

    R' = 100 x 1.5 = 150
    G' = 100 x 1.0 = 100
    B' = 100 x 0.8 = 80.

此时 R:G:B 的比例被拉平,灰卡成功还原为白色/灰色。

  • 对于红苹果(彩色):
    在 D65 光源下,红苹果吸收了大部分蓝光和绿光,反射了红光。假设传感器捕捉到的原始 RGB 值为 (120, 40, 30)。
    应用同样的增益后:

    R' = 120 x 1.5 = 180
    G' = 40 x 1.0 = 40
    B' = 30 x 0.8 = 24

结果分析:校正后的像素值为 (180, 40, 24)。虽然绝对值变大了,但 R:G:B 的相对比例(色彩属性)被完美保留了。因此,红苹果依然呈现鲜艳的红色,而不会变成白色。

相关推荐
armwind2 小时前
openISP学习1-openISP介绍
图像处理·计算机视觉
armwind2 小时前
openISP学习3-AAF— Anti-Aliasing Filter(抗混叠滤波)
人工智能·计算机视觉
FL16238631292 小时前
Synapse腹部CT多器官分割数据集png图片+掩码图片+颜色映射表
人工智能·计算机视觉
在水一缸3 小时前
深度解析:基于 3D Gaussian Splatting 技术的编辑器实践与原理
计算机视觉·3d·编辑器·aigc·3d建模·nerf·3d编辑器
装不满的克莱因瓶3 小时前
从梯度下降到 Adam 优化器:掌握神经网络参数优化的核心原理
人工智能·python·深度学习·神经网络·机器学习·计算机视觉·ai
armwind3 小时前
openISP学习6-CFA -Color Filter Array Interpolation(去马赛克)
图像处理·计算机视觉
香蕉鼠片13 小时前
数字化图像的过程
人工智能·深度学习·计算机视觉
埃科光电14 小时前
打通全场景检测痛点UB系列相机赋能多元智造场景
图像处理·数码相机·计算机视觉·制造·相机
A hao14 小时前
P2与P2.5 LED显示屏的5大区别
图像处理·人工智能·广告