Commits

Robert Kern  committed 95fb58b

Add some color distance functions.

  • Participants
  • Parent commits a181b45

Comments (0)

Files changed (1)

File colormap_explorer/color_distance.py

+""" Models of color distances.
+
+Each model is just a callable that takes an array of XYZ tristimulus values (D65
+whitepoint), and returns the distance, in the model's units, between each color.
+Implementations which need external information should be classes with
+a __call__ method of this interface.
+
+def model(xyz):
+    '''
+    Parameters
+    ----------
+    xyz : float array (n, 3)
+
+    Returns
+    -------
+    distances : float array (n-1,)
+    '''
+"""
+
+# Major library imports.
+import numpy as np
+
+# Enthought library imports.
+from enthought.traits.api import HasTraits
+
+# Local imports.
+import conversion
+
+
+def Luv_distance(xyz):
+    """ Return the Euclidean distances between colors in L*u*v* space.
+    """
+
+    luv = conversion.xyz2luv(xyz)
+    diff = luv[1:] - luv[:-1]
+    distances = np.sqrt((diff*diff).sum(axis=-1))
+
+    return distances
+
+
+def Lab_distance(xyz):
+    """ Return the Euclidean distances between colors in L*a*b* space.
+    """
+
+    lab = conversion.xyz2lab(xyz)
+    diff = lab[1:] - lab[:-1]
+    distances = np.sqrt((diff*diff).sum(axis=-1))
+
+    return distances
+
+
+def Ljg_distance(xyz):
+    """ Return the Euclidean distances between colors in the OCA UCS Ljg
+    colorspace.
+    """
+
+    # Calculate the chromaticity coordinates (x, y).
+    X, Y, Z, axis = separate_colors(xyz, axis=-1)
+    black = (X+Y+Z) == 0.0
+    x = np.where(black, 0.0, X / (X+Y+Z))
+    y = np.where(black, 0.0, Y / (X+Y+Z))
+
+    third = 1./3
+    Y0 = Y * (4.4934*x*x + 4.3034*y*y - 4.276*x*y - 1.3744*x - 2.56439*y + 1.18103)
+    Y0cbrt = Y0**third
+    lam = 5.9 * (Y0cbrt - 2./3 + 0.042*(Y0-30.0)**third)
+    R =  0.799 *X + 0.4194*Y - 0.1648*Z
+    G = -0.4493*X + 1.3265*Y + 0.0927*Z
+    B = -0.1149*X + 0.3394*Y + 0.717 *Z
+    C = lam / (5.9*(Y0cbrt - 2./3))
+    L = (lam - 14.4) / np.sqrt(2)
+    j = C*(1.7*R**third + 8*G**third - 9.7*B**third)
+    g = C*(-13.7*R**third + 17.7*G**third - 4*B**third)
+
+    dL = L[1:] - L[:-1]
+    dj = j[1:] - j[:-1]
+    dg = g[1:] - g[:-1]
+
+    return np.sqrt(dL*dL + dj*dj + dg*dg)
+
+
+# TODO:
+#  * CIECAM02
+
+#### EOF #######################################################################