转自:https://www.sohu.com/a/231410657_252971

十分钟色彩科学:LUT 的前世今生 

2018-05-12 22:00

泼辣修图5.0的发布让LUT这个词密集曝光,泼辣修图之前曾专门推出文章《看似高深的LUT,原来如此简单!》,为了从更专业的角度来告诉你关于LUT到底是什么?小辣为大家特别推出这篇LUT前世今生,经作者授权转载。

小编:长文预警!!非战斗人员迅速撤离!!

本文大纲

  • LUT 是什么
  • 1D LUT
  • 2D LUT
  • 3D LUT
  • LUT 的优势
  • LUT 的劣势
  • LUT 精度
  • LUT 范围
  • LUT vs ACES
  • 纯数学方式实现 ACES
  • LUT 的制作
  • 结束语

LUT 这个名词对于很多人来说,有点向往,甚至说是信仰一样的存在。

有了LUT 就可以让调色变得简单漂亮。

有了LUT 就可以随意的输出各种的色彩空间。

有了LUT 就好像拥有了和色彩相关的一切……

LUT 是什么

LUT 的全称是 Lookup Table,中文名为“查找表”。

从名字可以看出,LUT 的根本作用就是查找。

举个例子,当遇到不认识的单词的时候,大家都会翻字典。字典就是一个巨大的查找表:

lua颜色值 lut色彩还原_lua颜色值

因此查找的本质含义就是:给定一个输入的值,返回给你一个对应的输出值。

1D LUT

1D LUT 的本质就是一维空间内的查找表。

什么是一维空间?就是说,你的输入值只能是一个变量,不能是好几个。(字典就是1D LUT,因为每次你只能给他一个单词,而不能给出多个单词的组合。PS:别说英文有词组…… 科普文章嘛~)。

更加抽象的来看,就是你只能输入一个变量x,得到一个结果y。

lua颜色值 lut色彩还原_插值_02

拿上面的图像来说,就可以当做一个1D LUT。

这个LUT 中有4个数据点:

输入

输出

0

0

1

0.5

2

1.4

3

1.5

只要我给出一个输入值,那么就可以查到一个对应的输出值。是不是和查字典很像?

2D LUT

2D LUT 本质上就是二维查找表。就是说,你输入两个不相关的变量,就会得到相应的输出。比方说,我们的输入一组坐标(x, y),会得到一个高度数值。

lua颜色值 lut色彩还原_lua颜色值_03

输入x

输入y

输出

0

0

2.57781

0

1

3.21666

0

2

2.95918

……

……

……

3D LUT

本质上3D LUT 就是三维的查找表,你可以输入三个不相关的变量,得到一个输出值。

放到色彩空间中,就是你给一组RGB 的数值,然后色彩3D LUT 就会返回给你一组新的RGB 数值。这就是颜色发生变化的根本原因。

3D LUT 的厉害之处就在于可以体现R、G、B 三个通道之间的关系,并非简单的单一通道进行查找变化。我最喜欢的一个例子来区分1D、3D LUT 就是:

『 3D LUT 可以让你把一张纯绿的图片变成红色,但是1D LUT 永远做不到』

LUT 的优势

不论是1D、2D、3D LUT,他们的本质都是查找,所以LUT 都具备以下的优势:

  • 非常的直观,给定输入,就会得到对应的输出
  • 悠久的历史传承
  • 其实是个文本文件,所以总让人觉得很亲切
  • 感觉很魔法,只要拥有了某种LUT,就会得到一种风格。调色轻松又惬意!
  • 可以隐藏某些调色技巧,让别人只能知道结果,而无法知道调色的手法
  • 便于传播和使用。基本上所有的软件都会用某些方式支持LUT,从而使得LUT 的用户基础非常大。

LUT 的劣势

LUT 作为很多人心中的圣经,依旧会有一些劣势。

这些劣势你觉得无所谓就会微乎其微,你要是在意,那么也会是非常严重的问题。

LUT 精度

LUT 有个天生的缺点,就是精度。

因为是查找表,所以只能给出一对对固定的输入和输出。

简单来说还是那1D LUT 来举例子:

lua颜色值 lut色彩还原_插值_04

我可以准确的知道输入为0,1,2,3 时候,对应的输出值是多少。但是中间的数值是多少呢?比方说,输入x = 0.3 的时候,输入y 应该是多少?

LUT 中明确的数据点叫做Lattice (有人会翻译成晶格点),LUT 的精度缺陷就是由这个造成的。那么如何提高LUT 的精度呢?目前有两种方法:

  1. 给出更多的lattice,也就是更多的数据,让晶格点之间的间距缩小。
  2. 使用插值算法来获得lattice 之间的部分。

第一种做法是非常野蛮粗暴的。

