十分钟色彩科学:LUT 的前世今生
泼辣修图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 的根本作用就是查找。
举个例子,当遇到不认识的单词的时候,大家都会翻字典。字典就是一个巨大的查找表:
因此查找的本质含义就是:给定一个输入的值,返回给你一个对应的输出值。
1D LUT
1D LUT 的本质就是一维空间内的查找表。
什么是一维空间?就是说,你的输入值只能是一个变量,不能是好几个。(字典就是1D LUT,因为每次你只能给他一个单词,而不能给出多个单词的组合。PS:别说英文有词组…… 科普文章嘛~)。
更加抽象的来看,就是你只能输入一个变量x,得到一个结果y。
拿上面的图像来说,就可以当做一个1D LUT。
这个LUT 中有4个数据点:
输入 | 输出 |
0 | 0 |
1 | 0.5 |
2 | 1.4 |
3 | 1.5 |
只要我给出一个输入值,那么就可以查到一个对应的输出值。是不是和查字典很像?
2D LUT
2D LUT 本质上就是二维查找表。就是说,你输入两个不相关的变量,就会得到相应的输出。比方说,我们的输入一组坐标(x, y),会得到一个高度数值。
输入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 来举例子:
我可以准确的知道输入为0,1,2,3 时候,对应的输出值是多少。但是中间的数值是多少呢?比方说,输入x = 0.3 的时候,输入y 应该是多少?
LUT 中明确的数据点叫做Lattice (有人会翻译成晶格点),LUT 的精度缺陷就是由这个造成的。那么如何提高LUT 的精度呢?目前有两种方法:
- 给出更多的lattice,也就是更多的数据,让晶格点之间的间距缩小。
- 使用插值算法来获得lattice 之间的部分。
第一种做法是非常野蛮粗暴的。
我们说的1024阶 的1D LUT 或者65阶的3D LUT 都是表示的某个维度上的晶格数量。就算你有1024个点,我肯定可以再找到两个晶格点之间的缝隙。
而且一味的提高晶格点的数量,还会快速的增加计算机的负担。对于常用的3D LUT,计算量是成三次方增长的,比方说一个64x64x64 的3D LUT 只比32x32x32 的3D LUT 精度上提高了一倍,但是计算量却是增加了8 倍。所以这个方法不是特别的好(但是的确有软件就是这么干的……)
第二种方法就是通过插值。很多人肯定早就想到了。但是问题又来了,插值的本质是“猜”。那么猜的方法就各式各样了:
猜的方法千千万,万变不离其宗。最重要的三种方式:
- step 插值(阶跃):好像台阶一样。在到达下一个晶格点之前都保持当前的数值。很明显,这种插值……效果有点差。但是计算速度是很快的。
- linear 插值(线性):在晶格点之间用直线连接。看起来还可以,有个重大的缺点就是每个晶格点两端是个折角,不平滑。
- cubic 插值(曲线):有非常多的高阶插值方式可以实现这种平滑的曲线插值。这里主要使用最常见的cubic 三次曲线插值。得到了一条平滑的曲线,计算的速度也还可以。
这时候千万不要被“选择哪种插值方式最好”给迷惑进去了,不论选择哪种插值方式都是“猜测”,而且不同的“猜测” 方式还会出现不同的结果。
比方说对于上面的图像:如果x = 1.5 的时候
step 插值后 y=0.5
linear 插值后 y=0.95
cubic 插值后 y≈1.05
所以也只是折中的方式。
LUT 范围
除了精度,LUT 还有一个重大的问题,范围!
还是这个图片,如果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 就出现了一些问题:
- 难以建立系统的色彩管理体系
- LUT 的范围只有0-1
- 3D LUT 的精度不够(大多数为65 阶)
我这里稍微列举了几个常用的色彩空间,当我们需要所有色彩空间之间都可以任意转换,需要LUT 的数量就非常可观了……
假设如果有20种常用的色彩空间,那么需要的LUT 数量就是 19+18+...+2+1 = 190,而且由于任意两个色彩空间转换都存在正反两个LUT ,所以上面的190 个LUT 还要再乘以2。最终的总量是210*2 = 380!麻烦的要死啦!
那问题来了,不用 LUT,我们用什么来实现/实践 ACES 呢?
(OCIO是一个简单快捷的实现方式,但其本质是使用 LUT,所以......。以后可能会单独更新,嗯,可能会。)
使用纯数学的方式实现 ACES
优势非常明显
- 纯粹的数学,理论上是无限的精度
- 正反变换,理论上完全无损(实际上会受到浮点数计算精度的制约,不过依旧远远小于LUT)
- 电脑计算的很快
- 可以更加有效的实现系统的色彩管理
我们还来看看上面的那个例子。
假设有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
Davinci Resolve
某些自制软件
有了这个图片,就可以得到色彩变换的结果了。这是什么原理呢?
这张HALD 图片其实就是将一个方盒子等分切成更多的小方块后,每个交点处对应的标准色彩数值。然后,把这个“标准”图片送入处理。经过处理之后,图片的颜色肯定发生了一些改变,只需要记录变化后每个像素对应的RGB 数值,然后写入一个特定格式LUT 文件中就搞定了!
(点开看大图也不知道会不会清晰点)
说到这里,肯定有人已经想到了利用这个方式去得到各种LUT(手机APP 相片处理的风格、其他人调色的风格……) 这就是大部分软件生成LUT 的方法。
上面的方法多种多样,但是总的来说都是lattice 晶格算法。这种方法只能得到比标准box 体积小的查找,有诸多的限制。
...Andy炫技的分割线...
但是还有一个核弹级别的方法。由于这个方法实在是太过于bug,不能公开。有点像武侠小说里面的绝世武功秘籍,万一被学了去,根基不足者可能会走火入魔。
有了他你可以做到:
- 只有两张图片,不需要标准色彩图HALD,就能够得到高精度的LUT(而且不会出现LUT 色域狭窄的问题)
- 可以高精度的计算任意LUT 的反LUT(甚至可以得到原来LUT 不存在的范围,当然也是插值,不过精度还不错)
- 在生成LUT 的时候,可以抵御一部分噪点、锐化引起的局部色彩突变(不会出现LUT 跳变)
- 算法完全摒弃晶格插值算法,通过计算整体色彩空间的非线性变化趋势,从而得到LUT 的晶格点
- 理论上可以生成任意范围的LUT(不过目前为了兼容性,采用的cube 格式是0-1之间的)
偷偷漏一点
原始的“图像” ↑↑↑
实际变换后的“图像” ↑↑↑
挂工具生成的LUT的“图像” ↑↑↑
(Andy已得到满足,没看懂也不要深究了)
结束语
LUT 作为一个重要的色彩工具来说,估计永远不会消失。而且随着色彩引擎的更新,相信未来支持更大范围的LUT 也会成为稀松平常的事情。虽然LUT 好用,但是如果认为LUT 可以做任何事情,并且只要有了LUT 就一劳永逸,这种想法还是稍微更正一下的好。毕竟大部分情况下LUT 是数学计算过程的一个采样而已。
Andy的苦口婆心:
不要过分的信仰LUT,也不要排斥LUT。
不要用LUT 窃取别人的色彩,多多磨炼自己的调色技法。
让LUT 成为你的奴隶,而不要变成LUT 的奴隶……
最后,我爱数学,数学使我快乐?
《十分钟色彩科学》目录