这是Pillow 5.2中引入的功能的概述:使用三维查找表(3D LUT)进行颜色转换。这项技术在视频处理和3D游戏中非常普遍,但是在此之前很少有图形库可以吹嘘3D LUT转换。
三维查找表为描述颜色转换提供了极大的灵活性,但是最重要的是,转换无论在多么复杂的情况下都可以同时执行。
from PIL import Image, ImageFilter
def washout(r, g, b):
h, s, v = _rgb_to_hsv(r, g, b)
if 0.3 < h < 0.7:
s = 0
return _hsv_to_rgb(h, s, v)
im = Image.open('./Puffins.jpg')
im = im.filter(ImageFilter.Color3DLUT.generate(17, washout))
完全用Python编写的功能可在75ms内应用于16.6百万像素的图片。

使用图像已经占用大量资源,因此我喜欢可以消除输入参数复杂性的算法。五年前,我在Pillow上实现了高斯模糊,同时在任何半径下工作。不久前,我谈到了如何在恒定时间内以最小的质量损失来缩小图像。今天,我将向您展示可以使用3D LUT执行哪些任务,其局限性是什么,并且我在吹嘘Pillow-SIMD所实现的性能。
正常进行-这不正常
: , . - , ( 0 255). , HSV , Hue, , , Saturation, , , Value, . , , Saturation - , . .
? , , . - , , . API, , , , . .
, , . , , , . , : , , , . API — .
- . , . , , , . , , - !
, . . , , RGB #e51288
, [229, 18, 136]. — , RGB-. :
. 256³, 16 , 48 . 48 — . , L3 , . , 16 , 16 , , , . ?
, . , -- , . , , , 16³ . 12 , L3, L1 .
? — . , , ( ) .
, , . , , , . , .
, - . : , , , , . . . , -, . .
: , , , . , , .
, , . , , , . , . , , , - ( , ) .
?
, Pillow. API Color3DLUT
PIL.ImageFilter
. , :
from PIL.ImageFilter import Color3DLUT
table = [(0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0),
(0, 0, 1), (1, 0, 1), (0, 1, 1), (1, 1, 1)]
lut = Color3DLUT(2, table)
— . , . :
from PIL import Image
Image.open('in.jpg').filter(lut).save('out.jpg')
, . - , :

— - , generate
, . , . 3D-.
def transform(r, g, b):
r, g, b = (max(r, g, b), g, min(r, g, b))
avg_v = r * 0.2126 + g * 0.7152 + b * 0.0722
r += (r - avg_v) * 0.6
g += (g - avg_v) * 0.6
b += (b - avg_v) * 0.6
return r, g, b
lut = Color3DLUT.generate(17, transform)
Image.open('in.jpg').filter(lut).save('out.jpg')


- , . : - , . , . Pillow-lut. rgb_color_enhance
, :
from pillow_lut import rgb_color_enhance
lut = rgb_color_enhance(
11, exposure=1, contrast=0.3, vibrance=-0.2, warmth=0.3)
Image.open('in.jpg').filter(lut).save('out.jpg')


, , ? : .cube ( , ) hald- — , .
Pillow-lut .
from pillow_lut import load_hald_image
lut = load_hald_image('hald.6.hefe.png')
Image.open('in.jpg').filter(lut).save('out.jpg')


— , , ! , , . rgb_color_enhance
, , :
lut = load_hald_image('hald.6.hefe.png')
lut = rgb_color_enhance(
lut, exposure=1, contrast=0.3, vibrance=-0.2, warmth=0.3)
Image.open('in.jpg').filter(lut).save('out.jpg')


, . rgb_color_enhance
. transform_lut
, .
, «». ? . , 1, , — . . amplify_lut
:
from pillow_lut import load_hald_image, amplify_lut
lut = load_hald_image('hald.6.hefe.png')
lut = amplify_lut(lut, scale=3.0)
Image.open('in.jpg').filter(lut).save('out.jpg')


: , . , ? , ( . : ).
, Pillow 5.2 16- ( ). , . 16- .
, 7 . 21 . , , . , ( 6 ), 2,5 , , . , SIMD-.
. ImageMagick GraphicsMagick. — LittleCMS — icc- . , , . , perf
, PrelinEval8
, , .

Intel Core i5-8279U.
Pillow-SIMD — Pillow, x86 . 100% Pillow . , , , Pillow 5.4, Pillow-SIMD 7.0. Pillow , . .
从测试结果可以看出,Pillow中的颜色转换比现有解决方案要快,并且使用SIMD指令可以飞向太空。我必须说,这仍然比对可以用C编写的大量转换进行优化的实现慢。但是,在搜索表方面,无论转换的数量和复杂性如何,通用性,简单性和稳定的时间。一个简单的API可让您快速开始使用颜色转换,而特殊的Pillow-lut库则使工作变得更加轻松。