1. AWB基础
任务目标
实现灰度世界白平衡算法,对一张偏色图像完成颜色校正,并通过灰度均值对比与直方图分布评估校正效果。本案例使用Python + OpenCV,输入为一张白炽灯下拍摄的偏黄图像,输出为校正后的图像及量化评估指标。
核心原理
灰度世界假设:场景中所有颜色的平均反射率近似为灰色(即RGB三通道均值趋于相等)。算法将图像三通道均值分别缩放至同一目标值(通常取三通道均值的平均值),从而消除光源色偏。
实现代码
import cv2
import numpy as np
def gray_world_awb(img):
"""灰度世界白平衡校正"""
# 分离通道并计算各通道均值
b, g, r = cv2.split(img)
b_mean, g_mean, r_mean = np.mean(b), np.mean(g), np.mean(r)
# 目标灰度值:三通道均值的平均
gray_target = (b_mean + g_mean + r_mean) / 3.0
# 计算各通道增益并应用
b_gain, g_gain, r_gain = gray_target / b_mean, gray_target / g_mean, gray_target / r_mean
b_balanced = np.clip(b * b_gain, 0, 255).astype(np.uint8)
g_balanced = np.clip(g * g_gain, 0, 255).astype(np.uint8)
r_balanced = np.clip(r * r_gain, 0, 255).astype(np.uint8)
return cv2.merge([b_balanced, g_balanced, r_balanced])
def evaluate(img, name):
"""计算三通道均值与标准差"""
b, g, r = cv2.split(img)
means = [np.mean(ch) for ch in (b, g, r)]
stds = [np.std(ch) for ch in (b, g, r)]
print(f"{name} 通道均值 B/G/R: {means[0]:.1f}, {means[1]:.1f}, {means[2]:.1f}")
print(f"{name} 通道标准差 B/G/R: {stds[0]:.1f}, {stds[1]:.1f}, {stds[2]:.1f}")
return means, stds
if __name__ == "__main__":
# 读取偏色图像(请将图片路径替换为实际路径)
img = cv2.imread("warm_cast.jpg")
if img is None:
print("图像读取失败,请检查路径")
exit(1)
# 执行白平衡校正
result = gray_world_awb(img)
# 保存结果
cv2.imwrite("awb_result.jpg", result)
# 评估校正前后效果
print("=== 校正前 ===")
means_before, _ = evaluate(img, "原图")
print("=== 校正后 ===")
means_after, _ = evaluate(result, "校正图")
# 判定标准:校正后三通道均值差应显著缩小
diff_before = max(means_before) - min(means_before)
diff_after = max(means_after) - min(means_after)
print(f"\n通道均值最大差:校正前 {diff_before:.1f} → 校正后 {diff_after:.1f}")
print("校正通过" if diff_after < diff_before * 0.3 else "校正效果不足,请检查输入图像是否严重偏色")
运行与验证
- 依赖安装:
pip install opencv-python numpy - 准备输入:将一张白炽灯下拍摄的偏黄照片命名为
warm_cast.jpg放在脚本同目录 - 执行:
python gray_world.py - 通过条件:
- 程序输出校正前后各通道均值;
- 校正后三通道均值最大差值应小于校正前的30%(例如校正前差值为60,校正后应小于18);
- 生成awb_result.jpg,目视检查白色物体(如白墙、白纸)不再偏黄,整体色温趋于中性。
预期输出示例(基于典型偏黄图像,实际值随输入变化):
校正前通道均值差约 55.2 → 校正后约 2.1,校正后白色区域RGB值接近(如 210, 208, 212),无明显色偏。
校正前通道均值差约 55.2 → 校正后约 2.1,校正后白色区域RGB值接近(如 210, 208, 212),无明显色偏。
常见问题
- 校正后偏红/偏蓝:图像中存在大面积单一纯色物体(如纯蓝天空)会破坏灰度世界假设,导致过校正。此时可改用更鲁棒的动态阈值算法(后续案例覆盖)。
- 图像过暗或过亮:灰度世界只做通道增益,不改变整体亮度。若原图曝光异常,需先做亮度归一化。