Skip to content
Search

CIELAB color space

lastmod 2024-01-29created 2024-01-293 edits

The Lab color space is a color space created by a nonlinear transformation of the CIE XYZ color space, based on the opponent process theory of human vision.

Originally, the term Lab color space referred to the Hunter 1948 Lab color space, but in modern times it has come to refer to the CIE 1976 Lab* color space. Both color spaces were created by transforming the CIE XYZ color space, which is based on research into human color perception. The difference between the two is that the Hunter 1948 color space uses a transformation based on quadratic functions, while the CIE 1976 color space uses a transformation based on cubic functions. Also, both were influenced by the Munsell color system and aimed to be more uniform color systems than the XYZ color space. Here, a uniform color system means one that aims for colors separated by the same distance in the color space to be perceived by the human eye as color differences of the same size.

The Lab color space is defined relative to the white defined in XYZ. Therefore it can refer to different colors depending on the value of white. The CIE standard illuminant D50 is commonly used, but different illuminants can be used depending on the environment.

The Lab* color space includes every gamut that RGB or CMYK can represent, and also includes colors that humans cannot perceive.

Pros

The biggest advantage of the Lab color space is that, unlike RGB or CMYK, it is media-independent. Unlike color spaces whose colors vary with the display device or print medium, the Lab* color space was defined based on research into human vision. In particular, the L value, the luminance axis, was designed to correspond to the brightness humans perceive.

The gamut of the Lab color space is far larger than that of computer displays and print media, and even larger than the range of colors humans can perceive. Therefore it must be represented with more precise values than RGB or CMYK. Until the 1980s most image formats supported only 8 bits, which made them unsuitable for representing the Lab color space, but today most formats support 16-bit images, so this is no longer a problem.

CIE Lab*

In the CIE Lab* color space,

  • The L* value represents lightness. L* = 0 is black, and L* = 100 is white.
  • a* indicates whether the color leans toward red or green. A negative a* is a color leaning toward green, and a positive a* is a color leaning toward red/purple.
  • b* represents yellow and blue. A negative b* is blue and a positive b* is yellow.

Also, following research findings that human color perception is nonlinear, the Lab* color space has a nonlinear relationship with the actual wavelengths of light.

Also, the Lab* space was designed so that the distance between two different colors is proportional to the color difference humans perceive.

Because the RGB and CMYK color spaces are not media-independent, converting them to the Lab* color space first requires converting them to an absolute color space such as sRGB or Adobe RGB.

Formula and conversion results in OpenCV

\(RGB \leftrightarrow CIE L*a*b* ( CV_BGR2Lab, CV_RGB2Lab, CV_Lab2BGR, CV_Lab2RGB )\)

In case of 8-bit and 16-bit images, R, G, and B are converted to the floating-point format and scaled to fit the 0 to 1 range.

\(\begin{bmatrix} X \\ Y \\ Z \end{bmatrix} \leftarrow \begin{bmatrix} 0.412453 & 0.357580 & 0.180423 \\ 0.212671 & 0.715160 & 0.072169 \\ 0.019334 & 0.119193 & 0.950227 \end{bmatrix} \cdot \begin{bmatrix} R \\ G \\ B \end{bmatrix}\)

\(X \leftarrow X/X_n, \text{where} X_n = 0.950456\)

\(Z \leftarrow Z/Z_n, \text{where} Z_n = 1.088754\)

\(L \leftarrow \left\{ \begin{matrix} \begin{align} & 116*Y^{1/3}-16 & \textrm{for} \; Y>0.008856 \\ & 903.3*Y & \textrm{for} \; Y \le 0.008856 \end{align} \end{matrix} \right.\)

\(a \leftarrow 500 (f(X)-f(Y)) + delta\)

\(b \leftarrow 200 (f(Y)-f(Z)) + delta\)

where

\(f(t)= \left\{ \begin{matrix} \begin{align} & t^{1/3} & \textrm{for} \; t > 0.008856 \\ & 7.787t+16/116 & \textrm{for} \; t \leq 0.008856 \end{align} \end{matrix} \right.\)

and

\(delta = \left\{ \begin{matrix} \begin{align} & 128 & \textrm{for} \; 8-bit images \\ & 0 & \textrm{for} \; floating-point images \end{align} \end{matrix} \right.\)

This outputs \(0 \leq L \leq 100, -127 \leq a \leq 127, -127 \leq b \leq 127\). The values are then converted to the destination data type:

8-bit images
\(L \leftarrow L*255/100, \; a \leftarrow a + 128, \; b \leftarrow b + 128\)

That is,

  • L values are 0 ~ 255
  • a values are 0 ~ 128
  • b values are 0 ~ 128

Python code:

result = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)

See also

Favorite site

author Zer0 sitemap