简介:个人学习分享,如有错误,欢迎批评指正。
一、相关概念
1. 色调映射
影像系统的一个核心功能是图像显示,好的显示效果能够真实地再现原始场景,给人的知觉效果就像直接观察原始场景一样。色调映射是影像再现系统的一个重要组成部分,它将原始场景的光照映射成显示设备的发光强度。
一个好的影像再现系统需要考虑到人类视觉系统(Human Vision System, HVS)是如何处理光线的。场景辐射的光线被人类视网膜上的杆细胞和锥细胞捕捉产生电信号,并传递到视觉神经通道(visual pathway)中做进一步处理。这些信号会被若干层神经网络进行非线性处理,形成的图像被称为知觉(percept),此时的知觉图像已经与原始的物理辐射图像相去甚远。
自然场景中可以存在非常广泛的光照条件,从昏暗的夜间场景到明媚的室外场景。下图列举了一些典型场景的光照度等级。


人类为了能够在上述各种场景下都能够正常观察物体并分辨足够的细节,人的视觉系统进化出了多种机制以适应不同的光照条件。首先是瞳孔,它可以改变直径从而控制进入眼睛的光线多少,这是对全局光照强度的一种适应性机制。其次是视锥细胞可以根据视场(Field of View, FOV)上的平均光亮度(即视网膜照度)调节敏感度。最后,当目光注视某一小区域时,视觉系统会自动调节局部对比度。因此,尽管人类生活环境中的光照度变化可以达到12个数量级,从极弱星光的10^-6nits 到阳光直射的 10^6 nits,而人眼感光细胞的实际动态范围只有4个数量级就能够适应各种环境场景。

视频捕捉设备生成的图像一般是正比于场景的光辐射强度的,即响应符合线性关系。尤其是当前主流的CMOS Image Sensor (CIS),线性度已经好到可以对入射光子的数量进行准确的计数。CIS的线性特点使人们可以很方便地对摄像机捕捉的原始图像进行处理,从而模拟人类视觉的行为,使设备输出的图像在人眼看来更加自然。这个过程叫做色调映射,如下图所示。


如果不做色调映射处理,摄像机直接输出最原始的线性图像,在人眼看来图像比正常的要暗,如下图所示。

