ISP-AWB(Auto White Balance 白平衡)

简介:个人学习分享,如有错误,欢迎批评指正。

白平衡 ,字面上的理解是白色的平衡。白平衡是描述显示器中红、绿、蓝三基色混合生成后白色精确度的一项指标。白平衡是电视摄像领域一个非常重要的概念,通过它可以解决色彩还原和色调处理的一系列问题。白平衡是随着电子影像再现色彩真实而产生的,在专业摄像领域白平衡应用的较早。家用电子产品(家用摄像机、数码照相机)中也广泛地使用,然而技术的发展使得白平衡调整变得越来越简单容易,但许多使用者还不甚了解白平衡的工作原理,理解上存在诸多误区。它是实现摄像机图像能精确反映被摄物的色彩状况,有手动白平衡和自动白平衡等方式。许多人在使用数码摄像机拍摄的时候都会遇到这样的问题:在日光灯的房间里拍摄的影像会显得发绿,在室内钨丝灯光下拍摄出来的景物就会偏黄,而在日光阴影处拍摄到的照片则莫名其妙地偏蓝,其原因就在于白平衡的设置上

一、色彩学基础

1.光源与物体颜色

我们看到的白光是由多种色光复合而成,我们之所以可以辨别色彩很大原因取决于光线中包含的色光成分;

物体的颜色是由于光作用于物体,物体对光进行反射、吸收或透射后,在人眼所引起的一种视觉反映,没有光便没有色彩

相机拍摄的是物体接收光源照射后反射出来的色光,反射的那部分色光的色相就是物体的色彩。

在自然界绝大部分的物体均为非发光体,因此,物体的颜色依赖于光源,也就是说必须有光源我们才能看到一个五彩缤纷的世界。

2.三原色原理与色彩空间

人眼对红、绿、蓝最为敏感,人的眼睛像一个三色接收器的体系,大多数的颜色可以通过红、绿、蓝三色按照不同的比例合成产生。同样,绝大多数单色光也可以分解成红、绿、蓝三种色光,这是色度学的最基本的原理,也称三原色原理


3.色温

色温表示光线中包含颜色成分的一个计量单位。从理论上说,黑体温度指绝对黑体从绝对零度(-273℃)开始加温后所呈现的颜色。黑体在受热后,逐渐由黑变红,转黄,发白,最后发出蓝色光。当加热到一定的温度,黑体发出的光所含的光谱成分,就称为这一温度下的色温,计量单位为"K"(开尔文)。

如果某一光源发出的光,与某一温度下黑体发出的光所含的光谱成分相同,就称为某K色温。如100W灯泡发出的光的颜色,与绝对黑体在2527℃时的颜色相同,那么这只灯泡发出的光的色温就是:(2527+273)K=2800K。

4.色彩恒常性

色彩恒常性(Color constancy)是指当照射物体表面的颜色光发生变化时,人们对该物体表面颜色的知觉仍然保持不变的知觉特性。

图中左图圆圈中的五个色块由左至右看起来是"蓝黄红蓝绿",而右图圆圈中的五个色块,看起来也是"蓝黄红蓝绿"。即使左右两图的背景光源完全不同,也不影响你对这五个色块的色彩判断,这就是色彩恒常性。

图中左图中的蓝色方块(如左下箭头处),其实独立出来时的光谱根本是灰色,而右图的黄色方块(如右下箭头处),独立出来时的光谱也是灰色,但是这两个灰块看起来却分别变成了蓝色和黄色。

二、白平衡是什么?为什么需要?

1. 人眼为什么看起来"哪儿都不偏色"

  • 人眼有色彩恒常性(color constancy):在钨丝灯房间、阴天街头,你仍会觉得白纸是白的。
  • 生理机制:大脑会对三种视锥(L/M/S,近似红绿蓝)进行自适应归一化和情景推断(同时参考记忆色:肤色、天空、草地)。
  • 结论:人眼会"自动白平衡" ;但相机的传感器不会。
  • 不同光源下sensor的成像结果

2. 相机为什么会偏色(物理本质)

相机每个像素(以 Bayer 传感器为例)的红/绿/蓝响应可写成:

S c ( x ) = ∫ λ E ( λ )   R ( x , λ )   Q c ( λ )   d λ + n c , c ∈ { R , G , B } S_c(x)=\int_{\lambda} E(\lambda)\,R(x,\lambda)\,Q_c(\lambda)\,d\lambda + n_c,\quad c\in\{R,G,B\} Sc(x)=∫λE(λ)R(x,λ)Qc(λ)dλ+nc,c∈{R,G,B}

  • E ( λ ) E(\lambda) E(λ):光源的光谱功率分布(SPD)------钨丝灯在红端强、天空在蓝端强、很多 LED / 荧光灯有不连续谱且偏绿。
  • R ( x , λ ) R(x,\lambda) R(x,λ):物体表面的光谱反射率。
  • Q c ( λ ) Q_c(\lambda) Qc(λ):相机第 c c c 个通道的光谱灵敏度(与 CFA/微滤镜有关)。
  • 如果场景白色物体 R ( λ ) ≈ R(\lambda)\approx R(λ)≈ 常数(即"中性"),那么 S R : S G : S B S_R:S_G:S_B SR:SG:SB 主要由光源 E ( λ ) E(\lambda) E(λ) 与传感器灵敏度 Q c ( λ ) Q_c(\lambda) Qc(λ) 决定
    因此在暖光下蓝通道会偏低、在冷光下红通道偏低,直接导致整图偏黄/偏蓝,LED/荧光灯还会偏绿或偏品(tint)。

3. 白平衡是什么(工程定义)

  • 目标 :让在真实世界中应该"中性"的东西(白、灰、银)在图像里也呈中性;换句话说,把"拍到的照明白点"拉到目标白点 (通常是 sRGB 的 D65)。
  • 方法 :在 RAW 空间对三通道做对角增益(Von Kries 假设):

I ′ ( x ) = d i a g ( g R , g G , g B )   I ( x ) \mathbf{I}'(x)=\mathrm{diag}(g_R,g_G,g_B)\,\mathbf{I}(x) I′(x)=diag(gR,gG,gB)I(x)