我们说的1024阶 的1D LUT 或者65阶的3D LUT 都是表示的某个维度上的晶格数量。就算你有1024个点,我肯定可以再找到两个晶格点之间的缝隙。

而且一味的提高晶格点的数量,还会快速的增加计算机的负担。对于常用的3D LUT,计算量是成三次方增长的,比方说一个64x64x64 的3D LUT 只比32x32x32 的3D LUT 精度上提高了一倍,但是计算量却是增加了8 倍。所以这个方法不是特别的好(但是的确有软件就是这么干的……)

第二种方法就是通过插值。很多人肯定早就想到了。但是问题又来了,插值的本质是“猜”。那么猜的方法就各式各样了:

lua颜色值 lut色彩还原_色彩空间_05

猜的方法千千万,万变不离其宗。最重要的三种方式:

  1. step 插值(阶跃):好像台阶一样。在到达下一个晶格点之前都保持当前的数值。很明显,这种插值……效果有点差。但是计算速度是很快的。
  2. linear 插值(线性):在晶格点之间用直线连接。看起来还可以,有个重大的缺点就是每个晶格点两端是个折角,不平滑。
  3. cubic 插值(曲线):有非常多的高阶插值方式可以实现这种平滑的曲线插值。这里主要使用最常见的cubic 三次曲线插值。得到了一条平滑的曲线,计算的速度也还可以。

这时候千万不要被“选择哪种插值方式最好”给迷惑进去了,不论选择哪种插值方式都是“猜测”,而且不同的“猜测” 方式还会出现不同的结果。

比方说对于上面的图像:如果x = 1.5 的时候

step 插值后 y=0.5

linear 插值后 y=0.95

cubic 插值后 y≈1.05

所以也只是折中的方式。

LUT 范围

除了精度,LUT 还有一个重大的问题,范围!

lua颜色值 lut色彩还原_3D_06

还是这个图片,如果x < 0 或者x > 3 的时候,会出现什么数值呢?

大部分的LUT 格式都是默认0-1 的范围,在这个范围内可以随意的进行查找。那个时候0-1 的范围已经足够了,所以渐渐的,大家都把3D LUT 形象的比作一个1x1x1 的方盒子。但是随着各种 HDR 的出现,越来越多的数值会在 0-1 之外。

那么LUT 怎么办呢?

这时候就看你的运气了。为什么这么说?

因为超过范围的数值,要看色彩引擎是如何插值的。

老年间的色彩引擎只会统统裁切!超过范围的数值就按照边界处的数值处理;好一点的色彩引擎会根据边缘数据的“趋势” 猜出一个插值曲线,然后得到插值后的数值。

不过一说到“插值”,就回到了上一个缺点中,不同插值的方式会得到不同的结果,从而造成精度的下降。

现代的色彩引擎甚至可以支持任意范围的LUT,但是说到底,因为LUT 本身总是有个最大值,于是我还是可以找到比这个最大值还要大的数值……

(这里稍微给LUT 点机会,毕竟人眼的分辨力都是有限的,所以对于制作来说,比较高的精度和能够超过1 的范围,有这两点的话,LUT 还是可以继续战斗下去的!)

【你说为什么以前LUT 的范围都够用?回顾一下关于linear 的讨论,那时候都是尽可能使用log编码的方式,在0-1之间尽可能多的存入人眼敏感的信息,log 的编码基本上都控制在0-1之间,因此LUT 使用0-1 的范围也就无可厚非了】

LUT vs ACES

“LUT 已经足够了,干嘛还需要ACES?”

这个是在ACES 推广的过程中听到最多的话。

『 LUT 只是实现色彩管理的一个手段,和ACES 并不冲突』

理论上LUT 可以完成各种色彩转换,但是当实际生产中色彩管理变得越来越复杂的时候,LUT 就出现了一些问题:

  1. 难以建立系统的色彩管理体系
  2. LUT 的范围只有0-1
  3. 3D LUT 的精度不够(大多数为65 阶)

lua颜色值 lut色彩还原_色彩空间_07

我这里稍微列举了几个常用的色彩空间,当我们需要所有色彩空间之间都可以任意转换,需要LUT 的数量就非常可观了……

假设如果有20种常用的色彩空间,那么需要的LUT 数量就是 19+18+...+2+1 = 190,而且由于任意两个色彩空间转换都存在正反两个LUT ,所以上面的190 个LUT 还要再乘以2。最终的总量是210*2 = 380!麻烦的要死啦!

那问题来了,不用 LUT,我们用什么来实现/实践 ACES 呢?

(OCIO是一个简单快捷的实现方式,但其本质是使用 LUT,所以......。以后可能会单独更新,嗯,可能会。)

使用纯数学的方式实现 ACES

