5.19. 色调校正¶
色调校正用于改变采集图像中亮度和颜色的分布方式——当一帧图像过暗、过亮、过于平淡或偏向错误的颜色时,应用程序所采取的修正手段。
这些校正分为两大类:重新分配亮度的明暗与对比度调整,以及改变每个像素所呈现颜色的颜色调整。两者在传感器的 ISP 中都有对应的处理,ISP 会在每一帧进入时对其进行校正;而本文介绍的方法则是事后作用于已采集的 Image,用于处理那些 ISP 提供的校正仍不足以满足需求的情况。
5.19.1. 直方图均衡化¶
最简单的对比度拉伸操作是 直方图均衡化。其思路是重新映射像素值,使输出的直方图尽可能平坦——每个值出现的频率大致相同。视觉上的效果是:一幅低对比度图像(其直方图集中在很窄的区间内)会变成一幅高对比度图像,其像素覆盖完整的 0 -- 255 范围。
histeq() 执行均衡化:
img.histeq()
其原理很直接。先计算源图像直方图的累积分布函数(CDF);每个输入像素值被映射到它在 CDF 中的位置,并缩放到输出范围。在像素本已均匀分布的地方,映射接近于恒等映射;在像素堆积于某一亮度的地方,映射会通过将该亮度拉伸到更宽的输出值范围来把它们展开。
在低对比度场景下,效果非常显著——一张昏暗的室内照片与同一张照片经 histeq 处理后的差别,往往就是“无法辨认”与“清晰可读”之间的差别。其代价是该操作会放大 一切,包括传感器噪声。对于确实存在需要恢复的低对比度细节的场景,histeq 是正确的选择;而对于本就干净、曝光良好、根本不需要处理的场景,histeq 会引入可见的噪声。
5.19.2. CLAHE:自适应均衡化¶
直方图均衡化是全局性的:它使用从整幅图像计算出的单一 CDF,并将其应用于所有位置。这在亮度范围大致均匀的图像上有效,但在存在局部暗区和亮区的场景上会失效——CDF 会被像素更多的一侧拉偏,而另一侧则会被过度校正。
其自适应变体是 对比度受限自适应直方图均衡化(Contrast Limited Adaptive Histogram Equalisation),通常称为 CLAHE。CLAHE 不使用单一的 全局 CDF,而是为图像的每个小图块分别计算一个 CDF,针对各自的 CDF 对每个图块进行均衡化,并将图块边界混合在一起。其结果是亮度调整发生在 局部 ——阴影中的角落获得自己的均衡化处理,而不会被明亮的角落拉向错误的方向。
adaptive=True 标志将 histeq() 切换为 CLAHE 模式:
img.histeq(adaptive=True, clip_limit=10)
clip_limit 参数对应名称中“对比度受限”所指的部分。在 CDF 几乎没有几个不同取值的平坦区域,局部均衡化可能会过度放大噪声;裁剪限制控制任何单个柱体被重新分配的激进程度,从而在防止噪声放大的同时仍允许在需要的地方进行对比度拉伸。10 左右的值是一个合理的起点;较大的值让 CLAHE 工作得更激进,代价是噪声更明显,较小的值则使其更柔和。
CLAHE 比 全局 histeq 开销更大,但在亮度分布不均匀的场景上能产生更干净的结果——而现实世界中的大多数场景都是如此。
5.19.3. 伽马、对比度和亮度¶
直方图均衡化是数据驱动的亮度重映射方式。而 与数据无关 的方式是应用一条选定的曲线,并通过几个易于调节的旋钮来参数化。gamma() 提供了三个这样的旋钮:
img.gamma(gamma=1.0, contrast=1.0, brightness=0.0)
每个参数对每个像素施加一种特定的变换:
gamma 将每个像素的值通过幂函数 output = input ** (1 / gamma) 进行处理。标准含义为:大于 1.0 的值会 提亮 图像并抬升中间调(即经典的“显示器伽马”校正);小于 1.0 的值会使其 变暗。该参数是非线性的——它保留黑场和白场,仅重塑两者之间的分布,当目标是在不压垮现有极值的情况下恢复阴影或高光区域的细节时,这正是恰当的行为。
contrast 将每个像素围绕中灰点进行一次直接的乘法运算。大于 1.0 的值会增强对比度(暗的更暗,亮的更亮,中灰保持不变);小于 1.0 的值会降低对比度。
brightness 为每个像素值加上一个常数。正值提亮,负值变暗。这种偏移是 均匀的 ——不保留任何内容——单独使用时这很少是应用程序所需要的,但它与一次对比度处理搭配使用以重新居中结果时效果很好。
这三个参数可以组合:一次 gamma() 调用就能在一个流程中先施加伽马曲线,再进行对比度乘法,最后施加亮度偏移。其顺序是先伽马,再对比度,最后亮度,这与当三者都为非默认值时能给出最符合直觉结果的顺序一致。
5.19.4. 自动白平衡¶
色调校正中的颜色类操作从 自动白平衡 开始。传感器 ISP 作为成像流水线一部分所运行的同一机制——调整红、绿、蓝通道的相对增益,使平均灰色调的色块呈现为真正的灰色——也可作为对已完成的 Image 进行的采集后操作:
img.awb()
默认使用 灰度世界(gray-world)算法:假定整幅图像的平均颜色为中性灰,并调整各通道增益使之成立。另一种 max=True 形式使用 白块(white-patch)算法:假定最亮的像素为中性白,并调整增益使之成立。两者都适用于 RGB565 和原始 Bayer 数据;都不适用于灰度图(其中没有可平衡的颜色)或 YUV(其颜色表示方式不是这些算法所操作的对象)。
何时应选择采集后形式而非 ISP 的自动白平衡:当 ISP 的选择与特定场景不匹配时,当应用程序正从磁盘加载在不同条件下采集的参考帧时,或当颜色判断重要到应用程序希望用自己选择的算法重新执行它时。
5.19.5. 颜色校正矩阵¶
当图像所需的颜色校正不是白平衡所提供的逐通道缩放,而是更一般的 通道混合 时,应选用的操作是 颜色校正矩阵。ccm() 方法应用一个 3×3(或带偏移量的 3×4)矩阵,将每个像素的 (r, g, b) 向量相乘以产生新的 (r, g, b) 向量:
img.ccm([[1.1, -0.05, -0.05],
[-0.05, 1.1, -0.05],
[-0.05, -0.05, 1.1]])
该矩阵让应用程序能够校正颜色通道之间的串扰——例如,当红色传感器的响应中包含了一些绿光时,矩阵可以从红色输出中减去一部分绿色通道以进行补偿。结合逐通道的偏移量,3×4 形式还能让应用程序对每个通道重新归零。
ISP 流水线 的材料阐述了颜色校正矩阵的 原理。Image 上的采集后形式只是同一操作的事后应用。