Transformação de cores: pesquisas de tabela de desbaste

Esta é uma visão geral da funcionalidade introduzida no Pillow 5.2 : o uso de tabelas de pesquisa tridimensionais (3D LUTs) para transformação de cores. Essa técnica é difundida em processamento de vídeo e jogos 3D, mas poucas bibliotecas gráficas podem se orgulhar de transformações 3D LUT antes disso.


As tabelas de pesquisa tridimensionais fornecem grande flexibilidade na descrição das transformações de cores, mas o mais importante é que as transformações são executadas ao mesmo tempo, não importa quão complexas sejam.


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))

Um recurso totalmente escrito em Python se aplica a uma imagem de 16,6 megapixels em 75ms.



Trabalhar com imagens já consome muitos recursos, por isso adoro algoritmos que removem a complexidade dos parâmetros de entrada. Há cinco anos, implementei um borrão gaussiano no Pillow , trabalhando ao mesmo tempo em qualquer raio. Há pouco tempo, falei sobre como você pode reduzir a imagem em tempo constante com perda mínima de qualidade. Hoje vou mostrar para quais tarefas você pode usar o 3D LUT, quais são suas limitações e se orgulhar do desempenho alcançado no Pillow-SIMD.


Faça normalmente - não será normal


: , . - , ( 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 .



? — . , , ( ) .


, , . , , , . , .


3D LUT


, - . : , , , , . . . , -, . .


: , , , . , , .


, , . , , , . , . , , , - ( , ) .


?


, 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 , . .



Como pode ser visto nos resultados do teste, a transformação de cores no Pillow é mais rápida que as soluções existentes e, com o uso das instruções SIMD, voa para o espaço. Devo dizer que isso ainda pode ser mais lento do que uma implementação bem otimizada de um número bastante grande de transformações que poderiam ser escritas em C. Mas do lado das tabelas de pesquisa, versatilidade, simplicidade e tempo estável, independentemente do número e da complexidade das transformações. Uma API simples permite que você comece a usar rapidamente as transformações de cores, e uma biblioteca especial Pillow-lut facilita ainda mais o trabalho.


All Articles