又见色彩匹配
- Color
- 三十分钟系列
又见色彩匹配
色彩匹配,这是我个人非常喜欢的一个话题。
之前已经研究过很多种不同的匹配算法:
传统的color transfer
(基于直方图均衡方法等)
基于标准色卡的匹配
基于LUT
采样(梯度下降匹配、GAN之类的)
这些方法都有点“机器化” 的味道。这不禁让我回想起调色的过程,人们是怎么判断色彩风格相近?
看起来颜色一样?
调色的时候,我们会找很多参考样片,然后参考这些画面色彩进行调整。当我们看到图片的时候,我们如何直观的衡量是不是色彩一致?
《疯狂的麦克斯》
可能的步骤是:
- 亮度的感觉(暗部、亮部、反差感、分布曲线)
- 色彩整体倾向(各个亮度区域的色彩倾向)
- 固有色倾向(皮肤、天空、植物等等)
这里就隐含了一种感觉。其实我们是在一一对应不同部位的色彩。
肖申克的救赎
问题来了
我仅仅提供少数的color pair
,怎么能够让所有色彩的变化更加的“平滑”?这样才能够不出现反色、调变等问题,还能够更好顺应色彩的“走势”?
经过一番科学上网,找了很老的一个算法。叫做Thin-plate spline
(薄板插值)。
薄板样条插值(Thin Plate Spline
,TPS
)是插值方法的一种,是常用的2D插值方法。假如给定两张图片中一些相互对应的控制点,如何将其中一个图片进行特定的形变,使得其控制点可以与另一张图片的控制点重合。
这种算法往往被应用在实际的生产中。例如有汽车铁板冲压的过程中。我们希望:
- 冲压后,所有原始位置
p_i
尽可能靠近目标位置q_i
- 薄板的“扭曲程度”尽可能的小
把这个算法提升到3D 空间中,不就正好可以用于描述色彩LUT
变形的样式么!
3D Thin-plate Spline 色彩匹配
利用上面说的thin-plate spline
插值方式,可以更好的实现平滑过度。
本质上,3D TPS
算法在这里的使用场景是,对于有固定色卡采用的屏幕,可以相对快速的计算得到LUT
。
一些优点:
- 可以通过数量比较少的
sample
,推导出LUT
,计算速度极快。Xrite digital SG 色卡,140 samples - 用户可以根据控制
TPS
算法中的lambda
,来人工控制匹配程度或者是色彩变化平滑程度,减少色彩跳变。
算法支持 float
,不会受到 0~1
的裁切。
算法测试
参考代码和 LUT
见文末
这里成为一个互动式的校准过程。
- 默认使用基准点进行 matching (这里是直接采样了中间的色卡点)
- 查看匹配效果
- 如果发现效果不够好的时候,不断添加source-dst 的pair,就可以不断逼近。
这里累计使用了37个采样点,就完成了这样的效果。近看的话,在比较暗部的皮肤处还有不同,不过这可以通过不断的增加匹配点来进行逼近。或者是调整扭曲的程度,让色彩变化更加的平滑。
原始LogC
Rec709(ACES)
应用匹配LUT 的结果
进一步的改进
上面说到了,可以人为的发现“不够好”的点,然后添加到color pair
中,实现进一步的匹配。如果不想要人工进行匹配的话,那么可以采用自动的方式。这里有三种可能的思路:
- 图像色彩差异比较
- 3D color 空间比较
- 在
uniform colorspace
中完成计算
图像色彩差异比较
这种思路非常的直观,只需要对比target
和 output
,然后选择其中数值差异超过阈值的色彩部分即可。当然最好也是在uniform
的色彩空间中进行比较。
色彩差异扩大了4倍,便于展示
3D 空间的差异处理
这里只能有几个思路:
- 找到相对聚类的色彩区域,然后进行移动
- 从
3D position
找到对应的2D 画面position
,然后读取色彩作为key point
Target 709
Output 709
在 uniform colorspace 中完成计算
由于TPS 的误差是欧式距离误差,而显示色彩空间并不是uniform
的。因此如果可以在uniform colorspace
中进行计算的话,理论上会得到更加符合人眼感受的拟合效果。
哲学高度
兜兜转转,曾经幻想着用各种“绝对客观” 的方法直接进行色彩匹配,但是现在又回到了最靠谱的方案,稍微让人动手做点事情,算法就能更有效的解决其他问题。 人的主观选择,直接解决了色彩差异敏感性、匹配权重、匹配过拟合、匹配结果是否满意等一系列高难度。
于是乎,基于上面的code,这里想到一个色彩匹配LUT
的生成软件方式。有兴趣的可以自己实现一下!
人手稍微动个100次,就能够得到一个相对通用的匹配结果LUT
,何乐而不为呢~
《又见色彩匹配》参考代码和 lut 文件以及算法论文
点击购买,或者扫描二维码