ISP-Tone Mapping

简介:个人学习分享,如有错误,欢迎批评指正。

一、相关概念

1. 色调映射

影像系统的一个核心功能是图像显示,好的显示效果能够真实地再现原始场景,给人的知觉效果就像直接观察原始场景一样。色调映射是影像再现系统的一个重要组成部分,它将原始场景的光照映射成显示设备的发光强度。

一个好的影像再现系统需要考虑到人类视觉系统(Human Vision System, HVS)是如何处理光线的。场景辐射的光线被人类视网膜上的杆细胞和锥细胞捕捉产生电信号,并传递到视觉神经通道(visual pathway)中做进一步处理。这些信号会被若干层神经网络进行非线性处理,形成的图像被称为知觉(percept),此时的知觉图像已经与原始的物理辐射图像相去甚远。

自然场景中可以存在非常广泛的光照条件,从昏暗的夜间场景到明媚的室外场景。下图列举了一些典型场景的光照度等级。

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

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

图片\]](https://i-blog.csdnimg.cn/direct/4e258471b21e4d249698b3da36e548ab.png) ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/c5a2b030e56a41708d456ecd6edece71.png) 如果不做色调映射处理,摄像机直接输出最原始的线性图像,在人眼看来图像比正常的要暗,如下图所示。 ![\[图片\]](https://i-blog.csdnimg.cn/direct/98625beec12f4a8386fe8486fa522fca.png) (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 最重要的分类。 ![\[图片\]](https://i-blog.csdnimg.cn/direct/ca71624538ee4f50aef7ee4fda219aa9.png) (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}\ 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 往往不是"纯某一种算法",而是组合式的: 1. 先做全局 tone curve * 定整体风格 * 定高亮 shoulder * 定中间调基线 2. 再做局部 Tone Mapping * 提暗部可见性 * 增加局部层次 3. 最后再接 Gamma / OETF * 做显示与编码适配 所以真正量产系统里常见的是: **GTM + LTM + Gamma 的组合** 而不是某个单独"神奇公式"。 ## 四、Tone Mapping对比分析 1. Tone Mapping 与 HDR 的关系 很多人会混淆: * HDR 是不是就是 Tone Mapping? * Tone Mapping 是不是 HDR 才有? 答案都是否定的。 ![\[图片\]](https://i-blog.csdnimg.cn/direct/97f2b5ffeeae4303a401c8d8e789807c.png) (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](https://zhuanlan.zhihu.com/p/104430989) *** ** * ** *** 结\~\~\~

相关推荐
yugi9878382 小时前
非支配排序遗传算法NSGA-III详解与MATLAB实现
算法
米粒12 小时前
力扣算法刷题 Day22
算法·leetcode·职场和发展
科德航空的张先生2 小时前
飞行错觉(空间定向障碍)地面模拟训练系统
人工智能·算法
老四啊laosi2 小时前
[双指针] 2. 力扣--复写零
算法·leetcode·双指针·复写零
ballball~~2 小时前
ISP-Gamma
图像处理·算法·isp
机器学习之心2 小时前
HHO-LSBoost哈里斯鹰算法优化最小二乘提升多输入回归预测MATLAB代码
算法·matlab·回归·hho-lsboost
ballball~~2 小时前
ISP-Demosaic
图像处理·数码相机·算法
m0_730115112 小时前
C++中的装饰器模式实战
开发语言·c++·算法
我真会写代码2 小时前
深入浅出图像处理原理:OpenCV基础与YOLO实战,从入门到落地
图像处理·人工智能