(a)摄像机捕捉的原始线性图像 (b)人眼知觉的正常效果
这显然是因为人的视觉系统对视野中的暗区信号做了提升以形成更强烈的知觉,这个特性可以帮助人类识别隐藏在黑暗中的危险,是人类对生存环境的一种适应(adaptation)。
2. Tone Mapping 到底是什么
最简洁的定义是:
Tone Mapping 是把高动态范围亮度映射到低动态范围输出范围中的过程,同时尽量保留人眼感知上的亮度关系、层次和观感。
这里有两个关键词:
- 高动态范围
- 映射到可显示范围
现实世界的亮度范围非常大。
例如:
- 阴影角落可能很暗
- 窗外阳光可能非常亮
- 夜景里灯牌和暗部差异也很大
但显示设备、JPEG、8bit/10bit 编码都只能表示有限范围。
因此,必须把"场景中的大亮度跨度"压缩进"显示系统能表达的小范围"里。
这个压缩过程就是 Tone Mapping。
3. 为什么需要 Tone Mapping
3.1 场景动态范围远大于显示动态范围
现实世界的场景亮度跨度可能非常大。
一个典型逆光场景里:
- 室内人物脸部很暗
- 窗外天空极亮
传感器可能通过 HDR、多帧融合等手段记录了更多范围,但最终你仍然要显示在:
- 手机屏幕
- SDR 显示器
- JPEG 文件
- 视频编码系统
这些都不可能原样显示真实场景亮度。
所以必须进行压缩。
3.2 直接线性压缩效果很差
如果只是把 HDR 亮度线性压缩:
- 暗部容易发黑
- 高亮容易发灰
- 中间调缺乏层次
- 画面整体"平"
因为人眼并不是线性感知亮度的。
单纯线性缩放无法兼顾:
- 高亮细节
- 暗部可见性
- 整体对比感
Tone Mapping 的价值就在于:
不是机械压缩,而是按视觉需求进行有策略的压缩。
3.3 需要保留"看起来合理"的观感
Tone Mapping 不追求把物理亮度原封不动搬过来,因为做不到。
它追求的是:
- 看起来自然
- 明暗关系合理
- 高光不刺眼
- 暗部有细节
- 画面不死、不灰、不假
所以 Tone Mapping 的核心不是"物理忠实",而是:
在有限显示范围中重建一个视觉上合理的亮度世界。
4. Tone Mapping 的核心目标
Tone Mapping 通常要同时满足这几件事:
4.1 压缩动态范围
把大范围亮度压缩到小范围输出内:
L o u t = f ( L i n ) L_{out} = f(L_{in}) Lout=f(Lin)
其中:
- L i n L_{in} Lin:输入 HDR 或线性亮度
- L o u t L_{out} Lout:输出显示亮度或编码亮度
- f ( ⋅ ) f(\cdot) f(⋅):非线性压缩函数
4.2 保留高光细节
高亮区域不能一片死白。
比如:
- 云层纹理
- 灯牌细节
- 反光物体层次
Tone Mapping 需要压高亮,但不能把高亮全压平。
4.3 提升暗部可见性
暗部不能死黑。
例如:
- 室内阴影
- 夜景暗巷
- 背光人脸
Tone Mapping 往往要在压缩整体动态范围的同时,把暗部适度抬起来。
4.4 保持中间调自然
中间调往往决定"观感"。
如果中间调处理不好,会出现:
- 发灰
- 发闷
- 平
- 假 HDR 感
- 过度修图感
所以 Tone Mapping 很多时候真正难调的不是极亮极暗,而是中间调的走向。
4.5 尽量保持局部对比和层次
压缩动态范围会天然损失对比。
Tone Mapping 的难点在于:既要压,又不能压得没层次。
所以优秀的 Tone Mapping 不只是让亮度落进范围,更重要的是:
- 保细节
- 保层次
- 保局部对比
- 保自然感
5. Tone Mapping 的数学本质
从数学上看,Tone Mapping 就是在设计一个非线性函数:
L o u t = f ( L i n ) L_{out} = f(L_{in}) Lout=f(Lin)
这个函数通常具有这些特征:
1. 单调递增
更亮的输入不能映射成更暗的输出。
2. 低亮区域相对展开
暗部保留更多可见性。
3. 高亮区域逐渐压缩
避免高光溢出和死白。
4. 中间调控制整体观感
决定画面是通透、厚重、平淡还是刺激。
你可以把 Tone Mapping 曲线理解成一条 S 曲线、对数曲线或 shoulder/toe 曲线,而不是一条简单直线。
6. Tone Mapping 最直观的图像理解
如果横轴是输入亮度,纵轴是输出亮度,那么一条典型 Tone Mapping 曲线通常会有:
- toe(脚部):处理暗部
- mid-tone region(中间调区域):决定主体观感
- shoulder(肩部):压缩高亮
也就是说:
- 暗部不是死压,而是柔和抬起
- 中间调保持较好的斜率,保留主体对比
- 高亮逐渐变平,防止爆掉
这和简单 Gamma 不一样。
Gamma 更多是感知编码;
Tone Mapping 更强调"动态范围重分配"。
二、全局 Tone Mapping 与局部 Tone Mapping
这是 Tone Mapping 最重要的分类。

