web-dev-qa-db-fra.com

Convertir une image RGB-> Lab avec python

Quelle est la méthode préférée pour effectuer la conversion à l'aide de PIL/Numpy/SciPy aujourd'hui?

31
Antony Hatchkins

Depuis 2010, lorsque la question liée a été posée, le code correspondant a été déplacé de scipy vers une boîte à outils distincte: http://scikit-image.org/

Voici donc le code que je cherchais:

from skimage import io, color
rgb = io.imread(filename)
lab = color.rgb2lab(rgb)

Il convient également de noter qu'en raison de Lab nature srgb-> la conversion de laboratoire dépend d'un paramètre supplémentaire: whitepoint, par exemple:
Photoshop utilise un point blanc appelé D50 (qui est une norme pour icc)
OpenCV et skimage utilisent D65 (qui est une norme pour srgb).
• implémentation par défaut Matlab utilise D50 (il est capable d'utiliser autres ),

Cette belle FAQ l'explique de cette façon:

Vous devez utiliser D65 sauf si vous avez une bonne raison d'utiliser autre chose.
L'industrie de l'impression utilise couramment le D50 et la photographie utilise généralement le D55.
.

Vous pouvez savoir à quel point blanc vous avez affaire en convertissant RVB (0,0,255) au laboratoire:
• D50 vous donnerait (30, 68, -112)
• D55 (30, 73, -110)
• D65 (32, 79, -108)

Les chiffres après "D" correspondent à la température de couleur utilisée (en interne) du point blanc: D50 = 5003 K (jaunâtre), D65 = 6504 K (bleuâtre)

Je suis reconnaissant à Alex et Roman pour leurs réponses car ils m'ont indiqué la bonne direction.

53
Antony Hatchkins

J'ai trouvé ce code sur l'ancien site Adobe Cookbook et je me suis adapté pour Python. Il ne nécessite aucun module ou composant tiers:

def rgb2lab ( inputColor ) :

   num = 0
   RGB = [0, 0, 0]

   for value in inputColor :
       value = float(value) / 255

       if value > 0.04045 :
           value = ( ( value + 0.055 ) / 1.055 ) ** 2.4
       else :
           value = value / 12.92

       RGB[num] = value * 100
       num = num + 1

   XYZ = [0, 0, 0,]

   X = RGB [0] * 0.4124 + RGB [1] * 0.3576 + RGB [2] * 0.1805
   Y = RGB [0] * 0.2126 + RGB [1] * 0.7152 + RGB [2] * 0.0722
   Z = RGB [0] * 0.0193 + RGB [1] * 0.1192 + RGB [2] * 0.9505
   XYZ[ 0 ] = round( X, 4 )
   XYZ[ 1 ] = round( Y, 4 )
   XYZ[ 2 ] = round( Z, 4 )

   XYZ[ 0 ] = float( XYZ[ 0 ] ) / 95.047         # ref_X =  95.047   Observer= 2°, Illuminant= D65
   XYZ[ 1 ] = float( XYZ[ 1 ] ) / 100.0          # ref_Y = 100.000
   XYZ[ 2 ] = float( XYZ[ 2 ] ) / 108.883        # ref_Z = 108.883

   num = 0
   for value in XYZ :

       if value > 0.008856 :
           value = value ** ( 0.3333333333333333 )
       else :
           value = ( 7.787 * value ) + ( 16 / 116 )

       XYZ[num] = value
       num = num + 1

   Lab = [0, 0, 0]

   L = ( 116 * XYZ[ 1 ] ) - 16
   a = 500 * ( XYZ[ 0 ] - XYZ[ 1 ] )
   b = 200 * ( XYZ[ 1 ] - XYZ[ 2 ] )

   Lab [ 0 ] = round( L, 4 )
   Lab [ 1 ] = round( a, 4 )
   Lab [ 2 ] = round( b, 4 )

   return Lab
19
Roman Nazarkin

Modifier: exemple de code pyCMS:

from PIL import Image
import pyCMS
im = Image.open(...)
im2 = pyCMS.profileToProfile(im, pyCMS.createProfile("sRGB"), pyCMS.createProfile("LAB"))

Edit: Pillow, la fourche PIL, semble avoir pyCMS intégré.

Vous pouvez utiliser pyCMS ( http://www.cazabon.com/pyCMS/ ) qui fonctionne avec les images PIL.

Si la vitesse n'est pas un facteur, utilisez python-colormath ( http://code.google.com/p/python-colormath/ ).

7
Alex I