7、高动态范围(HDR)基础:HDR原理、线性与非线性传感器、多帧合成与单帧HDR

各位好,今天我们来聊聊车载Camera系统里一个绕不开的话题——HDR。说实话,HDR这个词在消费电子领域已经被说烂了,但在车载领域,它的意义完全不同。你手机拍夜景HDR,拍糊了可以重来。但在车上,前方一个隧道出口,阳光刺眼,如果HDR没做好,那一帧图像可能就直接导致感知系统漏掉一个行人。嗯,责任重大。

7.1 为什么车载摄像头需要HDR?

我们先想一个问题:一个普通的8-bit sensor,动态范围大概在60-70dB左右。这是什么概念?我举个例子,你在一个晴朗的下午开车,隧道入口处的亮度可能只有10 lux,而隧道外的阳光直射区域可能高达100,000 lux。这中间的跨度超过80dB。普通sensor根本hold不住,要么暗部一片死黑,要么亮部过曝成一片白。

我当年在做一个ADAS项目时,第一次拿到路测数据,发现车辆刚出隧道的那几帧,前方几乎全是白茫茫一片。算法团队直接炸了,说这数据没法用。后来我们才意识到,不是算法不行,是图像数据本身就已经丢失了信息。所以,HDR在车载领域不是锦上添花,而是刚需。

核心结论: 车载HDR的目标是在同一帧图像中,同时保留暗部细节和亮部细节,使动态范围覆盖场景的真实光照范围(通常需要 > 120dB)。

7.2 HDR的基本原理

说白了,HDR就是让摄像头能「看」到更亮和更暗的东西。传统sensor的响应是线性的,每个像素的电荷量与入射光强成正比。但线性响应有个问题——它只能在一个有限的亮度范围内保持线性。超出这个范围,就饱和了。

HDR的核心思路其实很简单:用不同的曝光参数去捕捉同一场景,然后把它们合成在一起。短曝光捕捉亮部细节,长曝光捕捉暗部细节,中间曝光负责过渡区域。最后通过融合算法,把三张图里「最好」的部分拼成一张图。

你可能会问:这不就是多帧合成吗?没错,但车载场景下,多帧合成面临一个巨大的挑战——运动。车辆在高速行驶,场景中的物体也在快速移动。如果帧与帧之间有运动,合成出来的图像就会出现鬼影(ghosting)。所以,车载HDR的难点不在于「怎么合成」,而在于「怎么在运动场景下合成得又快又好」。

7.3 线性传感器 vs 非线性传感器

这里我要讲一个很多初学者容易混淆的概念。我们常说的「线性传感器」,指的是光电转换特性是线性的——入射光强增加一倍,输出电压也增加一倍。这种传感器在低动态范围场景下表现很好,但遇到高对比度场景就捉襟见肘了。

那非线性传感器呢?它的响应曲线不是一条直线,而是一条对数曲线或者分段线性曲线。什么意思?就是它对暗部区域的增益高,对亮部区域的增益低。这样一来,同样的8-bit数据,它能覆盖更宽的亮度范围。

我个人的习惯是,在选型时先看sensor的响应曲线。如果是线性sensor,那基本只能靠多帧合成来做HDR。如果是非线性sensor(比如LFM、Split Pixel这类),那单帧就能实现不错的HDR效果。

特性 线性传感器 非线性传感器
响应曲线 直线(光强 vs 电压) 对数/分段线性
动态范围 60-70 dB(典型) 100-140 dB(典型)
HDR实现方式 多帧合成(DOL、SME) 单帧HDR(LFM、Split Pixel)
运动伪影 容易产生鬼影 基本无鬼影
成本 较低 较高
车载适用场景 低速/停车场景 高速/全场景
避坑指南: 我曾经在一个项目中选了线性sensor做多帧HDR,结果在高速测试时鬼影严重到无法使用。后来换成了LFM sensor,问题迎刃而解。所以,如果你的应用场景涉及高速运动(比如前视ADAS),建议直接上非线性sensor。

7.4 多帧合成HDR

多帧合成HDR,也叫DOL(Digital Overlap)模式。它的工作流程是这样的:sensor在同一个曝光周期内,连续输出多帧不同曝光时间的图像。比如一帧短曝光(1ms)、一帧中曝光(4ms)、一帧长曝光(16ms)。然后ISP把这些帧对齐、融合,输出一张HDR图像。