一般以 G G G 为基准 g G = 1 g_G=1 gG=1,按估计的光源把 R , B R,B R,B 放大/缩小,抵消光源色偏

4. 为什么"必须"做白平衡(不仅是好看)

  1. 与显示/色彩标准对齐

    • sRGB/Rec.709 的参考白点是 D65 ;打印常用 D50 。如果不把"场景白点"拉到"标准白点",同一张图在不同设备上会表现出系统性偏色
  2. 避免不可逆的信息损失

    • JPEG管线里,WB 会影响后续亮度映射与量化。如果先不做 WB 就强行压高光,某通道可能过曝/剪裁,之后再补救会发现颜色回不来。
    • 在暖光下蓝通道很弱,后补蓝等于放大噪声与量化误差;在 RAW 前期正确做 WB,能显著改善信噪比观感。
  3. 影响 CCM/噪声/降噪

    • 很多相机会按 WB 估计在两套(或多套)日光/钨丝 CCM 之间插值;WB 不准会连带 CCM 不准。
    • 白平衡增益改变通道噪声水平与动态范围分配,影响降噪与后级的"肤色、天空"再现。
  4. 与人眼感知一致

    • 用户主观期待"白纸像白纸、肤色自然",这正是白平衡要达成的感知目标。专业创作中可以故意不完全中和(保暖/保冷),但自动流程需要先把"技术中性"打好。

5. 色温与 Tint:两条轴都要管

  • 色温(CCT):蓝↔黄轴的冷暖,单位 K(例如 2800K 钨丝灯,5500--6500K 日光)。
  • Tint(偏绿↔偏洋红) :由光谱不匹配引起(荧光/LED 常偏绿),单调色温不足以纠正,必须加 Tint 轴
  • 现代相机/手机 AWB 实际估计的是"白点(x,y) "或"(CCT, Duv) ",然后映射到 ( g R , g G , g B ) (g_R,g_G,g_B) (gR,gG,gB)。

6. "白"的严格含义

  • 严格地说,"白/灰"是光谱反射率在可见光范围内大致平坦的材料。只有这种材料在任意光源下被"正确白平衡"后才会显中性。
  • 许多生活中的"白物"并不严格中性(涂料增白剂、纸张荧光增白),它们的"看起来白"更多源自人眼的恒常性 ,对相机而言仍可能带来偏差。因此工程上常用标准灰卡/ColorChecker 的中性块做标定与评测。

7. 一个最直观的"灰卡思维实验"

  • 在 2800K 钨丝灯下拍一张灰卡,得到三通道均值 ( μ R , μ G , μ B ) (\mu_R,\mu_G,\mu_B) (μR,μG,μB);通常 μ R > μ G ≫ μ B \mu_R>\mu_G\gg\mu_B μR>μG≫μB。
  • 设 g G = 1 , g R = μ G / μ R , g B = μ G / μ B g_G=1,\ g_R=\mu_G/\mu_R,\ g_B=\mu_G/\mu_B gG=1, gR=μG/μR, gB=μG/μB,把整图乘以这些增益。
  • 结果:灰卡回到 R ≈ G ≈ B R\approx G \approx B R≈G≈B,白点被拉回 D65;其他物体颜色也随之"去偏色"。

8. 白平衡≠颜色校正≠曝光

  • 白平衡(WB):通道独立缩放,抵消光源色偏。
  • 颜色校正(CCM):一个 3×3 线性变换,把"相机RGB"映射到目标色域(sRGB/AdobeRGB)。
  • 曝光:整体亮度控制(快门/光圈/ISO/曲线),改变的是亮度,不是色偏。三者相辅相成,但职能不同。

9. 什么时候"自动白平衡"也不想完全中和?

  • 审美与"记忆色" :人们"记忆中的钨丝灯"就是温暖的,日落应该偏金。很多相机的 AWB 具有"保暖策略",不过度中和以保留氛围,尤其在人像与夜景。
  • 但在科研/测量或可复现的成像里(机器视觉、色彩管理)通常需要严格中性

白平衡就是把"拍到的照明白点"挪到"标准白点"(如 D65)

它以 RAW 三通道对角增益为核心,既是色彩还原的"地基",也是避免噪声放大、通道剪裁、CCM 选择错误的关键一步。


三、 成像与校正的简化模型

1. 从"光谱积分"到"三通道向量"的两步近似

最准确的传感器成像(以 Bayer 传感器为例)可写成:

S c ( x ) = ∫ λ E ( λ )   R ( x , λ )   Q c ( λ )   d λ + n c ( x ) , c ∈ { R , G , B } S_c(x)=\int_{\lambda} E(\lambda)\,R(x,\lambda)\,Q_c(\lambda)\,d\lambda + n_c(x),\quad c\in\{R,G,B\} Sc(x)=∫λE(λ)R(x,λ)Qc(λ)dλ+nc(x),c∈{R,G,B}

  • E ( λ ) E(\lambda) E(λ):光源的光谱功率分布(SPD)
  • R ( x , λ ) R(x,\lambda) R(x,λ):像素位置 x x x 处物体的光谱反射率
  • Q c ( λ ) Q_c(\lambda) Qc(λ):相机第 c c c 通道的光谱灵敏度
  • n c ( x ) n_c(x) nc(x):噪声/黑电平偏置等

这是真实世界,但直接用它做白平衡太重。于是工程上做两步近似

近似A:中性物体近似常数反射

对"灰/白"区域,令 R ( x , λ ) ≈ ρ ( x ) R(x,\lambda)\approx \rho(x) R(x,λ)≈ρ(x)(在可见光内大致平坦)。

则:

S c neutral ( x ) ≈ ρ ( x ) ∫ E ( λ )   Q c ( λ )   d λ    ≜    ρ ( x )   L c S_c^{\text{neutral}}(x)\approx \rho(x)\int E(\lambda)\,Q_c(\lambda)\,d\lambda \;\triangleq\; \rho(x)\,L_c Scneutral(x)≈ρ(x)∫E(λ)Qc(λ)dλ≜ρ(x)Lc

这把光源对三通道的综合作用,压缩成一个三维向量 L = [ L R , L G , L B ] T \mathbf{L}=[L_R,L_G,L_B]^T L=[LR,LG,LB]T。

