OCIO v2 的好处都有啥

Andy Guo原创
  • Color
  • 三十分钟系列
  • Color
  • Color Science
  • 色彩空间
  • 色彩科学
  • ACES
  • OCIO
  • 反向LUT
大约 13 分钟

OCIO v2 的好处都有啥

起源

最近ACES 的各种讨论感觉又火了起来。ACES 经过这么多年的打磨、更新、教育、标杆作品出现,使得行业对于ACES的接纳程度越来越高了。

1599751305888.jpg

我个人觉得最功不可没的还属是各大软件厂商的支持,使得ACES 不再是少数人的玩具,每个人都可以自己在软件里面,自己摆弄一下各种in colorspaceout colorspace 选项,就能够看到直观的色彩变化了。

ScreenShot2022-02-07at21.07.10.png

今天,不说ACES 本身了,说说ACES 背后的“好心人” OpenColorIO

手撸实现 vs OCIO

不禁让我想起自己在2014年左右开始研究ACES 的时候,自己看着CTL 的算法在各种软件里面进行实现,其中包括pythonnuke NDKOFXrenderman shader 等,非常麻烦:

  • 每个实现方式都略有不同
  • 纯粹CPU 的实现效能又比较差……(主要还是因为自己人菜

OCIO 作为ASWF 接纳的开源项目,是一套非常成熟的色彩管理解决方案。有了OCIO,所有的色彩管理都可以认为是一套“方案”或者“预设”,OCIO 按照这个方案对色彩进行运算处理即可。

好处主要有:

  • 色彩管理方案 和 实际运算引擎 分离。兼容未来新的色彩空间,无需每出现一套新的处理方案就需要重写计算部分
  • 分离后的色彩管理方案,可以轻松实现自定义配置。版本控制优秀
  • 可以保证在所有支持OCIO 的软件内得到相同的结果
  • 软件厂家只需要内嵌OCIO,无需自己亲自实现色彩运算部分
  • 让色彩管理操作简化,降低用户跨软件的学习成本

提示

不得不说,Sony Pictures Imageworks 真·好心人! 又把自家的好东西拿出来了~

OCIO v2 来了!

相关信息

OCIO v2 主要是由Autodesk 主导,在2017年开始开发,2021年1月放出官方正式版。

可以拍着胸脯来说,只要你用了比较新的VFX 软件,那么OCIO 基本上已经是标配了,即便不了解色彩管理的背景知识,还是可以进行操作:

  1. 开启OCIO 配置 (或插件)
  2. 选择某个 OCIO config 文件
  3. 根据实际制作规范,选择对应的in、out 色彩空间
  4. 开干!

OCIO v2 对艺术家的影响其实不大,因为操作没有什么变化。但是底层变化比较多。其中比较大的功能性更新主要有:

  • 全新的GPU 渲染器。速度快+保证和CPU效果一致
  • 更快的CPU 渲染器。利用SSE 指令集,最快提速20x
  • 支持整形像素buffer。和我们关系不大
  • 更好的针对处理器优化。和我们关系不大
  • 所有操作都支持反向
  • 支持ACES 的全新操作器。与ACES 官方CTL 效果一致
  • 支持 ASC CLF。支持并且很彻底的支持了ACES 1.2 中的CLF 格式
  • 内置了常用的色彩转换,省着连最基本的转换都需要自己去找LUT
  • 所有的OCIO 转换操作,都能够转换成为CTF xml
  • 可以通过公开的API 进行所有操作
  • 可以用Display-referred 类空间作为connection space。不必所有的转换都需要回到scene-referred
  • shared view 可以对于多个显示器进行复用。和我们关系不大
  • 支持ICC profile 文件。嗯……支持的很基本
  • 太多了…… 自己可以去OCIO v2open in new window 去看

计算反向LUT,又来了!

看完了刚才那一大堆OCIO v2 的新特性,不知道你有没有很敏锐的发现一些小秘密?

提示

所有操作都支持反向?!那岂不是…… 3D LUT

没错,计算反向LUT,他又回来了!

4a8a53559044a_1523930913772.jpg

TL;DR

如果你只是想得到一个反向LUT,那么跟着下面操作就行了。

  1. 安装OCIO v2
brew install opencolorio
  1. 等待漫长的安装
  2. 开始计算反LUT
ociobakelut --format resolve_cube --invlut [INPUT.cube] --cubesize 65 [INV.cube]
  1. 好了

更加详细的解释

如果读到了这里,我估计你不会满足于上面的操作。是不是想要了解更多?

  • 这个反LUT 的效果怎么样?
  • OCIO v2 的反LUT 算法是什么?
  • 比起之前自己写的那么多种反向计算LUT 算法,有什么优势?

效果

首先来看反LUT 的效果。这里测试使用的是Sony Slog Sgamut3.cine to Rec709 的官方LUT

OCIOv2_sony_inv.cube

原始原始+官方LUT原始+官方LUT+反LUT
ScreenShot2022-02-07at22.04.56.pngScreenShot2022-02-07at22.05.17.pngScreenShot2022-02-07at22.05.36.png
ScreenShot2022-02-07at22.07.32.pngScreenShot2022-02-07at22.07.37.pngScreenShot2022-02-07at22.07.29.png

简单来说,可用!还不错!操作非常简单!综合性价比高!

具体分析一下的话,首先是肉眼观感,基本上可以做到非常不错的抵消。但是从标准color box 就能看出来问题了,还是对于clamp 或者极度压缩的区域是无法很好的处理。(这本身就是一个 ill problem,原理上无法解决,只能 trick 来逼近)

算法是如何实现的?

OCIO 是开源的,那么所有的答案自然就在他的代码里面了。我们去OpenColorIO 的github 仓库open in new window 看看。

经过一番学习,我目前理解的算法方式如下(还没仔细看,不代表正确)。

参考:OpenColorIO/src/OpenColorIO/ops/lut3d/Lut3DOpCPU.cpp 中的

void InvLut3DRenderer::apply(const void * inImg, void * outImg, long numPixels) const
{...}
	
unsigned long invert_hypercube
(
    unsigned long    n,
    float*           x_out,
    const float*     gr,
    unsigned long*   ind2off,
    float*           val,
    unsigned long*   guess,
    unsigned long    list_len,
    long*            ops_list,
    unsigned long*   entering_list,
    unsigned long*   new_vert_list,
    unsigned long*   path_list,
    unsigned long*   path_order
)
{...}

算法原理

首先LUT 对于整体色彩空间来说,产生的是一种“非均匀的形变”。有点像是橡皮泥一项,可以随意的捏。这里用2D 格子来进行说明。

ScreenShot2022-02-07at22.51.20.png

但是对于4号小格子来说,由于LUT 的精度限制,所以可以认为一个小格子只能发生仿射变换

ScreenShot2022-02-07at22.54.10.png

好了,当出现“仿射变换”的时候,线性代数就告诉我们,问题就比较好解决了。整个求反向LUT 的大问题就被拆解成了两个小问题:

  1. 如何找到重新采样的晶格顶点,属于哪个格子?
  2. 如何对一个小格子求解仿射变换的逆变换?

重新采样的晶格顶点属于哪个格子?

如何确定重新采样的晶格顶点,属于形变后哪个格子?

我们还是画图来看。对于LUT 变换后的色彩空间重新进行均匀的顶点采样,可以看到重新采样的3号格子的右下角顶点,落在了变换前的4号格子内。

ScreenShot2022-02-07at23.04.28.png

这里有很多技巧可以优化查找速度,不过最粗暴的方法就是进行遍历!由于LUT 只需要生成一次,所以即使慢也没有什么太大的关系。

仿射变换的逆变换

当确定3号格子的右下角晶格点属于原先的4号格子后,我们就需要进行逆变换。计算出晶格点对应原始空间的坐标。

ScreenShot2022-02-07at23.11.49.png

这个空间坐标就是反向LUT 对应的数值!

算法的一些问题

很明显这个算法的性能很好,这符合OCIO 对于实时处理的需求。不过也存在几个问题:

  • 如果小格子被压缩成为一条线?也就是仿射变换矩阵的秩 = 0,那么就没有逆矩阵了(可以求伪逆)。在LUT 边缘处很容易出现这个问题
  • 重新采样的一个格子,对应的顶点,往往会属于多个变换前的格子。仅仅对于每个顶点求解逆变换,并不是该格子内部所有点的最优解。

和其他反向算法比起来?

我也写过好几种不同的反向计算LUT 的算法了。由于OCIO v2 的反向算法也是完全无需人工干预的,所以这里就不和 色彩匹配算法(3D Thin-Plate Spline)比较了,主要和利用机器学习的梯度下降算法进行比较。

还是先说结论:

对比项目OCIO v2 算法梯度下降算法
肉眼感官✅ 优秀✅ 优秀
数值精度✅ 中心区域优秀 ⚠️ 边缘range稍优于梯度下降✅ ✅ 中心区域更优秀 ❌ 边缘抖动|
计算速度✅ 很快(秒级)❌ 很慢(半天级别)
实现难度✅ 无需自己实现❌ 自己实现门槛高
操作难度✅ 安装即用❌ 要敲代码,或者封装

从上面来看,综合性价比最好的选择就不用我说了吧……

总结

你觉得命令行操作依旧很麻烦?

如果你有安装nuke 13.1 以上的版本,就会发现nuke 内嵌的OCIO 已经是2.0 版本啦,那么反向LUT 的操作甚至可以直接在软件内的OCIO FileTransform 节点中进行操作!

ScreenShot2022-02-07at23.27.10.png

不过经过对比,发现这种方法得到的效果和使用ociobakelut 生成LUT 的方法有一些区别

目前比较值得怀疑的点是 OCIO 提供了 OPTIMIZATION_LOSSLESSOPTIMIZATION_LUT_INV_FAST 两种模式,nuke 在软件内追求速度,所以使用了FAST 模式;而ociobakelut 命令行不关心速度,就使用了INV_EXACT 模式

Andy 泪目

曾经的知识,在新的科技面前,变得好像没什么了不起了 😭

参考阅读:

温馨提示

现在有 Andy 十分钟色彩科学合集售卖open in new window

十分钟色彩科学面包多二维码

购买后加微信muyanru345,拉入Andy 铁粉儿群,可在群里对学习工作中的色彩疑问进行讨论。

上次编辑于:
贡献者: muyanru