2. AWB基础
任务目标
实现完美反射(Perfect Reflector)白平衡算法。该算法假设图像中最亮的像素区域可作为场景中白色或灰色参考,通过统计这些高亮像素的RGB均值来估计光源颜色,进而对整幅图像进行通道增益校正,消除色偏。
算法原理
完美反射算法的核心步骤:
- 统计图像RGB三通道的直方图,确定各通道的亮度阈值(通常取累计占比前1%的像素作为“最亮点”集合);
- 计算这些高亮像素在各通道的均值,作为光源颜色估计值
(R_max, G_max, B_max); - 以最大通道值为基准,计算各通道增益
gain = max_val / channel_max; - 将增益逐像素乘回原图,并做饱和截断。
完整实现
本案例使用Python + OpenCV实现,输入任意彩色图像,输出校正后的图像及增益参数。代码自包含,无需额外数据文件。
import cv2
import numpy as np
def perfect_reflector_awb(img, percentile=99.0):
"""
完美反射白平衡
Args:
img: BGR图像, uint8, 0-255
percentile: 高亮像素截取百分位 (默认99, 即取最亮1%像素)
Returns:
out: 校正后BGR图像, uint8
gains: (gain_r, gain_g, gain_b) 各通道增益
"""
# 分离通道
b, g, r = cv2.split(img.astype(np.float32))
# 计算各通道高亮阈值 (取百分位对应的像素值)
thr_b = np.percentile(b, percentile)
thr_g = np.percentile(g, percentile)
thr_r = np.percentile(r, percentile)
# 生成掩码:三通道同时高于各自阈值的像素视为"最亮点"
mask = (b >= thr_b) & (g >= thr_g) & (r >= thr_r)
# 若掩码为空(极端情况), 退化为全图最大像素
if not np.any(mask):
mask = (b == b.max()) & (g == g.max()) & (r == r.max())
# 高亮像素各通道均值作为光源估计
r_max = r[mask].mean()
g_max = g[mask].mean()
b_max = b[mask].mean()
# 以最大通道值为基准计算增益
max_val = max(r_max, g_max, b_max)
gain_r = max_val / r_max if r_max > 0 else 1.0
gain_g = max_val / g_max if g_max > 0 else 1.0
gain_b = max_val / b_max if b_max > 0 else 1.0
# 应用增益并截断到[0,255]
out_r = np.clip(r * gain_r, 0, 255).astype(np.uint8)
out_g = np.clip(g * gain_g, 0, 255).astype(np.uint8)
out_b = np.clip(b * gain_b, 0, 255).astype(np.uint8)
out = cv2.merge([out_b, out_g, out_r])
return out, (gain_r, gain_g, gain_b)
if __name__ == "__main__":
# 读取图像 (请替换为实际路径)
img = cv2.imread("input.jpg")
if img is None:
raise FileNotFoundError("未找到输入图像 input.jpg")
corrected, gains = perfect_reflector_awb(img)
# 保存结果
cv2.imwrite("output_awb.jpg", corrected)
print(f"增益 R={gains[0]:.3f}, G={gains[1]:.3f}, B={gains[2]:.3f}")
print("校正图像已保存至 output_awb.jpg")
运行与验证
环境依赖:Python 3.7+,安装 opencv-python 和 numpy。
pip install opencv-python numpy
python awb_perfect_reflector.py
验证方法:
- 准备一张有明显色偏的图像(如室内白炽灯下拍摄、偏黄或偏蓝),命名为
input.jpg放在脚本同目录; - 运行脚本,观察终端输出的三通道增益值——若图像偏黄(R通道过强),则
gain_r应小于1,gain_b应大于1,反之亦然; - 打开
output_awb.jpg,检查白色物体(如白墙、白纸)是否恢复为中性白,整体色偏是否明显消除; - 若图像中不存在白色或高亮物体,算法效果会受限,这是完美反射算法的固有假设,属正常现象。
预期输出示例(仅作逻辑演示,非实测值):对于一张偏黄的图像,可能输出 增益 R=0.82, G=0.95, B=1.18,校正后高亮区域RGB趋于接近。
常见问题
- 校正后过曝:若图像本身过亮,增益放大后高光细节丢失。可适当降低
percentile(如98.0)使参考像素更少、增益更温和。 - 无白色物体时效果差:算法依赖“最亮像素为白色”的假设,若场景中最亮区域是彩色物体(如红色灯光),校正会产生错误色偏。此时需改用灰度世界或其他算法。