3. AE算法目标:理解18%灰板与目标亮度

做AE控制这么多年,我越来越觉得一个道理很朴素——曝光的目标不是让画面“看起来亮”,而是让画面“还原准确”。说白了,就是让场景中18%反射率的物体,在图像里呈现出中灰亮度。这个基准,就是整个AE算法的锚点。

3.1 18%灰板到底是个啥?

你可能在摄影器材店见过那种灰色卡片,一面灰一面白。那个灰色面,反射率就是18%。为什么是18%?不是20%也不是15%?

嗯,这其实跟人眼对亮度的感知曲线有关。人眼对暗部更敏感,对亮部不那么敏感。18%这个值,恰好落在人眼感知的中间区域。相机测光系统都是以这个为基准设计的——你测哪里,系统就默认那里应该是18%灰。

核心概念:AE算法的本质,就是通过调整曝光参数,让场景中18%反射率的区域,在输出图像中映射到128(8bit)或512(10bit)附近的中灰值。

我在项目中遇到过一个问题:一个用户拍雪景,结果画面总是灰蒙蒙的。为什么?因为相机测光系统“以为”雪是18%灰,拼命压低曝光,雪就变成了灰色。这就是典型的测光欺骗。所以后来我们在AE里加了场景分类,遇到高反射场景就自动补偿。

3.2 目标亮度怎么定?

目标亮度不是拍脑袋定的。它取决于三件事:

  • 传感器特性:不同sensor的线性区、饱和点不一样
  • 输出位深:8bit还是10bit,目标值不同
  • 场景意图:人脸、风景、文档,各有各的偏好

我一般这样设目标:

场景类型 目标亮度(8bit) 目标亮度(10bit) 说明
通用场景 100~120 400~480 以18%灰为基准
人脸优先 140~160 560~640 人脸偏亮一点更讨喜
夜景/低照 60~80 240~320 保留暗部细节
文档扫描 180~200 720~800 文字清晰优先

我的习惯:在调试阶段,我会先固定目标亮度为120(8bit),等AE收敛稳定了,再根据场景微调。不要一上来就搞复杂策略,容易翻车。

3.3 AE的统计信息——亮度直方图

AE算法怎么知道当前画面亮不亮?靠的就是亮度直方图。说白了,就是把画面里每个像素的亮度值做个统计,看看分布情况。

直方图的横轴是亮度(0~255),纵轴是像素数量。我每次调试AE,第一件事就是拉出直方图看。它能告诉你很多信息:

  • 左偏:画面偏暗,欠曝
  • 右偏:画面偏亮,过曝
  • 两边撞墙:有细节丢失(暗部裁切或高光溢出)
  • 中间集中:对比度低,画面发灰

在ISP里,直方图统计一般分两步:

  1. 分bin统计:把0~255分成256个bin,每个bin统计像素个数
  2. 加权计算:不同区域可以给不同权重(比如人脸区域权重更高)

我曾经踩过一个坑:直方图统计的bin数太少,导致AE在低照场景下抖动。后来把bin从64改成256,问题就解决了。你想想看,bin太少,亮度分辨率不够,AE就像瞎子摸象,当然稳不住。

3.4 从直方图到曝光调整

有了直方图,AE算法就能算出一个当前平均亮度,然后跟目标亮度比较。差值就是曝光误差。

伪代码大概是这样的:

// 简化版AE核心逻辑
uint8_t target_luma = 120;  // 目标亮度
uint8_t current_luma = get_average_luma(histogram);  // 从直方图算当前亮度

int error = target_luma - current_luma;  // 曝光误差

if (abs(error) < threshold) {
    // 曝光OK,不动
    return;
}

// 根据误差调整曝光参数
if (error > 0) {
    // 画面偏暗,增加曝光
    increase_exposure(error);
} else {
    // 画面偏亮,减少曝光
    decrease_exposure(-error);
}

实际工程里,不会直接用这个error一步到位。我会加一个低通滤波,防止AE来回跳。比如:

// 平滑处理,防止抖动
static int filtered_error = 0;
filtered_error = filtered_error * 0.7 + error * 0.3;

注意:滤波系数不能太大,否则AE反应太慢;也不能太小,否则画面会闪烁。我一般从0.7开始调,根据实际效果微调。

3.5 本章知识体系

下面这张图,把AE算法从目标到统计再到调整的链路画清楚了:

AE算法核心流程 AE算法核心流程 18%灰板基准 目标亮度设定 亮度直方图统计 计算当前平均亮度 曝光误差计算 调整曝光参数 输出图像 反馈循环 关键点 • 18%灰是锚点 • 直方图是眼睛 • 误差驱动调整

从图上你能看到,整个AE是一个闭环反馈系统。18%灰板是理论基准,目标亮度是工程设定,直方图是实时反馈,误差计算是决策依据,参数调整是执行动作。每一环都缺一不可。

3.6 避坑指南

最后分享几个我踩过的坑:

  • 直方图bin数别太少:64bin以下,AE在低照场景容易抖动。建议至少128bin,256bin更稳。
  • 目标亮度别死板:不同场景用同一个目标值,效果一定差。我习惯在AE模块里预置3~5组目标值,根据场景切换。
  • 滤波系数要调:0.7是个好起点,但遇到快速变化的场景(比如从室内走到室外),系数要动态调整。
  • 别忘了权重:画面中心区域、人脸区域,权重应该更高。否则背景亮了,人脸黑了,用户肯定骂娘。

一句话总结:AE算法的核心,就是用直方图这把尺子,量出画面亮度,然后把它拉到18%灰这个锚点附近。理解了这一点,你就抓住了AE的魂。