近似B:对角模型(Von Kries 假设)

认为光源变化对颜色的影响,在相机 RGB 空间里可以用每通道各自缩放来补偿

于是对任意像素(非必为中性):

I ( x ) ≈ R ( x ) ⊙ L ⇒ d i a g ( g R , g G , g B ) ⏟ D    I ( x ) ≈ R ( x ) ⊙ ( D L ) \mathbf{I}(x) \approx \mathbf{R}(x)\odot \mathbf{L} \quad\Rightarrow\quad \underbrace{\mathrm{diag}(g_R,g_G,g_B)}_{\mathbf{D}}\;\mathbf{I}(x) \approx \mathbf{R}(x)\odot \big(\mathbf{D}\mathbf{L}\big) I(x)≈R(x)⊙L⇒D diag(gR,gG,gB)I(x)≈R(x)⊙(DL)

要"校白",只需选 D \mathbf{D} D 使 D L ∝ [ 1 , 1 , 1 ] T \mathbf{D}\mathbf{L}\propto [1,1,1]^T DL∝[1,1,1]T。

结论:白平衡 = 估计光源三通道 L \mathbf{L} L,然后乘以其"近似倒数"的增益。

注意:这两个近似在大多数自然光/常见灯下管用,但对窄谱/怪谱 LED、强荧光、混合光会变差。


2. 用模型推导"白平衡增益"的计算式

设场景中"应为中性"的像素的观测均值为 μ = [ μ R , μ G , μ B ] T \boldsymbol{\mu}=[\mu_R,\mu_G,\mu_B]^T μ=[μR,μG,μB]T。

对于中性目标,它满足 μ ∝ L \boldsymbol{\mu}\propto \mathbf{L} μ∝L(忽略尺度 ρ \rho ρ)。

我们要 D μ ∝ [ 1 , 1 , 1 ] T \mathbf{D}\boldsymbol{\mu}\propto [1,1,1]^T Dμ∝[1,1,1]T。最简单的选择是:

g R = k μ R , g G = k μ G , g B = k μ B g_R = \frac{k}{\mu_R},\quad g_G = \frac{k}{\mu_G},\quad g_B = \frac{k}{\mu_B} gR=μRk,gG=μGk,gB=μBk

其中 k k k 是任意正常数(选来保证不改变整体亮度或令 g G = 1 g_G=1 gG=1)。

在工程里常用G 为参照归一化

g G = 1 , g R = μ G μ R , g B = μ G μ B g_G = 1,\quad g_R = \frac{\mu_G}{\mu_R},\quad g_B = \frac{\mu_G}{\mu_B} gG=1,gR=μRμG,gB=μBμG

这样一来,中性区域被拉回 R ≈ G ≈ B R\approx G\approx B R≈G≈B,整图去偏色。

数值小例子(比如钨丝灯下):

  • 中性块测到均值: μ R = 0.60 ,    μ G = 0.40 ,    μ B = 0.20 \mu_R=0.60,\;\mu_G=0.40,\;\mu_B=0.20 μR=0.60,μG=0.40,μB=0.20
  • 则 g R = 0.40 / 0.60 = 0.667 ,    g G = 1.0 ,    g B = 0.40 / 0.20 = 2.0 g_R=0.40/0.60=0.667,\;g_G=1.0,\;g_B=0.40/0.20=2.0 gR=0.40/0.60=0.667,gG=1.0,gB=0.40/0.20=2.0
  • 解释:压一点红大幅抬蓝,就是把暖光的黄偏(蓝弱)纠回来。

3. 与 CCT / Tint 的关系(把三通道"倒数"换成两维参数)

有时不直接报 ( g R , g G , g B ) (g_R,g_G,g_B) (gR,gG,gB),而是报色温 CCT(蓝↔黄)Tint(绿↔品)。:

  • 先把估计到的白点从相机 RGB 映射到某标准空间(XYZ 或相机自定义的"白点平面"),
  • 得到白点的色度 ( x , y ) (x,y) (x,y) 或 ( u ′ , v ′ ) (u',v') (u′,v′),再换算成 ( CCT , Duv ) (\text{CCT}, \text{Duv}) (CCT,Duv)(Duv 对应"偏绿/偏品")。
  • 最终还是要落回一个三通道增益来乘 RAW,只是参数化成了"CCT+Tint"。

因为许多真实光源(LED/荧光)仅用"色温"一条轴不够描述,所以加 Tint 轴来补偿"偏绿/偏品"。


4. 与 DNG 元数据(AsShotNeutral)的换算

DNG/RAW 文件里常有 AsShotNeutral(ASn),它记录了拍摄时相机内部用到的白点信息。经验上:

  • 若 ASn = [ n R , n G , n B ] [n_R, n_G, n_B] [nR,nG,nB](越大表示该通道原本越强/需要越少增益),
  • 则常用的白平衡增益近似为:

g R ∝ 1 n R , g G ∝ 1 n G , g B ∝ 1 n B , g_R \propto \frac{1}{n_R},\quad g_G \propto \frac{1}{n_G},\quad g_B \propto \frac{1}{n_B}, gR∝nR1,gG∝nG1,gB∝nB1,

再做一次以 G G G 为 1 的归一化即可实用化(不同厂商存在细节差异,但"取倒数再归一化"是通行做法)。


5. 在 Bayer RAW 上如何"真正乘增益"?

  • 先黑电平校正 : I c ← max ⁡ ( I c − black_level c , 0 ) I_c \leftarrow \max(I_c - \text{black\_level}_c, 0) Ic←max(Ic−black_levelc,0)

  • 按 CFA 通道分别乘

    • 有的管线分 R , G r , G b , B R,Gr,Gb,B R,Gr,Gb,B 四路各乘(更精细;Gr 与 Gb 灵敏度略有差异)
    • 也有先把 G r , G b Gr,Gb Gr,Gb 合并成 G G G 再统一乘
  • 再去马赛克:避免"先插值后放大噪声"的副作用

  • 注意溢出与剪裁:乘增益可能让高光更容易饱和;工程里会联动高光压缩/恢复