这里有个关键参数——帧间间隔。如果三帧之间的时间差太大,运动物体就会在帧间发生位移,导致合成后出现鬼影。所以,DOL模式要求帧间间隔尽可能短,最好在1ms以内。

我记得有一次调试一个DOL方案,发现鬼影总是消不掉。查了半天,发现是sensor的帧间间隔配置错了,实际间隔是3ms而不是我们以为的0.5ms。改回来之后,效果立竿见影。所以,做多帧HDR,一定要确认sensor的时序配置。

// DOL模式下的曝光时序配置示例(伪代码)
// 假设使用三帧合成:T1=1ms, T2=4ms, T3=16ms
// 帧间间隔要求 < 1ms

sensor_config_t cfg;
cfg.hdr_mode = HDR_MODE_DOL;
cfg.num_exposures = 3;
cfg.exposure_times[0] = 1000;   // 1ms (短曝光)
cfg.exposure_times[1] = 4000;   // 4ms (中曝光)
cfg.exposure_times[2] = 16000;  // 16ms (长曝光)
cfg.frame_interval = 500;       // 0.5ms 帧间间隔

// 注意:不同sensor的寄存器配置方式不同
// 务必参考datasheet中的时序图
sensor_apply_config(&cfg);
注意事项: 多帧合成HDR对sensor的读出速度要求很高。如果sensor的读出速度跟不上,帧间间隔就会拉长,鬼影风险急剧上升。另外,多帧合成会占用更多的ISP带宽和内存带宽,设计时要提前评估。

7.5 单帧HDR

单帧HDR,顾名思义,就是只用一帧曝光就实现高动态范围。这听起来有点反直觉——一帧怎么能同时覆盖亮部和暗部呢?答案是:利用sensor像素本身的设计

目前主流的单帧HDR技术有两种:

  • LFM(Large Full Well):每个像素有两个电荷存储节点,一个容量大(用于亮部),一个容量小(用于暗部)。曝光结束后,两个节点的电荷分别读出,然后合成。
  • Split Pixel:每个像素被分成两个子像素,一个子像素的感光面积大(灵敏度高,用于暗部),另一个感光面积小(灵敏度低,用于亮部)。两个子像素的信号合并,得到HDR图像。

这两种方案的好处是:没有帧间间隔,所以没有鬼影。你想想看,车辆在高速上跑,前方突然出现一个逆光的行人,单帧HDR能在一帧内同时保留行人的轮廓和背景的细节。而多帧HDR如果帧间间隔没控制好,可能就出现鬼影了。

不过,单帧HDR也有代价。LFM方案需要更大的像素面积,所以分辨率会受限。Split Pixel方案则对工艺要求高,成本也更高。我个人的建议是:前视、环视这类对运动伪影敏感的场景,优先考虑单帧HDR;倒车、侧视这类低速场景,多帧HDR也够用

7.6 知识体系总览

下面这张图是我自己整理的HDR知识体系,涵盖了从原理到实现的完整链路。你可以把它当作一个快速索引,遇到具体问题时回来对照着看。

车载HDR知识体系 HDR核心目标 覆盖 >120dB 动态范围 传感器类型 线性传感器 60-70dB 需多帧合成 非线性传感器 100-140dB 支持单帧HDR HDR实现方式 多帧合成(DOL) 3帧不同曝光 需防鬼影 单帧HDR LFM / Split Pixel 无鬼影 关键挑战 运动伪影(鬼影) 多帧HDR的核心痛点 ISP带宽与延迟 多帧合成占用大 传感器选型与成本 非线性sensor成本高

7.7 小结

好了,这一章的内容就到这里。我们聊了HDR的基本原理,对比了线性传感器和非线性传感器的差异,也深入分析了多帧合成和单帧HDR各自的优缺点。说实话,HDR这个领域水很深,不同场景、不同成本约束下,选择完全不一样。但有一点是确定的:在车载领域,HDR不是可选项,而是必选项。没有HDR,你的感知系统在强光、逆光、隧道出入口这些场景下,基本就是瞎子。

下一章我们会深入HDR的工程实现细节,包括ISP pipeline中的HDR融合算法、鬼影消除技术,以及如何在Android HAL层配置HDR模式。到时候我会分享一些我在项目中踩过的坑,希望能帮你少走弯路。

一句话总结: HDR的本质是用「多信息」换「宽范围」。线性传感器靠多帧,非线性传感器靠像素设计。选型时,先看场景,再看成本,最后看性能。


公众号:蓝海资料掘金营,微信deep3321