优势非常明显

  • 纯粹的数学,理论上是无限的精度
  • 正反变换,理论上完全无损(实际上会受到浮点数计算精度的制约,不过依旧远远小于LUT)
  • 电脑计算的很快
  • 可以更加有效的实现系统的色彩管理

lua颜色值 lut色彩还原_插值_08

我们还来看看上面的那个例子。

假设有20个色彩空间,需要实现他们之间的色彩管理。

如果使用ACES AP0 作为公用的色彩空间,那么只需要20+20 = 40 个色彩转换公式就好。第一个20,表示所有的色彩空间如何转换到AP0,第二个20,表示AP0 如何转换到这些色彩空间。远远小于420 个LUT 的数量。而且当色彩空间越来越多的时候,这个优势会越来越明显。

由于是数学公式,所以几乎不存在范围的限制。

假设有个色彩转换公式是 y = pow(x, 2.2),当输入的x 超过1 的时候,依旧可以使用2.2 次方,得到对应的y。不存在0-1 之间的限制了,甚至是负数都可以!

同时,理论上数学公式的精度是无限的。

无论数字如何细分,总可以找到他们之间更细分的数,然后依旧可以带入公式,得到相对应的结果。

LUT 的制作

很多人停留在到处找LUT 的阶段,我个人也曾经痴迷于收集各种LUT。(但是渐渐的你会发现,一个好的审美和对软件的熟悉会让你不用LUT 依旧可以创造出很多好的风格。)

那么如何利用图像 制(提)作(取)LUT呢?

有非常多的软件可以完成这个事情,有专业的、也有一些小工具:

  • Davinci Resolve
  • Nuke
  • LUT Generator
  • 3D LUT Creator
  • ……

但是这些软件大多数都是需要一个标准色彩图(HALD)。看起来可能各式各样:

Nuke

lua颜色值 lut色彩还原_3D_09

Davinci Resolve

lua颜色值 lut色彩还原_lua颜色值_10

某些自制软件

有了这个图片,就可以得到色彩变换的结果了。这是什么原理呢?

这张HALD 图片其实就是将一个方盒子等分切成更多的小方块后,每个交点处对应的标准色彩数值。然后,把这个“标准”图片送入处理。经过处理之后,图片的颜色肯定发生了一些改变,只需要记录变化后每个像素对应的RGB 数值,然后写入一个特定格式LUT 文件中就搞定了!

lua颜色值 lut色彩还原_色彩空间_11

(点开看大图也不知道会不会清晰点)

说到这里,肯定有人已经想到了利用这个方式去得到各种LUT(手机APP 相片处理的风格、其他人调色的风格……) 这就是大部分软件生成LUT 的方法。

上面的方法多种多样,但是总的来说都是lattice 晶格算法。这种方法只能得到比标准box 体积小的查找,有诸多的限制。

...Andy炫技的分割线...

但是还有一个核弹级别的方法。由于这个方法实在是太过于bug,不能公开。有点像武侠小说里面的绝世武功秘籍,万一被学了去,根基不足者可能会走火入魔。

有了他你可以做到:

  • 只有两张图片,不需要标准色彩图HALD,就能够得到高精度的LUT(而且不会出现LUT 色域狭窄的问题)
  • 可以高精度的计算任意LUT 的反LUT(甚至可以得到原来LUT 不存在的范围,当然也是插值,不过精度还不错)
  • 在生成LUT 的时候,可以抵御一部分噪点、锐化引起的局部色彩突变(不会出现LUT 跳变)
  • 算法完全摒弃晶格插值算法,通过计算整体色彩空间的非线性变化趋势,从而得到LUT 的晶格点
  • 理论上可以生成任意范围的LUT(不过目前为了兼容性,采用的cube 格式是0-1之间的)

偷偷漏一点

lua颜色值 lut色彩还原_色彩空间_12

lua颜色值 lut色彩还原_色彩空间_13

lua颜色值 lut色彩还原_3D_14

原始的“图像” ↑↑↑

lua颜色值 lut色彩还原_插值_15

实际变换后的“图像” ↑↑↑

挂工具生成的LUT的“图像” ↑↑↑

(Andy已得到满足,没看懂也不要深究了)

结束语

LUT 作为一个重要的色彩工具来说,估计永远不会消失。而且随着色彩引擎的更新,相信未来支持更大范围的LUT 也会成为稀松平常的事情。虽然LUT 好用,但是如果认为LUT 可以做任何事情,并且只要有了LUT 就一劳永逸,这种想法还是稍微更正一下的好。毕竟大部分情况下LUT 是数学计算过程的一个采样而已。

Andy的苦口婆心:

不要过分的信仰LUT,也不要排斥LUT。

不要用LUT 窃取别人的色彩,多多磨炼自己的调色技法。

..

《十分钟色彩科学》目录