Transformation des couleurs: recherches dans les tables d'éclaircie

Il s'agit d'un aperçu des fonctionnalités introduites dans Pillow 5.2 : l'utilisation de tables de recherche tridimensionnelles (LUT 3D) pour la transformation des couleurs. Cette technique est répandue dans le traitement vidéo et les jeux 3D, mais peu de bibliothèques graphiques pouvaient se vanter de transformations 3D LUT avant cela.


Les tables de recherche tridimensionnelles offrent une grande flexibilité dans la description des transformations de couleur, mais surtout, les transformations sont effectuées en même temps, quelle que soit leur complexité.


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

Une fonctionnalité entièrement écrite en Python s'applique à une image de 16,6 mégapixels en 75 ms.



Travailler avec des images est déjà gourmand en ressources, donc j'aime les algorithmes qui suppriment la complexité des paramètres d'entrée. Il y a cinq ans, j'ai implémenté un flou gaussien chez Pillow , travaillant en même temps pour n'importe quel rayon. Il n'y a pas si longtemps, j'ai expliqué comment réduire l'image en un temps constant avec une perte de qualité minimale. Aujourd'hui, je vais vous montrer pour quelles tâches vous pouvez utiliser 3D LUT, quelles sont ses limites et je me vante des performances obtenues dans Pillow-SIMD.


Faites-le normalement - ce ne sera pas 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 , . .



Comme le montrent les résultats des tests, la transformation des couleurs dans Pillow est plus rapide que les solutions existantes, et avec l'utilisation d'instructions SIMD s'envole dans l'espace. Je dois dire que cela peut encore être plus lent qu'une implémentation bien optimisée d'un assez grand nombre de transformations qui pourraient être écrites en C. Mais du côté des tables de recherche, polyvalence, simplicité et temps stable, quels que soient le nombre et la complexité des transformations. Une API simple vous permet de commencer rapidement à utiliser les transformations de couleurs, et une bibliothèque spéciale Pillow-lut facilite encore plus le travail.


All Articles