(a)全局色调映射 (b)全局加局部色调映射
1. 全局 Tone Mapping(Global Tone Mapping)
全局 Tone Mapping 的意思是:
整张图所有像素,只按同一条亮度映射曲线处理。
也就是:
L o u t ( x , y ) = f ( L i n ( x , y ) ) L_{out}(x,y)=f(L_{in}(x,y)) Lout(x,y)=f(Lin(x,y))
同样的输入亮度,无论在哪个位置,都会映射成同样输出亮度。
优点
- 实现简单
- 稳定
- 不容易出 halo
- 计算成本低
- 视频时序一致性好
缺点
- 对复杂场景适应能力有限
- 很难同时兼顾高光和暗部
- 容易出现:
- 高亮保住了,暗部太黑
- 暗部抬起来了,画面发灰
典型应用
- 基础 ISP tone curve
- 简单 HDR 输出
- 显示端标准映射
2. 局部 Tone Mapping(Local Tone Mapping)
局部 Tone Mapping 的意思是:不同区域采用不同程度的亮度压缩和对比调节。
即某个像素的输出不仅取决于它自己的亮度,还取决于周围区域的亮度分布:
L o u t ( x , y ) = f ( L i n ( x , y ) , N ( x , y ) ) L_{out}(x,y)=f(L_{in}(x,y),\mathcal{N}(x,y)) Lout(x,y)=f(Lin(x,y),N(x,y))
其中 N ( x , y ) \mathcal{N}(x,y) N(x,y) 表示邻域信息。
优点
- 更能兼顾高亮和暗部
- 局部细节保留更好
- 更容易做出"人眼觉得清楚"的效果
缺点
- 容易过度处理
- 容易出 halo(光晕)
- 容易出现局部不自然
- 视频里容易闪烁
- 算法复杂度更高
典型应用
- 手机 HDR
- LTM(Local Tone Mapping)
- 高级显示增强
- 计算摄影后处理
三、常见 Tone Mapping 算法思想
1. 算法定义
从算法角度看,Tone Mapping 的任务就是构造一个映射函数:
L o u t ( x , y ) = f ( L i n ( x , y ) ) L_{out}(x,y)=f\big(L_{in}(x,y)\big) Lout(x,y)=f(Lin(x,y))
或者在局部算法中写成:
L o u t ( x , y ) = f ( L i n ( x , y ) , N ( x , y ) ) L_{out}(x,y)=f\big(L_{in}(x,y),\mathcal{N}(x,y)\big) Lout(x,y)=f(Lin(x,y),N(x,y))
其中:
- L i n L_{in} Lin:输入亮度,通常是 HDR 亮度、线性 RGB 转出的亮度、或融合后的 luminance
- L o u t L_{out} Lout:输出亮度,通常是 SDR 或显示范围内的亮度
- N ( x , y ) \mathcal{N}(x,y) N(x,y):像素邻域信息
所以所有 Tone Mapping 算法本质上都在回答一个问题:
输入亮度太大了,怎么压到输出范围里,同时尽量保住细节和观感?
2. Tone Mapping 的基本处理对象是什么
在讲算法前,要先明确一个问题:
大多数 Tone Mapping 主要处理"亮度",不是直接处理 RGB
因为如果对 RGB 三通道分别随便做非线性压缩,很容易导致:
- 色相漂移
- 饱和度变化异常
- 彩色高光不自然
所以很多算法会先从 RGB 中提取亮度,例如:
L = 0.2126 R + 0.7152 G + 0.0722 B L = 0.2126R + 0.7152G + 0.0722B L=0.2126R+0.7152G+0.0722B
或者在某些空间里用 Y、log-luminance 等。
然后对亮度 L L L做 Tone Mapping,再把颜色重新恢复:
R ′ = L ′ L R , G ′ = L ′ L G , B ′ = L ′ L B R' = \frac{L'}{L}R,\quad G' = \frac{L'}{L}G,\quad B' = \frac{L'}{L}B R′=LL′R,G′=LL′G,B′=LL′B
这里: - L L L:原亮度
- L ′ L' L′:Tone Mapping 后亮度
这是一种常见"亮度-色彩分离"的思想。
3. 第一类:线性 / 分段线性 Tone Mapping
这类方法最简单,先从它讲起,因为很多 ISP 里最基础的 tone curve 本质上还是这一类。
3.1 纯线性压缩
最简单的办法是:
L o u t = a L i n L_{out} = aL_{in} Lout=aLin
如果最大输入亮度是 L m a x L_{max} Lmax,目标输出范围是 0,1,那么可以取:
a = 1 L m a x a = \frac{1}{L_{max}} a=Lmax1
于是:
L o u t = L i n L m a x L_{out} = \frac{L_{in}}{L_{max}} Lout=LmaxLin
优点
- 极其简单
- 稳定
- 没有局部伪影
- 硬件实现容易
缺点
- 画面通常很平
- 暗部不够亮
- 高亮压缩不灵活
- 中间调缺乏视觉优化
结论
这几乎只能算最原始基线,不适合高质量 HDR。
3.2 分段线性曲线
比纯线性更常见的是分段线性:
bash
暗部一段斜率
中间调一段斜率
高亮一段斜率
数学上可以写成:
L o u t = { a 1 L i n + b 1 , L i n < T 1 a 2 L i n + b 2 , T 1 ≤ L i n < T 2 a 3 L i n + b 3 , L i n ≥ T 2 L_{out} = \begin{cases} a_1L_{in}+b_1, & L_{in}<T_1 \\ a_2L_{in}+b_2, & T_1 \le L_{in}<T_2 \\ a_3L_{in}+b_3, & L_{in}\ge T_2 \end{cases} Lout=⎩ ⎨ ⎧a1Lin+b1,a2Lin+b2,a3Lin+b3,Lin<T1T1≤Lin<T2Lin≥T2
这里:
- T 1 , T 2 T_1,T_2 T1,T2:分段阈值
- a 1 , a 2 , a 3 a_1,a_2,a_3 a1,a2,a3:不同亮度段的斜率
直观理解
- 暗部斜率大一点:抬暗部
- 中间调适中:保主体层次
- 高亮斜率小一点:压高光
优点
- 容易控制风格
- LUT 实现方便
- 视频稳定性较好
- 工程可控性强
缺点
- 曲线转折如果不平滑,可能不自然
- 对复杂场景适应不够
- 本质仍是全局方法
手机 ISP 中的意义:很多 ISP 的基础 GTM 曲线,本质上就是平滑化后的分段曲线。
4. 第二类:全局非线性压缩类算法
这类方法比线性类更经典,也是 HDR Tone Mapping 的核心入门。

(a) linear mapping (b) Retinex mapping, 4 iterations
4.1 对数型 Tone Mapping
非常经典的一类是对数压缩:
L o u t = log ( 1 + α L i n ) log ( 1 + α L m a x ) L_{out} = \frac{\log(1+\alpha L_{in})}{\log(1+\alpha L_{max})} Lout=log(1+αLmax)log(1+αLin)
其中:
- α \alpha α:压缩强度控制参数
- L m a x L_{max} Lmax:输入亮度最大值或某个参考高亮值
为什么用对数
因为对数函数天然有这个性质:
- 小值变化更明显
- 大值变化逐渐压缩
这和"压高亮、展开暗部"的目标很一致。
参数影响
- α \alpha α 越大,高亮压得越厉害
- α \alpha α 越小,曲线越接近线性
优点
- 数学简单
- 能有效压缩超大动态范围
- 高亮不会轻易溢出
缺点
- 容易显得"发灰"
- 中间调缺乏主观优化
- 视觉风格偏保守
适用
- 学术入门
- 做基线方法
- 某些显示压缩场景
4.2 幂函数类 Tone Mapping
幂函数形式一般写作:
L o u t = L i n β , 0 < β < 1 L_{out} = L_{in}^\beta,\quad 0<\beta<1 Lout=Linβ,0<β<1
因为 β < 1 \beta<1 β<1,所以它会:
- 提升低亮
- 压缩高亮
和 Gamma 的区别
形式上很像 Gamma,但用途不同:
- Gamma 更偏"感知编码"
- Tone Mapping 里的幂函数更偏"压动态范围"
优点
- 形式简单
- 参数少
- 效果平滑
缺点
- 自由度低
- 很难兼顾高亮和中间调
- 对场景适应性差
4.3 Reinhard 全局 Tone Mapping
这是 HDR 里最经典的方法之一。
基础形式
L o u t = L i n 1 + L i n L_{out} = \frac{L_{in}}{1+L_{in}} Lout=1+LinLin
这个式子非常漂亮,因为它天然满足:
- 当 L i n L_{in} Lin 很小时,近似线性
- 当 L i n L_{in} Lin 很大时,逐渐趋于 1
也就是:
- 暗部不至于压没
- 高亮会自然 roll-off
白点控制版本
更常见的是:
L o u t = L i n ( 1 + L i n L w h i t e 2 ) 1 + L i n L_{out} = \frac{L_{in}\left(1+\frac{L_{in}}{L_{white}^2}\right)}{1+L_{in}} Lout=1+LinLin(1+Lwhite2Lin)
其中 L w h i t e L_{white} Lwhite 控制高亮"白点"位置。
为什么经典
它兼具:
- 数学简单
- 平滑单调
- 高亮肩部自然
- 物理直觉强
优点
- 稳定
- 自然
- 不容易出非常奇怪的伪影
缺点
- 中间调有时偏平
- 对局部对比保护不足
- 容易"安全但不惊艳"
工程理解
如果你想要一条"自然不太炸"的全局 tone curve,Reinhard 思路很值得参考。
4.4 Filmic / S-curve 类 Tone Mapping
这是现代显示和图像处理中非常重要的一类。
其核心不是单纯压高亮,而是设计一条更符合"胶片感"或"观感优化"的曲线,通常具有:
- toe:暗部脚部
- linear-ish middle:中间调较稳定
- shoulder:高亮肩部
一般形态
虽然公式各家不同,但共性是:
- 暗部柔和进入黑位
- 中间调保持层次
- 高亮平滑 roll-off,不硬截断
一个抽象形式
可以理解为某种有理函数、分段函数或拟合曲线:
L o u t = f ( L i n ) L_{out}=f(L_{in}) Lout=f(Lin)
其形状像一条平滑 S 曲线。
优点
- 观感好
- 中间调表现通常比纯对数/Reinhard 更讨喜
- 高亮 roll-off 更"像照片"
缺点
- 参数更多
- 调试复杂
- 容易因风格过强而偏"修图感"
实际意义
很多现代相机、游戏引擎、显示 pipeline 都很喜欢这类曲线,因为它更注重"看起来好"。
5. 第三类:基于统计量自适应的全局 Tone Mapping
前面的方法大多曲线固定或参数较少,这一类会根据整张图的统计特性自适应调整。
5.1 基于平均亮度的归一化
例如 Reinhard 论文中的经典步骤,会先计算 log-average luminance:
L ˉ l o g = exp ( 1 N ∑ x , y log ( δ + L ( x , y ) ) ) \bar{L}{log} = \exp\left(\frac{1}{N}\sum_{x,y}\log(\delta + L(x,y))\right) Lˉlog=exp(N1x,y∑log(δ+L(x,y)))
其中:
- δ \delta δ:防止 log(0) 的小常数
- N N N:像素数
然后把输入亮度归一化到某个"中灰"目标:
L m ( x , y ) = a L ˉ l o g L ( x , y ) L_m(x,y)=\frac{a}{\bar{L}_{log}}L(x,y) Lm(x,y)=LˉlogaL(x,y)
这里 a a a 往往代表中灰目标,例如 0.18。
含义
这一步本质上像"自动曝光 + 动态范围压缩前归一化"。
优点
- 能适应不同场景亮度
- 明亮图和昏暗图不会用同一绝对曲线硬压
缺点
- 整体受全图统计影响较大
- 极端高亮区域可能影响整体结果
5.2 基于直方图的自适应
另一类方法会看整张图的亮度直方图,决定 tone curve。
例如:
- 根据亮度分布决定中间调位置
- 根据 percentile 确定白点/黑点
- 对直方图做压缩映射
优点 - 对整图动态范围分布感知更好
- 比固定曲线更灵活
缺点 - 有时不够稳定
- 不同场景间风格跳动较大
- 视频里可能闪烁
5.3 基于 percentile 的白点/黑点设定
例如不是直接用最大亮度 L m a x L_{max} Lmax,而是用:
- 99.5% 分位点作为白点
- 0.5% 分位点作为黑点
这样可避免少数极端亮点主导曲线。
工程价值
这在手机 ISP 很有现实意义,因为: - 画面里可能有几个小灯珠非常亮
- 不能让几个极端点把整张图都压灰
6. 第四类:局部 Tone Mapping(LTM)算法
这部分是重点,也是最复杂的。
LTM 的核心思想是:
不只看像素本身亮度,还看它周围环境,做局部自适应压缩。
6.1 为什么要局部
全局曲线的根本局限是:
- 同一输入亮度,无论在亮背景还是暗背景,输出都一样
但人眼不是这样看的。
举例:
- 暗房间里的一张脸,和大太阳下的一张脸,即使绝对亮度相同,视觉感受也不同
- 局部对比和上下文很重要
所以局部 Tone Mapping 想模拟这种"相对感知"。
6.2 基本思想:分解 base 和 detail
最经典套路是先把亮度分成:
log L = log B + log D \log L = \log B + \log D logL=logB+logD
或者写成:
- B B B:base layer,低频大尺度亮度
- D D D:detail layer,高频局部细节
然后:
- 压缩 base layer 的动态范围
- 保留 detail layer
- 再重建输出
即:
L ′ = T ( B ) ⋅ D L' = T(B)\cdot D L′=T(B)⋅D
或者在 log 域:
log L ′ = T ( log B ) + log D \log L' = T(\log B)+\log D logL′=T(logB)+logD
为什么有效
因为动态范围主要体现在大尺度亮度变化上,而纹理细节主要在高频。
如果只压 base,不动 detail,就能:
- 压大范围明暗
- 保局部细节
6.3 如何得到 base layer
这是 LTM 算法的关键。
方法 A:高斯滤波
简单平滑:
B = G σ ∗ L B = G_\sigma * L B=Gσ∗L
优点:
- 简单
缺点:
- 容易跨边缘泄漏
- 易产生 halo
方法 B:双边滤波
双边滤波考虑空间距离和亮度差:
B ( p ) = 1 W p ∑ q ∈ Ω G s ( ∣ p − q ∣ ) G r ( ∣ L ( p ) − L ( q ) ∣ ) L ( q ) B(p)=\frac{1}{W_p}\sum_{q\in\Omega}G_s(|p-q|)G_r(|L(p)-L(q)|)L(q) B(p)=Wp1q∈Ω∑Gs(∣p−q∣)Gr(∣L(p)−L(q)∣)L(q)
其中:
- G s G_s Gs:空间权重
- G r G_r Gr:亮度相似性权重
优点:
- 保边缘
- 减少 halo
缺点:
- 计算复杂
- 参数敏感
方法 C:引导滤波
引导滤波是一种更高效的 edge-preserving smoothing 方法。
优点:
- 较快
- 保边缘效果好
- 更适合工程实现
方法 D:多尺度分解
把亮度分成多个尺度层,再分别调整。
这在高级算法和学习型方法里更常见。
6.4 LTM 的核心操作
假设你已经得到 base B B B 和 detail D D D,那么可对 base 做压缩:
B ′ = T ( B ) B' = T(B) B′=T(B)
例如:
B ′ = log ( 1 + α B ) log ( 1 + α B m a x ) B' = \frac{\log(1+\alpha B)}{\log(1+\alpha B_{max})} B′=log(1+αBmax)log(1+αB)
然后重建:
L ′ = B ′ ⋅ D L' = B' \cdot D L′=B′⋅D
或者 detail 还可以再轻微增强:
L ′ = B ′ ⋅ D η L' = B' \cdot D^\eta L′=B′⋅Dη
其中 η > 1 \eta>1 η>1 表示细节增强。
6.5 LTM 的优点
- 能同时保住高亮和暗部
- 局部细节更清楚
- 比全局算法更接近"人眼觉得清楚"的效果
6.6 LTM 的典型问题
Halo
最经典伪影。
在高对比边缘(如建筑边缘、树和天空边界)附近,base/detail 分解不完美会导致光晕。
局部不自然
如果局部压缩太强,会让每块区域都"自己亮起来",丢失整体光照逻辑。
假 HDR 感
这是手机 HDR 最常见问题之一:
细节很多,但画面很假、很脏、很"过处理"。
视频闪烁
局部估计不稳定时,视频容易时序抖动。
7. 第五类:学习型 Tone Mapping
近年来很多 RAW-to-RGB、HDR-to-SDR、display enhancement 都会用神经网络。
7.1 基本思路
输入:
- HDR 图
- RAW 图
- 多帧融合结果
输出:
- Tone mapped SDR 图
- 或某种 display-referred RGB
本质上让网络学习一个复杂映射:
I o u t = F θ ( I i n ) I_{out} = F_\theta(I_{in}) Iout=Fθ(Iin)
其中 F θ F_\theta Fθ 由 CNN/Transformer 表示。
7.2 它学到的是什么
网络往往同时学会了:
- 动态范围压缩
- 局部对比控制
- 高亮 roll-off
- 色彩重建
- 风格偏好
所以它已经不只是传统意义的 Tone Mapping,而是更大的"观感映射"。
7.3 优点
- 拟合能力强
- 对复杂场景表现可能更好
- 可把 Tone Mapping 和 denoise/color/style 联合起来
7.4 缺点
- 可解释性差
- 训练数据依赖强
- 时序一致性难
- 工程控制难
- 不容易像 LUT 那样精确调某一段亮度
工程现实
手机量产 ISP 里,纯神经网络直接取代传统 Tone Mapping 还不算主流,更多是:
- 传统 Tone Mapping 为主
- AI 模块做辅助增强
- 或在特定模式下做后处理
8. Tone Mapping 算法中的几个关键设计点
不管是哪类算法,真正做时都会碰到这些关键问题。
8.1 压的是亮度还是 RGB
更推荐压亮度,再恢复颜色。
否则容易色偏。
8.2 在什么域处理
常见有:
- 线性亮度域
- log-luminance 域
- YUV 的 Y 通道
- Lab 的 L 通道
很多算法喜欢在 log 域处理,因为动态范围跨度大时更稳定。
8.3 white point 怎么定
高亮压缩强不强,常取决于白点设定。
如果白点太低:
- 图会发灰
如果白点太高: - 高光容易炸
8.4 中间调怎么保
很多算法失败不是因为高光没压,而是中间调没保好。
中间调决定:
- 人脸
- 主体
- 通透感
- 自然度
8.5 局部增强强度怎么控
局部算法里,这往往决定:
- 是"清楚"
- 还是"假 HDR"
9. 不同算法家族的对比总结
9.1 线性/分段线性
适合:
- 简单实现
- 稳定量产
- 基础 GTM
缺点:
- 灵活性有限
9.2 对数/幂函数/Reinhard
适合:
- 学术基础
- 简洁全局压缩
- 自然保守输出
缺点: - 局部层次不够
9.3 Filmic / S-curve
适合:
- 好观感
- 更自然照片感
- 中间调优化
缺点:
- 参数复杂
9.4 局部 Tone Mapping
适合:
- 高反差复杂场景
- 手机 HDR
- 细节可见性要求高
缺点:
- 伪影风险高
9.5 学习型
适合:
- 高级联合优化
- 特定任务场景
缺点:
- 工程可控性差
10. 手机 ISP 中最常见的实际做法
真实手机 ISP 往往不是"纯某一种算法",而是组合式的:
- 先做全局 tone curve
- 定整体风格
- 定高亮 shoulder
- 定中间调基线
- 再做局部 Tone Mapping
- 提暗部可见性
- 增加局部层次
- 最后再接 Gamma / OETF
- 做显示与编码适配
所以真正量产系统里常见的是:
GTM + LTM + Gamma 的组合
而不是某个单独"神奇公式"。
四、Tone Mapping对比分析
- Tone Mapping 与 HDR 的关系
很多人会混淆:
- HDR 是不是就是 Tone Mapping?
- Tone Mapping 是不是 HDR 才有?
答案都是否定的。

(a) HDR scene in linear scale (b) HDR scene in logrithm scale
1.1 HDR 不是 Tone Mapping
HDR 是一个更大的概念,可能包括:
- 多曝光采集
- 多帧融合
- 更高动态范围表示
- 更高 bit-depth
Tone Mapping 只是其中一个环节。
1.2 Tone Mapping 是 HDR 输出的重要一步
HDR 图像即使融合出来了,仍然需要压到显示范围内。
这一步就需要 Tone Mapping。
所以:
HDR 负责"拿到更多动态范围",Tone Mapping 负责"把这些动态范围显示出来"。
1.3 没有 HDR 也可以有 Tone Mapping
即使单帧普通相机图,也会有 tone curve。
因为任何显示输出都需要某种亮度重分配。
2. Tone Mapping 与 Gamma 的区别
这个必须彻底分清。
2.1 Tone Mapping 解决的是"动态范围压缩"
核心问题是:
- 场景太亮太暗,显示装不下
- 怎么压进去还好看
2.2 Gamma 解决的是"感知均匀编码"
核心问题是:
- 线性亮度不适合显示和编码
- 怎么把码值分布更符合视觉感知
2.3 两者关系
通常可以理解成:
- Tone Mapping:先决定整体亮度如何压缩
- Gamma:再把结果编码成适合显示/存储的非线性信号
虽然工程上两者有时会融合进同一条 LUT,但概念上不一样。
3. Tone Mapping 与 LTM 的区别
LTM 其实是 Tone Mapping 的一个子类,更准确地说:
LTM = Local Tone Mapping
所以:
- Tone Mapping 是总概念
- GTM 是全局 Tone Mapping
- LTM 是局部 Tone Mapping
五、Tone Mapping 调不好会出现什么问题
1. 画面发灰
这是最常见的问题之一。
原因通常是:
- 动态范围压得太平
- 中间调斜率太小
- 高亮和暗部都被拉到中间
结果就是:
- 没冲击力
- 没层次
- 像蒙了一层灰
2. 高光死白
如果 shoulder 不够,或者高亮压得太晚,高光会直接剪掉,出现:
- 天空一片白
- 灯牌没纹理
- 反光物体发死
3. 暗部死黑
如果暗部没有被适当抬起:
- 阴影没细节
- 室内看不清
- 夜景黑成一片
4. 假 HDR 感
局部 Tone Mapping 过强时,会出现:
- 每个区域都像被单独照亮
- 缺乏真实光照关系
- 局部过度增强
- 细节过分"翻出来"
这就是常说的"假""脏""修过头"。
5. Halo(光晕)
LTM 经典伪影。
在高对比边缘附近出现明暗边带,像一圈光晕。
原因通常是:
- 基底层估计不准
- 局部增强跨边缘泄漏
- 边缘保持滤波不够好
6. 视频闪烁
局部 Tone Mapping 在视频里尤其麻烦。
如果帧间局部亮度估计不稳定,会出现:
- 明暗跳变
- 区域忽亮忽暗
- 肉眼可见闪烁
所以视频里的 Tone Mapping 通常要更保守,并强调时序一致性。
六、总结
你可以把它理解成:
Tone Mapping 是 ISP/显示链路中负责"亮度资源重新分配"的模块,它决定在有限的输出动态范围里,哪些亮度被压缩、哪些层次被保留、哪些区域被强调,从而直接决定画面的明暗风格、层次感和自然度。
如果用一句话总结 Tone Mapping:
Tone Mapping 是将高动态范围场景亮度通过非线性映射压缩到显示设备可表达范围内,同时尽可能保留高光细节、暗部可见性、中间调自然度和局部层次的过程。
参考文献:
Understanding ISP Pipeline - Tone Mapping
结~~~