3. AWB进阶
任务目标
在自动白平衡(AWB)处理中,经典灰度世界法假设场景平均色为灰色,但遇到大面积单色物体(如蓝天、绿草)时会产生严重色偏。本案例实现基于YUV色彩空间的动态阈值白平衡算法,通过自适应统计YUV空间中像素分布,动态筛选参考白点,从而在复杂场景下获得比固定阈值法更稳健的白平衡校正效果。
算法原理
动态阈值法核心思想:将RGB图像转换到YUV空间,利用U、V色度分量的统计特性动态确定白点判定阈值,而非使用固定常数。算法先计算U、V分量的均值与偏差,再以均值为中心、以偏差的加权值为半径划定动态范围,仅将落入该范围且亮度足够的像素视为参考白点,最后用这些白点的平均RGB值校正整幅图像。
核心代码
import numpy as np
import cv2
def dynamic_threshold_awb(img):
"""
基于YUV空间的动态阈值白平衡
img: BGR图像, uint8, 0-255
返回: 校正后的BGR图像
"""
# 转换到YUV
img_yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV).astype(np.float32)
Y, U, V = cv2.split(img_yuv)
# 动态阈值参数
T_Y = 0.85 * 255 # 亮度下限(排除过暗像素)
T_U = 0.25 * 255 # 色度偏差缩放系数
T_V = 0.25 * 255
# 计算U、V的均值与平均偏差
mean_U = np.mean(U)
mean_V = np.mean(V)
mad_U = np.mean(np.abs(U - mean_U))
mad_V = np.mean(np.abs(V - mean_V))
# 动态判定阈值(以均值为中心,偏差加权为半径)
lower_U = mean_U - T_U * mad_U
upper_U = mean_U + T_U * mad_U
lower_V = mean_V - T_V * mad_V
upper_V = mean_V + T_V * mad_V
# 构建白点掩码:亮度足够 + 色度在动态范围内
mask = (Y > T_Y) & (U > lower_U) & (U < upper_U) & \
(V > lower_V) & (V < upper_V)
# 若白点过少,回退到全图均值(防止除零)
if np.sum(mask) < 10:
mask = np.ones_like(mask, dtype=bool)
# 提取白点对应的BGR像素
bgr_white = img[mask]
mean_b = np.mean(bgr_white[:, 0])
mean_g = np.mean(bgr_white[:, 1])
mean_r = np.mean(bgr_white[:, 2])
# 以G通道为基准计算增益并校正
gain_b = mean_g / (mean_b + 1e-6)
gain_r = mean_g / (mean_r + 1e-6)
result = img.astype(np.float32)
result[:, :, 0] *= gain_b
result[:, :, 2] *= gain_r
# 饱和截断
result = np.clip(result, 0, 255).astype(np.uint8)
return result
# 最小调用示例
if __name__ == "__main__":
# 读取图像(请替换为实际路径)
img = cv2.imread("test.jpg")
if img is None:
print("请提供有效的图像路径")
else:
corrected = dynamic_threshold_awb(img)
# 保存结果
cv2.imwrite("awb_result.jpg", corrected)
print("处理完成,结果已保存为 awb_result.jpg")
运行与验证
环境依赖:Python 3.7+,NumPy,OpenCV(pip install numpy opencv-python)。
运行方式:将代码保存为 dynamic_awb.py,与测试图像置于同一目录,执行 python dynamic_awb.py。
验证方法:
- 准备两张测试图:一张正常光照下的标准色卡图,一张大面积蓝色天空或绿色草地的场景图。
- 运行后观察输出
awb_result.jpg:色卡图中灰色块应呈中性色(R≈G≈B);蓝天场景中天空应恢复为自然的蓝色,地面/建筑等原本偏色的区域色偏应明显减轻。 - 定量验证(可选):在图像中选取已知为白色的区域(如白纸),比较校正前后该区域R、G、B均值之差。校正后三者差值应小于校正前,且最大通道差通常不超过15(0-255范围)。
判定通过条件:程序无报错运行完成;输出图像无过曝或欠曝的异常色块;主观视觉上白平衡明显改善,且大面积单色场景未出现灰度世界法常见的整体偏色现象。
关键说明:动态阈值中的缩放系数 T_U、T_V 取0.25为经验值,实际场景中可在0.1~0.5间调整。亮度下限 T_Y 取0.85×255,用于排除暗部噪声干扰。当检测到的白点像素过少(<10)时,算法自动回退到全图均值计算增益,避免极端场景下的除零或异常放大。