1. 基于灰度世界假设的AWB校正

基于灰度世界假设的AWB校正 学习卡片

任务目标

实现经典灰度世界白平衡算法:假设场景中RGB三通道的平均值趋于同一灰度值,据此估计光源颜色并校正偏色图像。输入一张偏色图像,输出校正后的图像及三通道增益系数,用于验证算法有效性。

环境依赖

Python 3.8+,需安装 numpy 与 opencv-python(仅用于图像读写,核心算法不依赖OpenCV)。

核心实现

import numpy as np

def gray_world_awb(img):
    """
    灰度世界白平衡校正
    img: HxWx3 uint8 BGR图像 (OpenCV格式)
    返回: 校正后图像(uint8 BGR), 增益系数(gains)
    """
    # 转换为float避免溢出
    img_f = img.astype(np.float32)

    # 计算各通道均值
    mean_b = np.mean(img_f[:, :, 0])
    mean_g = np.mean(img_f[:, :, 1])
    mean_r = np.mean(img_f[:, :, 2])

    # 灰度世界假设:三通道均值应相等,取整体均值作为目标灰度
    gray_target = (mean_b + mean_g + mean_r) / 3.0

    # 计算增益并防止除零
    eps = 1e-6
    gain_b = gray_target / (mean_b + eps)
    gain_g = gray_target / (mean_g + eps)
    gain_r = gray_target / (mean_r + eps)

    # 应用增益并裁剪到有效范围
    corrected = np.zeros_like(img_f)
    corrected[:, :, 0] = np.clip(img_f[:, :, 0] * gain_b, 0, 255)
    corrected[:, :, 1] = np.clip(img_f[:, :, 1] * gain_g, 0, 255)
    corrected[:, :, 2] = np.clip(img_f[:, :, 2] * gain_r, 0, 255)

    return corrected.astype(np.uint8), (gain_b, gain_g, gain_r)

# 最小调用入口
if __name__ == "__main__":
    import cv2

    # 读取偏色图像(请替换为实际路径)
    img = cv2.imread("input.jpg")
    if img is None:
        raise FileNotFoundError("无法读取图像,请检查路径")

    corrected_img, gains = gray_world_awb(img)
    cv2.imwrite("output.jpg", corrected_img)

    # 打印增益系数
    print(f"Gain B: {gains[0]:.3f}, Gain G: {gains[1]:.3f}, Gain R: {gains[2]:.3f}")

    # 验证:校正后三通道均值应接近
    corrected_f = corrected_img.astype(np.float32)
    print(f"校正后均值 B: {np.mean(corrected_f[:,:,0]):.2f}, "
          f"G: {np.mean(corrected_f[:,:,1]):.2f}, "
          f"R: {np.mean(corrected_f[:,:,2]):.2f}")

运行与验证

  1. 将上述代码保存为 awb_gray_world.py,准备一张明显偏色的测试图像(如白炽灯下拍摄的照片)命名为 input.jpg 放在同目录。
  2. 运行 python awb_gray_world.py。
  3. 通过条件:程序无报错退出;生成的 output.jpg 中原本偏色区域(如偏黄或偏蓝的白色物体)恢复为中性色;控制台打印的校正后三通道均值基本接近(差值小于5视为有效)。

效果评估要点

灰度世界算法对色彩丰富的场景效果良好,但对大面积单色场景(如蓝天、绿草)会失效,因为灰度假设不成立。若测试图像校正后出现互补色偏(如原偏黄变为偏蓝),说明场景不满足灰度世界假设,属正常现象,可换用色彩丰富的图像验证。

输入偏色图 偏黄/偏蓝 白色区域不白 通道均值不相等 R≠G≠B 灰度世界算法 计算各通道均值 mean_R, mean_G, mean_B 目标灰度 = 三均值平均 gain = 目标/通道均值 像素值 × 对应增益 裁剪到[0,255] 校正输出 白色恢复 为中性色 三通道均值 趋于相等

上图展示了灰度世界算法的完整处理链路:从偏色输入中统计通道均值,计算各通道增益,最终使输出图像的三通道均值趋于一致,从而消除光源颜色带来的色偏。