6. 对角模型的适用范围与局限

  • 适用:自然光、卤素/钨丝、太阳直射/阴影、CRI 高的 LED 等大多数场景

  • 不那么准

    1. 窄谱/多峰 LED、荧光灯 :相机 Q c ( λ ) Q_c(\lambda) Qc(λ) 与光源谱 E ( λ ) E(\lambda) E(λ) 的耦合使得"每通道独立缩放"不足以完全中和,容易出现 Tint 残留;
    2. 混合光 (窗外日光 + 室内钨丝): L \mathbf{L} L 空间随位置 x x x 变化,单一全局增益没法同时校正 → 需分区 AWB人像/天空优先权重
    3. 强彩色物体主导 (大草地、蓝海、彩灯):估计 L \mathbf{L} L 被"误导" → 需更稳健的统计(分位点/灰边)或学习法。

当对角模型不够时,专业做法是:

  • 把图像先线性映射到 XYZ 或"CAT 空间"(Bradford/Von Kries/Sharp),
  • 做一次色度适应 : X ′ Y ′ Z ′ = M − 1 d i a g ( w t w s ) M X Y Z \mathbf{X'Y'Z'}=M^{-1}\mathrm{diag}(\frac{w_t}{w_s})M\mathbf{XYZ} X′Y′Z′=M−1diag(wswt)MXYZ(把白点 w s w_s ws 变到目标 w t w_t wt),
  • 然后再回到工作空间。手机/相机里常把 WB + CCM + CAT 打包"联合学习/插值"。

7. 如何从模型"稳健地"估计 L \mathbf{L} L(也就是算出增益)

把 1--2 的思路落到算法就是"找中性、估 L \mathbf{L} L、取倒数、归一化"。常见稳健技巧:

  1. 灰世界(Gray-World) : μ c = \mu_c= μc= 全图均值或中位数;简单鲁棒。

    • 加强:对饱和/暗噪声像素做掩码 ,对像素值使用 p p p-范数(Shades-of-Gray),或对梯度做统计(Gray-Edge)。
  2. 白点/最大值(White-Patch/Percentile):取每通道 95--99% 分位值代替"最大值",避免被少数饱和点误导。

  3. 目标检测/语义先验 :检测灰卡、人脸、纸张等"记忆中性/记忆色"区域,按置信度加权估计。

  4. 分区/金字塔 :网格估计 L ( x ) \mathbf{L}(x) L(x) 再平滑融合,处理混合光。

  5. 学习法 :CNN/Transformer 直接回归白点(CCT+Tint 或 L \mathbf{L} L),并用肤色/天空损失约束。


8. 与 CCM(颜色校正矩阵)的相互作用

  • WB 先于 CCM是最常见流程:

    RAW → 黑电平    → WB ( D )    → 去马赛克    → CCM ( M )    → 曲线/伽马 \text{RAW}\xrightarrow{\text{黑电平}}\; \xrightarrow{\text{WB (}\mathbf{D}\text{)}} \;\xrightarrow{\text{去马赛克}}\; \xrightarrow{\text{CCM (}\mathbf{M}\text{)}} \;\xrightarrow{\text{曲线/伽马}} RAW黑电平 WB (D) 去马赛克 CCM (M) 曲线/伽马

  • 原因:WB 是通道缩放;CCM 是 3×3 线性变换(把相机 RGB 映到 sRGB/XYZ)。如果 WB 不准,后面的 CCM 插值(日光/钨丝两套矩阵之间)也会选错位置,产生二次偏色。

  • 高级做法:联合优化 WB+CCM 或在 CAT 空间做适应,以提升在"怪谱光源"下的还原。


9. 实操流程小抄(按模型落地)

  1. 取中性 ROI (灰卡/白物/人脸高光区)或用稳健统计估计 μ \boldsymbol{\mu} μ。

  2. 算增益 : g G = 1 ,    g R = μ G / μ R ,    g B = μ G / μ B g_G=1,\;g_R=\mu_G/\mu_R,\;g_B=\mu_G/\mu_B gG=1,gR=μG/μR,gB=μG/μB。

  3. RAW 域应用:黑电平→逐 CFA 通道乘增益→去马赛克。

  4. 防护

    • 排除饱和像素(如 >99% 分位),
    • 对蓝通道增益设上限(防噪声被过度放大),
    • 需要时做分区估计并平滑融合。
  5. 后续 :根据白点在 CCM 间插值,进入曲线/伽马;有需要再做轻微的 Tint 微调


简化模型把"光谱世界"压缩为三通道向量

观测 I ( x ) ≈ R ( x ) ⊙ L \mathbf{I}(x)\approx \mathbf{R}(x)\odot \mathbf{L} I(x)≈R(x)⊙L,白平衡就是找 D = d i a g ( g ) \mathbf{D}=\mathrm{diag}(g) D=diag(g) 让 D L ∝ [ 1 , 1 , 1 ] \mathbf{D}\mathbf{L}\propto[1,1,1] DL∝[1,1,1]。

工程里用"估白点→取倒数→归一化"的增益法在 RAW 上执行;当光谱很"怪"或混合光时,再引入 Tint、CAT、分区或学习法补强。


四、入门级常见算法(从简单到复杂)

1. Gray-World(灰世界)

概念 :整幅场景的平均颜色应为"灰"(R≈G≈B)。
步骤

  1. 在 RAW 线性域取掩码(排除过曝、全黑、死点)。
  2. 计算各通道均值/中位数 μ R , μ G , μ B \mu_R,\mu_G,\mu_B μR,μG,μB。
  3. 设 g G = 1 , g R = μ G / μ R , g B = μ G / μ B g_G=1,\ g_R=\mu_G/\mu_R,\ g_B=\mu_G/\mu_B gG=1, gR=μG/μR, gB=μG/μB,对全图乘以增益。
    超参 :均值 vs 中位数;是否做亮度加权;掩码阈值(如上 99%/下 1%)。
    优点 :实现超简单、鲁棒、速度快(O(N))。
    缺点 :大面积单色(草地/海面/蓝天)会"骗"它;弱光噪声对均值影响大。
    适用/坑 :通用起步法;注意先黑电平线性域剔除饱和与暗噪声

(a) 灰世界 / 中位数版

python 复制代码
# I_r, I_g, I_b 为线性RAW三个通道,mask 为有效像素掩码
r = np.median(I_r[mask]); g = np.median(I_g[mask]); b = np.median(I_b[mask])
gains = np.array([g/r, 1.0, g/b])
I_r_wb = np.clip(I_r * gains[0], 0, maxv)
I_g_wb = np.clip(I_g * gains[1], 0, maxv)
I_b_wb = np.clip(I_b * gains[2], 0, maxv)

2. White-Patch / Max-RGB(白点/最大值法)

概念 :场景里总有接近白/高亮的区域,可拿来对齐白点。
步骤

  1. 取每通道亮度的高分位(如 95% 或 99%)而非最大值(防噪声/坏点)。
  2. 用这三个分位数作 μ R , μ G , μ B \mu_R,\mu_G,\mu_B μR,μG,μB 去算增益。
    超参 :分位数 p(95--99% 常用);高光掩码(剔除饱和)。
    优点 :有"白物/高亮"时很准;简单快。
    缺点 :若高亮是有色反射(彩灯、金属反光),会误导。
    适用/坑 :产品拍摄、文档拍摄等常有白背景;要排除饱和与彩色高光。

(b) 白点 / 分位数版(95%)

python 复制代码
pr = np.percentile(I_r[mask], 95)
pg = np.percentile(I_g[mask], 95)
pb = np.percentile(I_b[mask], 95)
gains = np.array([pg/pr, 1.0, pg/pb])

3. Shades-of-Gray(灰度 p-范数)

概念 :介于"全局均值"(p=1)与"最大值法"(p→∞)之间,用 p p p-范数平衡鲁棒性与高亮信息。
步骤

g c ∝ ( 1 ∣ Ω ∣ ∑ x ∈ Ω I c ( x ) p ) − 1 / p , c ∈ { R , G , B } g_c \propto \left(\frac{1}{|\Omega|}\sum_{x\in\Omega}I_c(x)^p\right)^{-1/p},\quad c\in\{R,G,B\} gc∝(∣Ω∣1x∈Ω∑Ic(x)p)−1/p,c∈{R,G,B}

再归一化使 g G = 1 g_G=1 gG=1。
超参 : p p p(常 4--10);掩码 Ω \Omega Ω。
优点 :能在"灰世界"与"白点法"间找到折中,抗单色场景稍好。
缺点 : p p p 需要调;极端颜色分布仍会偏。
适用/坑:风光、街拍的简单稳健基线;

© Shades-of-Gray(p-范数)

python 复制代码
p = 6
mr = (np.mean((I_r[mask]**p)))**(1/p)
mg = (np.mean((I_g[mask]**p)))**(1/p)
mb = (np.mean((I_b[mask]**p)))**(1/p)
gains = np.array([mg/mr, 1.0, mg/mb])

4. Gray-Edge(灰边)

概念 :颜色的"边"(梯度)包含物体真实色的信息,比纯像素值统计更稳。
步骤

  1. 线性域做高斯平滑(σ),再计算各通道一阶/二阶梯度幅值 ∣ ∇ I c ∣ |\nabla I_c| ∣∇Ic∣ 或 ∣ ∇ 2 I c ∣ |\nabla^2 I_c| ∣∇2Ic∣。
  2. 用 Shades-of-Gray 的 p p p-范数去统计梯度幅值,得各通道"代表值"。
  3. 反推增益并归一化。
    超参 :导数阶数 n=1/2、σ(1--3 像素)、 p p p(3--8)。
    优点 :对大面积单色背景更稳;细节丰富时效果好。
    缺点 :纹理少/大平面场景不占优;参数多。
    适用/坑 :室外自然场景、复杂纹理;先去噪/降采样可稳。

(d) Gray-Edge(n=1, σ=1.5, p=6)

python 复制代码
I_rs = gaussian(I_r, sigma=1.5); I_gs = gaussian(I_g, sigma=1.5); I_bs = gaussian(I_b, sigma=1.5)
Gr = np.hypot(sobelx(I_rs), sobely(I_rs))
Gg = np.hypot(sobelx(I_gs), sobely(I_gs))
Gb = np.hypot(sobelx(I_bs), sobely(I_bs))
mr = (np.mean(Gr[mask]**p))**(1/p); mg = (np.mean(Gg[mask]**p))**(1/p); mb = (np.mean(Gb[mask]**p))**(1/p)
gains = np.array([mg/mr, 1.0, mg/mb])

5. Gamut Mapping(色域映射/可实现色域)

概念 :在白光下"物体颜色云"的可实现集合(gamut)有边界;估计光源就是找一组通道缩放,使观测颜色经缩放后落回 该已知色域。
步骤

  1. 离线 :在标定白光下采集大量物体/表面,建"可实现色域" G \mathcal{G} G(在某色度/归一化空间)。
  2. 在线 :搜索对角缩放 D \mathbf{D} D,使 D ⋅ colors o b s ⊆ G \mathbf{D}\cdot \text{colors}_{obs}\subseteq \mathcal{G} D⋅colorsobs⊆G,用最小体积/最小外推等准则选最优 D \mathbf{D} D。
    超参 :色域表示方式(凸包/多面体)、搜索与准则。
    优点 :理论优雅、效果好;对"非灰世界"场景稳。
    缺点 :实现复杂、需要标定数据。
    适用/坑 :相机厂商/研究型项目;需稳定的标定流程

6. Bayesian / 先验驱动(MAP)

概念 :把"自然图像颜色分布""光源分布(CCT/Tint)""记忆色(肤色/天空)"作为先验,做概率推断。
步骤(示意)

L ^ = arg ⁡ max ⁡ L p ( L ) ∏ x ∈ Ω p ( I ( x ) ∣ L ) \hat{L}=\arg\max_L\ p(L)\prod_{x\in\Omega}p(I(x)\mid L) L^=argLmax p(L)x∈Ω∏p(I(x)∣L)

可用 EM/采样/离散网格。
超参 :先验形式、似然建模、采样密度。
优点 :可注入知识(室内常见 2700--4000K、肤色带...);在弱特征场景仍可给出合理估计。
缺点 :模型设定影响大,调参成本高。
适用/坑:静态图片、需要稳定而非极致准确。


7. 学习法(CNN/Transformer/混合专家)

概念 :用数据学"从图像到白点"的直接映射,并结合语义(人脸/天空/草地)与上下文(多帧/曝光/ISP 状态)。
常见设计

  • 输入:缩略图(例如 224×224 线性域)、亮度/梯度图、语义分割/人脸检测热图;
  • 输出 :白点 ( x , y ) (x,y) (x,y) 或 ( C C T , D u v ) (CCT,Duv) (CCT,Duv) 或直接 ( g R , g G , g B ) (g_R,g_G,g_B) (gR,gG,gB);
  • 损失角误差(Angular Error) 、 ℓ 1 / ℓ 2 \ell_1/\ell_2 ℓ1/ℓ2、感知损失;
  • 结构 :轻量 CNN(移动端)、ViT/ConvNeXt、Mixture-of-Experts(日光专家/钨丝专家/LED 专家);
  • 视频 :时域平滑、RNN/时序注意力,避免画面抖动。
    优点 :综合复杂先验,混合光/非平坦光谱下表现好。
    缺点 :需数据与标注(或弱标注/自监督),部署要考虑算力与延迟。
    适用/坑 :手机/相机/AR 实时 AWB;注意域外泛化不同传感器迁移。

8. 语义/人像优先(Skin/Sky-aware)

概念 :肤色、天空等"记忆色"很敏感。检测这些区域后加权 估计白点或直接回归。
步骤 :检测人脸/皮肤/天空 → 统计这些区域的中性度/色度偏移 → 与全局估计加权融合。
优点 :人像与风光中主观观感显著提升。
缺点 :依赖检测精度;错误检测会拉偏。
适用/坑 :人像模式、旅游风景;注意逆光高亮肤色不等于白。


9. 分区/多光源(Spatial AWB, Bi-Illuminant)

概念 :混合光下单一增益不可能同时校正。
做法 :网格估计 L ( x ) \mathbf{L}(x) L(x) 或拟合"两光源模型"并按位置插值融合;人脸/前景可贴近其局部白点。
优点 :复杂照明下更自然。
缺点 :可能引入空间不连续/接缝;算力更高。
适用/坑 :室内外混合、舞台灯;加正则化与引导滤波平滑过渡。


五、实操:最小可用 AWB 步骤

1. 准备与素材

  • 素材:一张包含中性目标(灰卡/白卡/银色金属/白纸)的 RAW(DNG 最佳;没有也能做)。

  • 基本工具(任意其一都行)

    • 桌面:rawpy(读 DNG)、numpy/opencv(算增益与掩码)。
    • 或 Lightroom/RawTherapee:用于"肉眼确认"与比对机内 WB。
  • 原则WB 一定在"线性 RAW、去黑电平"后 做;在去马赛克前做最稳。


2. 管线顺序(最小版)

黑电平校正 →(可选 LSC)→ 白平衡(对角增益)→ 去马赛克 →(降噪/锐化)→ CCM → 伽马/曲线 → 输出

  • 黑电平校正: I c ← max ⁡ ( I c − black_level c , 0 ) I_c \leftarrow \max(I_c - \text{black\_level}_c, 0) Ic←max(Ic−black_levelc,0)
  • 白平衡(WB): I ′ = d i a g ( g R , g G , g B )   I \mathbf{I}' = \mathrm{diag}(g_R,g_G,g_B)\,\mathbf{I} I′=diag(gR,gG,gB)I(见 §4/5 如何算 g g g)
  • CCM:把相机 RGB 送到 sRGB/XYZ;先 WB,后 CCM

3. 优先方案 1:直接复现机内 WB(有 DNG 元数据时)

目的:快速得到"机内 WB 的复现值",作为你算法的参考基线。

  1. 读取 DNG 元数据:

    • AsShotNeutral(ASn,形如 [ n R , n G , n B ] [n_R,n_G,n_B] [nR,nG,nB]),或 AsShotWhiteXY
  2. 将 ASn 转增益:

    • 经验做法:先取倒数再归一化

      g c ′ = 1 n c , g c = g c ′ g G ′ ( 令 g G = 1 ) g'_c = \frac{1}{n_c},\quad g_c = \frac{g'_c}{g'_G}\ \ (\text{令 } g_G=1) gc′=nc1,gc=gG′gc′ (令 gG=1)

  3. 应用到 RAW(三/四通道,见 §6),再继续去马赛克与后级处理。

  4. 对比相机 JPEG 或 use_camera_wb=True 的渲染,确认一致性。

说明:不同厂商对 ASn 的定义细节略有差异,但"取倒数+归一化"在多数机型上可较好复现机内 WB。


4. 方案 2:有灰卡/白卡(ROI 法,最稳)

目的:用场景中已知中性区域估计白点,得到最可信的最小 AWB。

  1. 选 ROI :框出灰卡/白卡/中性金属面;ROI 要均匀且不饱和

  2. 去黑电平 后,计算 ROI 的三通道统计量(推荐中位数截尾均值):

    μ R , μ G , μ B \mu_R,\ \mu_G,\ \mu_B μR, μG, μB

    • 截尾建议:去掉 ROI 中上下各 5% 的极端像素,抑制噪声与反光点。
  3. 算增益并归一化(以 G 为 1):

    g G = 1 , g R = μ G μ R , g B = μ G μ B g_G=1,\quad g_R=\frac{\mu_G}{\mu_R},\quad g_B=\frac{\mu_G}{\mu_B} gG=1,gR=μRμG,gB=μBμG

  4. 应用增益(§6),再去马赛克与后级处理。

  5. 查看效果 :ROI 应回到 R ≈ G ≈ B R\approx G\approx B R≈G≈B;若有偏绿/偏品,见 §6.8 微调 Tint。


5. 方案 3:无灰卡/白卡(稳健统计法)

目的:没有已知中性目标时,使用"灰世界/白点/混合法"得到可用的 WB。

A. 灰世界(Gray-World,中位数版)

  1. 掩码 Ω:剔除饱和(>99% 分位)与死黑(<1% 分位)像素。
  2. 对 Ω 内每通道取中位数截尾均值 : μ R , μ G , μ B \mu_R,\mu_G,\mu_B μR,μG,μB。
  3. g G = 1 , g R = μ G / μ R , g B = μ G / μ B g_G=1,\ g_R=\mu_G/\mu_R,\ g_B=\mu_G/\mu_B gG=1, gR=μG/μR, gB=μG/μB。

B. 白点(Percentile-White,分位数版)

  1. 同样构建掩码 Ω。
  2. 取每通道的 95--99% 分位数 : p R , p G , p B p_R,p_G,p_B pR,pG,pB。
  3. g G = 1 , g R = p G / p R , g B = p G / p B g_G=1,\ g_R=p_G/p_R,\ g_B=p_G/p_B gG=1, gR=pG/pR, gB=pG/pB。

C. 折中(Shades-of-Gray,p-范数)

m c = ( 1 ∣ Ω ∣ ∑ x ∈ Ω I c ( x ) p ) 1 / p , g G = 1 , g R = m G / m R , g B = m G / m B m_c=\left(\frac{1}{|\Omega|}\sum_{x\in\Omega} I_c(x)^p\right)^{1/p},\quad g_G=1,\ g_R=m_G/m_R,\ g_B=m_G/m_B mc=(∣Ω∣1x∈Ω∑Ic(x)p)1/p,gG=1, gR=mG/mR, gB=mG/mB

  • 典型 p = 6 p=6 p=6,兼顾高亮信息和鲁棒性。

经验融合

  • 实战常用"灰世界 "(中位数)与"白点 95% "各得一组增益,再加权平均(如 0.6/0.4)或二选一(通过灰度一致性/肤色自然度评分自动挑选)。

6. 在 Bayer RAW 上"正确应用增益"

  • 先黑电平:对 R/Gr/Gb/B 四路分别减去对应黑电平(相机常给每路不同 BL)。

  • 逐 CFA 通道乘

    • 细做法:对 R、Gr、Gb、B 分别乘 [ g R , g G , g G , g B ] [g_R,g_G,g_G,g_B] [gR,gG,gG,gB]。
    • 粗做法:把 Gr/Gb 合并为 G,再乘三通道增益。
  • 溢出保护:乘完增益后裁剪到传感器位深范围(如 14/16 bit);必要时先做高光压缩/卷绕。

  • 顺序:WB → 去马赛克;先去马赛克再放大会把噪声/插值误差放大。


7. 数据清洁与掩码(非常关键)

  • 饱和剔除 :各通道 >99% 分位(或接近 white_level)的像素排除。
  • 暗噪声剔除 :<1% 分位或低于 3 σ 3\sigma 3σ 噪声门限排除。
  • 彩色高光排除:若某通道接近饱和而其他通道明显低,判为彩色镜面高光,排除。
  • 坏点/列校正:必要时做简单去坏点或中值滤波后再统计。

8. Tint(绿↔品)微调(两种简单做法)

方法 1:G 通道平衡法(快而粗)

  • 对 Bayer 的 Gr 与 Gb,若统计值差异过大,说明有绿品相位偏移;对 G 的两路分别做轻微缩放,使 Gr≈Gb,再把合并后的 G 作为基准。

方法 2:色度微调(准一些)

  1. 去马赛克后,把图像转到 xy 色度(或 u'v')。
  2. 取中性 ROI 的白点坐标 ( x , y ) (x,y) (x,y),沿 等 CCT 线方向微调,使其靠近目标白(sRGB 的 D65)。
  3. 反推出一组微调矩阵(或在 RGB 中按绿品轴做 1--2% 的小幅旋转/缩放),再应用到全图。

9. 评估与验收(定量 + 观感)

  • Angular Error(°):把估计白点与参考白点单位化后算夹角,< 3° 常被视作可用,< 2° 较好。
  • 灰阶检查:灰卡多档应接近中性(R≈G≈B),无明显绿/品偏。
  • 肤色/天空:肉眼观感是否自然(不"蜡黄"或"品红脸")。
  • 对比基线:与机内 WB(§6.3)或 Lightroom 手动对齐的结果对比。

10. 常见问题与快速排错

  • 蓝通道噪声被放大 (暖光下 g B g_B gB 很大)
    → 上限约束(如 g B ≤ 3 g_B \le 3 gB≤3),或在 WB 前做轻噪声抑制,或加一点亮度加权(弱亮度像素权重低)。
  • LED/荧光偏绿 (仅调色温不够)
    → 一定要做 Tint 微调(§8),或在两套 CCM 间按白点插值。
  • 混合光 (窗外日光+室内钨丝)
    → 单一全局增益不可能完美;用分区估计(网格白点→导引滤波平滑)或"人像/前景加权"。
  • 被大面积单色误导 (草地/海天)
    → 用 Shades-of-Gray(p≈6)Gray-Edge 替代纯灰世界;或加入"人脸/纸张"检测做加权。
  • 去马赛克前后不一致
    → 确认 WB 在去马赛克之前做;若必须后做,务必在线性无伽马的 RGB 上进行。

11. "最小可用"Python 思路(示例骨架,中文注释)

仅示意流程;你可换成自己的读写与掩码实现。

python 复制代码
import rawpy, imageio.v2 as imageio
import numpy as np

# 1) 读取 RAW,并获取黑电平/白电平
with rawpy.imread('sample.dng') as raw:
    # 线性 Bayer 数据(去损坏像素插值前)
    bayer = raw.raw_image_visible.astype(np.float32)
    black = np.array(raw.black_level_per_channel, dtype=np.float32)  # [R, G1, B, G2] 取决于机型
    white = raw.white_level

    # 2) 黑电平校正(按像素位置映射到通道)
    H, W = raw.raw_colors_visible.shape
    cfa = raw.raw_colors_visible  # 0:R,1:G,2:B(rawpy 定义)
    bl_map = np.zeros_like(bayer, dtype=np.float32)
    for ch in (0,1,2):
        bl_map[cfa==ch] = black[ch if ch!=1 else 1]  # 简化:G 两路同一黑电平
    lin = np.clip(bayer - bl_map, 0, None)

    # 3) 构建掩码(剔除饱和与死黑)
    mask = (lin > np.percentile(lin, 1)) & (lin < np.percentile(lin, 99))

    # 4) 估计三通道统计量(灰世界:中位数)
    R = lin[cfa==0]; G = lin[cfa==1]; B = lin[cfa==2]
    r_med = np.median(R[mask[cfa==0]])
    g_med = np.median(G[mask[cfa==1]])
    b_med = np.median(B[mask[cfa==2]])

    # 5) 计算增益并归一化(g_G=1)
    gR, gG, gB = g_med/r_med, 1.0, g_med/b_med

    # 6) 应用增益到 Bayer(R/Gr/Gb/B)
    gain_map = np.zeros_like(lin, dtype=np.float32)
    gain_map[cfa==0] = gR
    gain_map[cfa==1] = gG
    gain_map[cfa==2] = gB
    lin_wb = np.clip(lin * gain_map, 0, white)

    # 7) 去马赛克与后级(保持线性,不使用自动亮度/自动 WB)
    rgb = raw.postprocess(
        use_camera_wb=False, no_auto_bright=True, output_bps=16,
        user_sat=1.0, gamma=(1,1), demosaic_algorithm=rawpy.DemosaicAlgorithm.AHD
    )

# 注意:上面的 postprocess 用的是原始 raw 数据;要把 lin_wb 喂给 demosaic 则需手写或换更底层流程。
# 初学者可用 use_camera_wb=True 先对比机内 WB ;接着把 gR,gG,gB 套在外部工具里验证观感。

小提示:实际工程里通常直接在 ISP 里对 Bayer 四路乘增益后再 demosaic;若用 rawpy 的高层接口,先用 use_camera_wb=True 验证参照,再过渡到自定义低层流程。


12. 两个练习(快速进步)

  1. ROI vs 灰世界对比:同一张含灰卡的 DNG,上一次用 ROI(§4),再用灰世界(§5),比较灰阶中性度与肤色观感,体会"被大面积单色误导"的差别。
  2. Tint 微调:在荧光/LED 下拍灰卡,做完 §4 后,尝试 §8 的方法 1(平衡 Gr/Gb)进行 1--2% 的微调,看看能否消除轻微绿偏。

最小可用 AWB = "去黑电平 → 稳健统计出三通道比例 → 归一化到 g G = 1 g_G=1 gG=1 → 在 Bayer 上乘增益 → 再去马赛克"。

有灰卡用 ROI;没灰卡用"灰世界/白点/折中",必要时加一点 Tint 微调与增益上限,就能得到稳定、可交付的初学者版本。


六、总结

1. 跨算法通用的工程细节(很重要)

  • 线性域:WB 必须在线性 RAW(去黑电平,未伽马)上做。
  • 掩码:剔除饱和(>99% 分位)、死黑(<1% 分位)、彩色强反射。
  • 蓝通道保护 :暖光下 g B g_B gB 巨大 → 可设上限或先降噪。
  • G/Gr/Gb:RGGB 传感器常对 R、Gr、Gb、B 分别乘增益(或先合并 G)。
  • LSC 顺序 :镜头像场/彩色阴影校正(Lens Shading)与 WB 交互,通常先做 LSC 再 WB更物理一致(实际依管线)。
  • 与 CCM 的关系:WB 之后再做 CCM;很多系统会按白点在"两套 CCM 之间插值"。
  • 评测指标:Angular Error(°)最常用;也看肤色/灰阶的可视主观分。
  • 数值稳定 :用中位数/分位数/Huber 替代均值更稳;可亮度加权。

2. 典型失败与应对

  • 大面积单色 (草地/海面/蓝天):灰世界被"骗"。
    → 用 ROI(灰卡/人脸/白物)或用 White-Patch/学习法。
  • LED/荧光灯 :光谱不连续,只调 CCT 不够,tint 必须调。
  • 混合光 (窗外日光 + 室内钨丝):单一增益无法同时校正
    → 分区 AWB(局部估计、融合),或拍摄时尽量统一光源。
  • 高光/金属反射 :别把彩色高光当"白"。
    → 用分位点(如 95%)代替最大值,排除饱和像素。
  • 蓝通道噪声放大:控制增益上限或先去噪。

3. 评测与调参

  • 常用指标:Angular Error(角误差)
    把估计光源与真值光源的三通道向量单位化,算夹角:
    θ = arccos ⁡ ⟨ L ^ ,   L ⟩ ∥ L ^ ∥   ∥ L ∥ \theta=\arccos\frac{\langle \hat{\mathbf{L}},\,\mathbf{L}\rangle}{\|\hat{\mathbf{L}}\|\,\|\mathbf{L}\|} θ=arccos∥L^∥∥L∥⟨L^,L⟩
    越小越好(单位:度)。
  • 评测道具:ColorChecker(有中性灰阶与记忆色),方便可视与定量评估。

4. 和颜色校正矩阵(CCM)的配合

  • WB 负责"抵消光源色偏",CCM 负责把"相机 RGB"映到标准色域(如 sRGB)。
  • 先 WB、后 CCM 是主流做法;若传感器响应与模型足够准,也可联合优化(高端相机/手机常联合学习)。

结~~~

相关推荐
m0_736919103 小时前
模板编译期图算法
开发语言·c++·算法
dyyx1113 小时前
基于C++的操作系统开发
开发语言·c++·算法
m0_736919103 小时前
C++安全编程指南
开发语言·c++·算法
蜡笔小马3 小时前
11.空间索引的艺术:Boost.Geometry R树实战解析
算法·r-tree
-Try hard-3 小时前
数据结构:链表常见的操作方法!!
数据结构·算法·链表·vim
2301_790300963 小时前
C++符号混淆技术
开发语言·c++·算法
我是咸鱼不闲呀4 小时前
力扣Hot100系列16(Java)——[堆]总结()
java·算法·leetcode
嵌入小生0074 小时前
单向链表的常用操作方法---嵌入式入门---Linux
linux·开发语言·数据结构·算法·链表·嵌入式
LabVIEW开发4 小时前
LabVIEW金属圆盘压缩特性仿真
算法·labview·labview知识·labview功能·labview程序
8K超高清4 小时前
回望2025,纷呈超清智能科技影像世界
网络·人工智能·科技·数码相机·智能硬件