3. HDR多帧捕获原理:曝光包围与帧序列设计
HDR(高动态范围)成像的核心在于通过多帧捕获扩展传感器的动态范围。本章深入剖析曝光包围(Exposure Bracketing)与帧序列(Frame Sequence)的设计原理,这是Android相机框架实现HDR模式的底层基础。
3.1 曝光包围(Exposure Bracketing)
曝光包围是指相机以不同的曝光参数(快门速度、ISO、增益)连续拍摄多帧图像,从而覆盖从暗部到亮部的完整亮度范围。每一帧捕获场景中不同亮度区间的细节,最终通过融合算法合成一张高动态范围图像。
3.1.1 曝光包围的核心参数
| 参数 | 说明 | 典型值 |
|---|---|---|
| 包围步长(EV Step) | 相邻帧之间的曝光量差值,以EV(曝光值)为单位 | 1.0 EV、2.0 EV |
| 包围帧数 | 一次HDR捕获中拍摄的总帧数 | 3帧、5帧、7帧 |
| 基准帧(Reference Frame) | 以场景测光结果确定的中间曝光帧 | 0 EV |
| 欠曝帧(Underexposed) | 低于基准曝光,保留高光细节 | -1 EV、-2 EV |
| 过曝帧(Overexposed) | 高于基准曝光,保留暗部细节 | +1 EV、+2 EV |
设计要点:步长过小(如0.5 EV)会导致帧间亮度重叠过多,融合增益有限;步长过大(如3.0 EV)则可能产生亮度断层,融合后出现伪影。Android Camera2框架推荐步长范围为1.0~2.0 EV。
3.1.2 对称包围与非对称包围
- 对称包围:欠曝帧与过曝帧的EV绝对值相等,如[-2, 0, +2]。适用于光照均匀的场景。
- 非对称包围:根据场景动态范围分布调整欠曝/过曝的步长,如[-3, 0, +1]。适用于高光区域远多于暗部或反之的场景。
实战建议:在移动设备上,由于传感器噪声和运动模糊的限制,3帧对称包围(-2 EV, 0 EV, +2 EV)是最常用的配置,兼顾了动态范围扩展与计算开销。
3.2 帧序列(Frame Sequence)设计
帧序列定义了多帧捕获的时序、顺序和同步策略。合理的帧序列设计能够最小化帧间运动、减少鬼影(Ghosting)并保证融合质量。
3.2.1 帧序列的三种典型模式
| 模式 | 描述 | 适用场景 |
|---|---|---|
| 顺序捕获(Sequential) | 按曝光顺序逐帧拍摄,帧间存在时间间隔 | 静态场景、三脚架拍摄 |
| 交错捕获(Interleaved) | 在预览流中插入HDR帧,与预览帧交替输出 | 实时取景、零快门延迟 |
| 突发捕获(Burst) | 以最高帧率连续拍摄多帧,帧间间隔最小 | 手持拍摄、运动场景 |
注意:顺序捕获模式下,帧间时间差可达数十毫秒,容易因手抖或物体运动导致帧间错位。Android Camera2框架通过
CAPTURE_INTENT和REQUEST_QUEUE机制控制帧序列的时序,开发者需合理设置TEMPLATE_STILL_CAPTURE与AE_MODE。
3.2.2 帧序列的曝光顺序策略
曝光顺序直接影响融合质量。常见的顺序策略包括:
- 低→中→高(L→M→H):先拍欠曝帧,再拍基准帧,最后拍过曝帧。优点是传感器从低曝光开始,避免高曝光后的残留电荷影响后续帧。
- 高→中→低(H→M→L):先拍过曝帧,再拍基准帧,最后拍欠曝帧。适用于暗部细节优先的场景。
- 中→低→高(M→L→H):以基准帧为起点,向两侧扩展。适合运动场景,因为基准帧的曝光时间最接近用户预期。
推荐策略:在Android平台上,L→M→H顺序配合
CONTROL_AE_MODE_ON自动曝光锁定,能够获得最佳的帧间一致性。基准帧通常作为融合的参考帧(Reference Frame),用于对齐和权重计算。
3.3 曝光包围与帧序列的协同设计
曝光包围决定了“拍什么”,帧序列决定了“怎么拍”。两者协同设计才能实现高效的多帧捕获。
3.3.1 协同设计流程
- 场景分析:通过预览帧的直方图分析场景动态范围,确定包围步长和帧数。
- 帧序列规划:根据场景运动程度选择突发或顺序模式,并确定曝光顺序。
- 参数下发:通过
CaptureRequest.Builder设置每帧的SENSOR_EXPOSURE_TIME、SENSOR_SENSITIVITY和CONTROL_AE_MODE。 - 帧同步:利用
CaptureCallback监听每帧的完成状态,确保所有帧在融合前全部就绪。 - 元数据记录:每帧携带曝光参数、时间戳、传感器增益等元数据,供融合算法使用。
3.3.2 帧序列设计中的关键约束
| 约束项 | 说明 | 影响 |
|---|---|---|
| 帧间隔(Frame Interval) | 相邻帧之间的最小时间差,由传感器帧率决定 | 帧间隔越小,运动伪影越少 |
| 曝光时间总和 | 所有帧的曝光时间之和不能超过用户可接受的延迟 | 通常限制在200ms以内 |
| 传感器读出时间 | 每帧曝光结束后传感器读出数据所需时间 | 影响帧序列的总耗时 |
| ISP管线延迟 | 图像信号处理(ISP)处理每帧的时间 | 影响帧序列的吞吐量 |
3.4 曝光包围与帧序列的SVG架构图
下图展示了3帧对称曝光包围与突发捕获帧序列的协同工作流程:
3.5 帧序列设计中的运动补偿策略
手持拍摄时,帧间运动不可避免。帧序列设计需要为后续的运动补偿(Motion Compensation)提供支持:
- 时间戳对齐:每帧记录硬件时间戳(
SensorTimestamp),用于运动估计算法计算帧间位移。 - 参考帧选择:通常选择基准帧(0 EV)作为对齐参考,因为其信噪比最高。
- 帧间重叠区域:设计帧序列时预留10%~20%的视场重叠,便于特征匹配和配准。
工程实践:在Android Camera2框架中,通过
CaptureRequest.CONTROL_ENABLE_ZSL启用零快门延迟(ZSL)模式时,帧序列会自动插入到预览流中。此时需要特别注意CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION的逐帧设置,避免预览帧与HDR帧的曝光冲突。
3.6 曝光包围与帧序列的代码示例
以下代码展示了如何使用Android Camera2 API配置3帧曝光包围的帧序列:
// 构建3帧曝光包围的CaptureRequest序列
List<CaptureRequest> hdrRequestList = new ArrayList<>();
// 帧1:欠曝帧 (-2 EV)
CaptureRequest.Builder builder1 = cameraDevice.createCaptureRequest(
CameraDevice.TEMPLATE_STILL_CAPTURE);
builder1.set(CaptureRequest.CONTROL_AE_MODE,
CaptureRequest.CONTROL_AE_MODE_OFF);
builder1.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 5_000_000L); // 5ms
builder1.set(CaptureRequest.SENSOR_SENSITIVITY, 100);
builder1.addTarget(surface);
hdrRequestList.add(builder1.build());
// 帧2:基准帧 (0 EV)
CaptureRequest.Builder builder2 = cameraDevice.createCaptureRequest(
CameraDevice.TEMPLATE_STILL_CAPTURE);
builder2.set(CaptureRequest.CONTROL_AE_MODE,
CaptureRequest.CONTROL_AE_MODE_OFF);
builder2.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 20_000_000L); // 20ms
builder2.set(CaptureRequest.SENSOR_SENSITIVITY, 200);
builder2.addTarget(surface);
hdrRequestList.add(builder2.build());
// 帧3:过曝帧 (+2 EV)
CaptureRequest.Builder builder3 = cameraDevice.createCaptureRequest(
CameraDevice.TEMPLATE_STILL_CAPTURE);
builder3.set(CaptureRequest.CONTROL_AE_MODE,
CaptureRequest.CONTROL_AE_MODE_OFF);
builder3.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 80_000_000L); // 80ms
builder3.set(CaptureRequest.SENSOR_SENSITIVITY, 400);
builder3.addTarget(surface);
hdrRequestList.add(builder3.build());
// 通过CaptureSession按顺序提交帧序列
for (CaptureRequest request : hdrRequestList) {
captureSession.capture(request, hdrCaptureCallback, null);
}
关键注意:上述代码中
CONTROL_AE_MODE_OFF表示完全手动控制曝光参数。在实际产品中,建议使用CONTROL_AE_MODE_ON配合CONTROL_AE_EXPOSURE_COMPENSATION实现自动曝光包围,这样传感器可以自动调整增益和曝光时间,同时保持AE算法的稳定性。
3.7 本章小结
曝光包围与帧序列设计是HDR多帧捕获的基石。曝光包围通过合理的步长和帧数选择扩展动态范围,帧序列通过时序和顺序策略保证帧间一致性。两者协同设计时,需要综合考虑场景动态范围、运动程度、传感器能力和用户延迟容忍度。在Android Camera2框架中,开发者通过CaptureRequest的精细配置和CaptureCallback的帧同步机制,可以实现高效、鲁棒的HDR多帧捕获管线。