18、Camera特性与参数:AE/AWB/AF算法、3A协调机制、Manual控制、ISO/ExposureTime/WhiteBalance
各位同学,今天我们来聊聊相机系统里最核心、也最让人头疼的部分——3A算法。说白了,AE(自动曝光)、AWB(自动白平衡)、AF(自动对焦)这三个家伙,决定了你拍出来的照片是“大片”还是“废片”。
我在做Camera HAL层开发那几年,几乎天天跟它们打交道。有一次客户反馈说夜景模式下照片偏绿,我排查了整整两天,最后发现是AWB在低照度下收敛错了方向。嗯,这种坑,踩过一次就忘不了。
18.1 自动曝光(AE)——让亮度刚刚好
AE的目标很简单:让画面既不过曝也不欠曝。但实现起来,远比你想象的要复杂。
它的核心逻辑是:通过调整曝光时间、模拟增益(ISO)和数字增益,把画面的平均亮度拉到一个目标值附近。这个目标值通常用“目标亮度”或“Target Luma”来表示,一般在100-120之间(8位数据范围0-255)。
核心公式:
当前亮度 = f(曝光时间, ISO, 光圈)
误差 = 目标亮度 - 当前亮度
调整量 = PID(误差)
我习惯把AE算法分成三个阶段:
- 粗调阶段:场景切换时,快速调整曝光时间。比如从室内走到室外,曝光时间会从1/30秒跳到1/1000秒。
- 细调阶段:亮度接近目标后,用ISO做微调。这一步要稳,不能来回跳。
- 锁定阶段:画面稳定后,AE进入“锁定”状态,只做很小的修正。
这里有个坑——曝光时间不能随便调。你想想看,如果曝光时间低于1/30秒,手持拍摄就容易糊。所以AE算法必须考虑“安全快门”的限制。我曾经在某个项目里,因为没处理好这个边界,导致用户在暗光下拍出来的照片全是糊的……后来加了一个“最小曝光时间”的约束才解决。
18.2 自动白平衡(AWB)——还原真实色彩
AWB要解决的问题是:不同光源下,白色物体看起来应该是白色的。听起来简单,做起来难。
它的基本原理是:统计画面中“灰色区域”的RGB比例,然后推算出当前光源的色温,最后做颜色校正。
常见的AWB算法流程:
- 把图像分成N×N的块,计算每块的R/G和B/G比值
- 剔除过亮、过暗、过饱和的块(这些块不包含灰色信息)
- 在色温曲线上找到最匹配的点
- 计算增益矩阵,应用到整幅图像
避坑指南:我曾经在调试AWB时发现,如果场景里全是绿色植物(比如森林),AWB会误判为“偏绿”,然后拼命加红色补偿,结果整个画面变成了紫色。解决办法是:加入场景识别,当检测到“绿色占比过高”时,降低AWB的响应速度。
色温曲线长什么样?我画个图给你看:
18.3 自动对焦(AF)——让主体清晰
AF算法分两大类:反差对焦(CDAF)和相位对焦(PDAF)。现在主流方案是两者结合——先用PDAF快速粗调,再用CDAF精调。
我简单说说它们的区别:
| 类型 | 原理 | 速度 | 精度 | 适用场景 |
|---|---|---|---|---|
| CDAF | 找画面中对比度最大的位置 | 慢(需要来回扫) | 高 | 静态场景、视频 |
| PDAF | 通过相位差计算偏移量 | 快(一次计算) | 中等 | 运动场景、连拍 |
| 混合AF | PDAF粗调 + CDAF精调 | 快且准 | 高 | 通用 |
AF算法里有个关键参数叫对焦窗口。不是整个画面都参与对焦,而是只取中间一块区域。窗口大小怎么定?太小了容易跑焦,太大了又会被背景干扰。我一般建议取画面面积的10%-20%。
注意:AF算法最怕“反复拉风箱”。就是镜头来回移动,始终找不到合焦点。这种情况通常发生在低对比度场景(比如白墙)或极暗环境下。解决办法是:设置超时时间,超时后锁定当前位置,或者切到手动对焦模式。
18.4 3A协调机制——三个和尚怎么喝水?
AE、AWB、AF三个算法是独立运行的,但它们共享同一个硬件资源(sensor、ISP),而且互相影响。比如:
- AE调整曝光时间 → 画面亮度变化 → AWB需要重新计算
- AF移动镜头 → 画面模糊 → AE统计值不准
- AWB改变颜色增益 → 影响AE的亮度统计
所以必须有一个协调机制。我见过两种主流方案:
方案一:串行执行
每一帧只运行一个算法,轮流来。比如第1帧跑AE,第2帧跑AWB,第3帧跑AF。优点是实现简单,缺点是响应慢。
方案二:并行+优先级
三个算法同时跑,但设定优先级。通常AE优先级最高,因为曝光不准会直接影响AWB和AF的输入。AWB次之,AF最低。我比较推荐这个方案,虽然实现复杂,但用户体验好。
下面这张图展示了3A协调的典型流程:
18.5 Manual控制——把方向盘交给用户
说完自动,咱们聊聊手动。Android Camera2 API提供了完整的手动控制能力,核心参数就三个:ISO、曝光时间、白平衡。
ISO(感光度):
ISO本质上是模拟增益。ISO越高,信号放大倍数越大,但噪声也越明显。我一般建议:
- 白天:ISO 100-200
- 室内:ISO 400-800
- 夜景:ISO 800-3200(再高就全是噪点了)
曝光时间(Exposure Time):
单位是纳秒(ns),但通常用微秒或毫秒来理解。1/30秒 ≈ 33ms,1/100秒 = 10ms。曝光时间越长,进光量越大,但手抖风险也越高。
白平衡(White Balance):
手动白平衡就是直接指定色温值。常见值:
- 日光:5500K
- 阴天:6500K
- 荧光灯:4000K
- 白炽灯:3000K
代码示例(Camera2 API手动设置):
// 手动设置曝光参数
CaptureRequest.Builder requestBuilder =
cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_MANUAL);
// 关闭自动曝光
requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
CaptureRequest.CONTROL_AE_MODE_OFF);
// 设置曝光时间:1/60秒
requestBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME,
16666666L); // 纳秒单位
// 设置ISO:400
requestBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, 400);
// 关闭自动白平衡
requestBuilder.set(CaptureRequest.CONTROL_AWB_MODE,
CaptureRequest.CONTROL_AWB_MODE_OFF);
// 设置白平衡色温:5500K
requestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE,
CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
// 实际需要设置3x3颜色变换矩阵,这里简化
我的经验:手动模式下,一定要给用户提供“曝光补偿”的选项。因为即使你手动设置了ISO和曝光时间,不同场景下的亮度还是会有偏差。曝光补偿本质上是在目标亮度上加减一个偏移量,简单但非常实用。
18.6 总结一下
3A算法是相机系统的灵魂。AE管亮度,AWB管颜色,AF管清晰度。它们之间需要良好的协调机制,否则就会互相打架。
手动控制则给了专业用户更大的创作空间。但说实话,大部分用户还是喜欢“傻瓜式”的自动模式。所以作为工程师,我们的目标是:让自动模式足够聪明,让手动模式足够强大。
嗯,这一章的内容就到这里。记住我强调的几个坑:AE的安全快门、AWB的绿色场景误判、AF的低对比度拉风箱。这些在实际项目中都是高频问题。