2. 完美反射白平衡算法

任务目标

实现完美反射(Perfect Reflector)白平衡算法:假设图像中最亮的像素区域能够完全反射光源颜色,据此估计场景光源色温,并对整幅图像进行颜色校正,使白色物体在不同光源下呈现为白色。

算法原理

完美反射算法核心步骤:

  1. 统计图像各通道(R/G/B)的亮度分布,确定每个通道的“最亮参考值”(通常取该通道前1%像素的平均值或最大值);
  2. 以三个通道的最亮参考值构成光源颜色估计向量;
  3. 将每个像素的通道值除以对应光源估计值(归一化),使最亮区域映射为白色,完成校正。

完整实现(Python + OpenCV)

import cv2
import numpy as np

def perfect_reflector_awb(img, percentile=99):
    """
    完美反射白平衡
    :param img: BGR图像,uint8类型
    :param percentile: 取前percentile%像素作为最亮参考
    :return: 校正后的BGR图像
    """
    # 分离通道
    b, g, r = cv2.split(img.astype(np.float32))

    # 计算各通道的亮度阈值(取前percentile%像素)
    def channel_gain(channel):
        # 计算通道直方图
        hist = cv2.calcHist([channel], [0], None, [256], [0, 256]).flatten()
        total = img.shape[0] * img.shape[1]
        cumsum = np.cumsum(hist)
        # 找到累计像素数达到 total * percentile/100 的灰度值
        threshold = np.searchsorted(cumsum, total * percentile / 100.0)
        # 取该阈值以上像素的平均值作为光源估计
        mask = channel >= threshold
        if np.sum(mask) == 0:
            return 255.0
        return np.mean(channel[mask])

    b_ref = channel_gain(b)
    g_ref = channel_gain(g)
    r_ref = channel_gain(r)

    # 计算增益(以G通道为基准,防止整体亮度偏移)
    max_ref = max(b_ref, g_ref, r_ref)
    b_gain = max_ref / b_ref if b_ref > 0 else 1.0
    g_gain = max_ref / g_ref if g_ref > 0 else 1.0
    r_gain = max_ref / r_ref if r_ref > 0 else 1.0

    # 应用增益并裁剪到有效范围
    b_corr = np.clip(b * b_gain, 0, 255)
    g_corr = np.clip(g * g_gain, 0, 255)
    r_corr = np.clip(r * r_gain, 0, 255)

    result = cv2.merge([b_corr, g_corr, r_corr]).astype(np.uint8)
    return result

# 使用示例
if __name__ == "__main__":
    # 读取图像(请替换为实际路径)
    img = cv2.imread("input.jpg")
    if img is None:
        print("图像读取失败,请检查路径")
        exit(1)

    corrected = perfect_reflector_awb(img)

    # 保存结果
    cv2.imwrite("output_perfect_reflector.jpg", corrected)
    print("校正完成,结果已保存至 output_perfect_reflector.jpg")

运行与验证

环境依赖:Python 3.6+,OpenCV(pip install opencv-python numpy)

运行方式:

python perfect_reflector_awb.py

验证方法:

  1. 准备一张在偏色光源(如白炽灯/荧光灯)下拍摄的包含白色物体的图像;
  2. 运行脚本后,观察输出图像中白色物体是否恢复为白色,整体色偏是否消除;
  3. 定量验证:计算校正前后图像中白色区域的平均RGB值,校正后三通道比值应接近1:1:1(例如R/G≈1.0,B/G≈1.0)。

预期输出示例:若输入图像中白色区域像素值约为(200, 150, 100)(BGR),校正后该区域应接近(200, 200, 200)左右,具体数值取决于光源估计的准确性。

常见问题

  • 图像过曝:若图像中存在大面积过曝区域(像素值=255),算法会将过曝区域误判为光源,导致校正失效。建议先检查直方图,避免使用过曝图像。
  • 无白色物体:若场景中不存在接近白色的高亮区域,算法估计的光源颜色可能不准确。此时可考虑改用灰度世界算法或结合其他方法。
  • 参数调整:percentile参数控制“最亮”的定义,默认99%表示取前1%最亮像素。若图像噪声较大,可适当降低该值(如95)以增强鲁棒性。