Color Space Sampling 101

How to uniformly sample a color space?

The evolution of color spaces is a testament to the intersection of art, science, and technology. Each color space has been developed to meet specific needs - from artistic expression and print media to digital interfaces and scientific research. Understanding these spaces is crucial for professionals in fields like photography, design, and digital media, where color accuracy and consistency are paramount.
programming
Python
tutorial
🇬🇧
Author

Antonio Montano

Published

January 27, 2024

Modified

February 11, 2024

Color spaces

Let’s break down the concept of a color space into simple terms first, and then delve into the technical aspects.

Layman terms

Imagine you have a huge box of crayons with every color you can think of. A color space is like picking a smaller box from this huge collection. This smaller box contains a specific range of colors that you can use for a particular purpose, like drawing a picture or printing a photograph.

Just like you can’t use the colors outside your chosen crayon box, a color space defines the range of colors (or ‘gamut’) that can be represented or reproduced in a medium, whether it’s a computer screen, a camera, or a printed page. Different color spaces are like different sets of crayons, each suited for different tasks or equipment.

Technically speaking

A color space is a specific organization of colors, which in a more formal setting can be described by the mathematics of color models. It’s a three-dimensional model where each color is represented by a unique point within a coordinate system.

Technically, a color space maps out a range of colors in terms of intensity values across different channels (like red, green, blue in RGB color space). It provides a standard by which we can define and reproduce colors across different devices and mediums.

Components of a color space are:

  • Primary Colors: These are the reference colors used in a color model. For example, RGB uses red, green, and blue as primary colors.

  • Gamut: This is the complete subset of colors that can be accurately represented within a given color space.

  • Color model: The underlying mathematical model describing the way colors can be represented as tuples of numbers (e.g., RGB, CMYK, HSL).

  • Perceptual uniformity: Some color spaces (like CIELab) are designed to be perceptually uniform. This means that a change of the same amount in a color value should produce a change of about the same visual importance.

  • Device-dependent vs device-independent: Color spaces can be device-dependent (like Adobe RGB, specific to monitors and printers) or device-independent (like CIELab), which abstracts color definitions from specific devices, allowing for consistent color reproduction across different devices.

  • Standardization: Standards such as sRGB are established to ensure uniform color representation across different digital devices and platforms, crucial in digital media and web content.

In essence, a color space is a framework that allows for consistent and precise color representation, ensuring that the colors you see and use are the same across various devices and mediums.

RGB and sRGB Color Spaces

The RGB color space, foundational in the realm of digital imaging and display technologies, represents colors through the additive combination of the red (R), green (G), and blue (B) primary colors. For instance, combining red and green light produces yellow, red and blue produce magenta, and green and blue create cyan.

The intensity of each primary color, typically represented by a value ranging from 0 to 255 in digital systems, combines to produce a wide spectrum of colors. This model is intrinsically linked to the way human vision perceives color through cone cells sensitive to these three color wavelengths.

In the digital context, the RGB color space is device-dependent, meaning the exact color rendition can vary across different devices like monitors, cameras, and scanners. This variation stems from differences in how devices are manufactured and the specific characteristics of their RGB color filters. As a result, a color seen on one RGB device might not look exactly the same on another, leading to inconsistencies in color reproduction.

sRGB, which stands for standard Red Green Blue, emerged as a standardization effort to tackle these inconsistencies, especially pertinent in consumer electronics and online content. Developed jointly by HP and Microsoft in 1996, sRGB provides a specific implementation of the RGB color space with well-defined chromaticities for the red, green, and blue primaries. It also specifies a transfer function (or gamma curve), which defines how the numerical values of R, G, and B map to actual luminance levels. In sRGB, this curve is a piecewise function: a linear segment in the darkest shades and a power function in the rest of the range, with a gamma value of approximately 2.2, which is close to the perceptual linearization of human vision.

One of the limitations of sRGB is its relatively narrow color gamut compared to other color spaces like Adobe RGB or ProPhoto RGB. This limitation is particularly evident in highly saturated colors, where sRGB can fail to reproduce the vibrancy seen in the real world or in wider-gamut color spaces. However, its ubiquity and standardization across a wide array of devices and software make it the default choice for web content, consumer electronics, and standard digital photography. Its compatibility and predictability across different platforms ensure that colors rendered in sRGB appear reasonably consistent on most modern displays, which are typically calibrated to this color space.

In current usage, while professional-grade equipment and applications might opt for wider-gamut color spaces like Adobe RGB, sRGB remains the principal color space for web-based content, ensuring that colors are represented uniformly across different viewing platforms. In essence, while RGB lays the foundation for digital color representation, sRGB standardizes this representation for widespread and consistent use in digital media.

Number of Colors

In both RGB and sRGB color spaces, the total number of colors that can be represented depends on the bit depth per channel. In typical scenarios where each of the RGB channels (Red, Green, Blue) is allocated 8 bits (which is quite common in consumer electronics and digital imagery), each channel can represent 2^8 or 256 distinct levels of intensity.

Since RGB and sRGB both use three channels, the total number of representable colors is calculated by multiplying the number of possibilities in each channel. So, the calculation would be:

256 (Red) x 256 (Green) x 256 (Blue) = 16,777,216 total colors

Therefore, both RGB and sRGB color spaces can represent approximately 16.7 million different colors when using an 8-bit per channel system. It’s important to note that this count is the same for both RGB and sRGB because the difference between these two spaces lies not in the number of colors they can represent but in how they interpret these colors (i.e., the color gamut and the mapping of color values to actual colors on a screen).

For images with higher bit depth per channel (like 10-bit, 12-bit, etc.), the total number of representable colors increases exponentially, allowing for a much richer and more nuanced color representation. However, the standard in most common digital applications remains 8-bit per channel.

Here are some examples of how certain colors are represented within this range:

  1. Red: Pure red is represented as (255, 0, 0). This means the red channel is at its maximum, while green and blue are at their minimum.

  2. Green: Pure green is (0, 255, 0), with the green channel at maximum and the others at minimum.

  3. Blue: Pure blue appears as (0, 0, 255), with the blue channel at its maximum.

  4. Yellow: Yellow is a mix of red and green, so it’s represented as (255, 255, 0).

  5. Cyan: Cyan is a mix of green and blue, shown as (0, 255, 255).

  6. Magenta: Magenta combines red and blue, represented as (255, 0, 255).

  7. Black: Black is the absence of color in the RGB space, so all channels are at their minimum: (0, 0, 0).

  8. White: White is the combination of all colors at their maximum intensity, so it’s (255, 255, 255).

  9. Gray: Shades of gray are created when all three channels have equal intensity. For example, a medium gray might be (128, 128, 128).

  10. Orange: Orange can vary in shade but is generally a mix of red and some green, such as (255, 165, 0).

These examples provide a basic understanding of how different colors are represented in the RGB color space. By adjusting the intensity values of the red, green, and blue channels, a wide range of colors can be created.

Display Standards

The standard for most consumer TVs and monitors is typically an 8-bit per channel RGB color system. This means that each of the three color channels (Red, Green, Blue) can display 256 levels of intensity (from 0 to 255), resulting in 16,777,216 possible colors (256^3 = 16,777,216). This is often referred to as “True Color” or “24-bit color” (8 bits x 3 channels).

However, there is an increasing trend towards higher bit depths in newer, higher-end TVs and monitors, especially those geared towards professional use or high-quality entertainment experiences. These include:

  1. 10-bit color depth: With 10 bits per channel, a display can produce 1,024 levels of intensity per channel, resulting in a total of about 1.07 billion colors (1,024^3). This is significant for professional-grade monitors used in color-critical tasks like photo and video editing.

  2. 12-bit color depth: Some very high-end and specialized monitors and TVs offer 12-bit color, with 4,096 levels per channel, totaling around 68.7 billion colors (4,096^3). These are less common and are typically used in professional and cinematic settings.

  3. HDR (high dynamic range): Modern high-end TVs and some monitors support HDR standards like HDR10, Dolby Vision, or HDR10+, which often use a 10-bit or even 12-bit color depth. HDR doesn’t just increase the number of colors; it also enhances the contrast and brightness, leading to a more dynamic and realistic image.

  4. Wide color gamut: Apart from bit depth, many newer displays also support a wider color gamut (such as DCI-P3 or Rec. 2020), meaning they can display a broader range of colors than the traditional sRGB gamut.

It’s important to note that to fully utilize these higher color depths and wider gamuts, the content being displayed (like movies, TV shows, or games) must also be created to support these standards, and the device’s hardware and software must be compatible with these advanced color features.

Complementary Colors

A complementary color is defined as a color that, when combined with a given color, produces a neutral color (white, gray, or black). Complementary colors are positioned opposite each other on the color wheel, a tool used to represent the relationships between colors.

In the RGB model, which is used for light-emitting sources like computer screens, the primary colors are red, green, and blue. The complementary color of red is cyan (a mix of green and blue), green’s complementary color is magenta (a mix of red and blue), and blue’s complementary color is yellow (a mix of red and green). When combined in this model, a color and its complementary produce white light. For example, combining red light with cyan light will result in white light.

Other Notations for RGB Color Space

HEX

HEX color notation is a staple in web and digital design, providing a succinct way to represent RGB colors. It encodes RGB values into a 6-digit hexadecimal number, prefaced by a hash symbol. Each pair of digits in this format, ranging from 00 to FF, corresponds to the red, green, and blue components of a color. This compact and efficient representation makes HEX particularly popular in coding and digital design environments.

Decimal

Decimal color notation is another way to describe RGB colors, similar to HEX but using decimal numbers. It presents colors with three values, each ranging from 0 to 255, for the red, green, and blue components. This approach is particularly user-friendly in programming and digital contexts, where working with decimal numbers is common.

CMY and CMYK Color Spaces

The CMY and CMYK color models are primarily used in color printing and are fundamentally different from the RGB color model, which is used in electronic displays. Both CMY and CMYK are based on the subtractive color model, unlike the additive nature of RGB.

CMY

CMY operates on the subtractive principle where colors are created by subtracting light. This model is based on the way light is absorbed and reflected off surfaces. It uses cyan, magenta, and yellow as its primary colors. These are the complementary colors of red, green, and blue (RGB), respectively.

In CMY, colors are created by partially or entirely subtracting the primary colors of light. For example, subtracting green from white light leaves magenta, subtracting red gives cyan, and subtracting blue yields yellow.

CMY is used in color printing. By combining varying amounts of cyan, magenta, and yellow, a wide range of colors can be reproduced. When all three colors are combined at their full intensity, they theoretically produce black, but in practice, they produce a muddy dark brown or gray.

CMYK

CMYK adds a fourth component, “key” (black), to the CMY model. The ‘K’ component is used because pure black cannot be created reliably through the combination of CMY inks due to imperfections in ink pigments. Adding black ink allows for deeper, more accurate, and consistent blacks.

CMYK creates colors through a subtractive process by layering different amounts of cyan, magenta, yellow, and black ink on paper. The more ink used, the darker the color becomes. Black ink in CMYK is also more economical and provides better shadow detail than CMY, making it a more efficient color model for full-color printing.

Differences with RGB

The most important difference is that RGB is an additive color model used in electronic displays, where colors are created by combining light. CMY and CMYK are subtractive, used in printing, where colors are created by subtracting light. Or, with different words, RGB is used for digital screens like monitors, TVs, and cameras, where light is emitted directly. CMY and CMYK are used in printing on physical media, where light is reflected.

In RGB, black is the absence of light, while in CMYK, black is a separate ink component for deeper and more uniform blacks.

HSL and HSV Color Spaces

Both HSL (hue, saturation, lightness) and HSV (hue, saturation, value) are color models used to represent the RGB color space in terms that are more intuitive for humans to understand and manipulate. These models describe colors in terms of their shade (hue), intensity (saturation), and brightness (lightness/value):

  • HSL:

    • Hue: Represents the type of color, or the color itself. It is typically measured in degrees around a color wheel, with red at 0°, green at 120°, and blue at 240°.

    • Saturation: Indicates the intensity or purity of the color. In HSL, saturation ranges from 0%, which is a shade of gray, to 100%, which is the full color.

    • Lightness: Also known as luminance, lightness defines how light or dark a color is. A lightness of 0% is black, 50% is the true color, and 100% is white.

  • HSV:

    • Hue: Similar to HSL, it defines the color itself.

    • Saturation: Measures the intensity or vibrancy of the color. It ranges from 0%, which is completely unsaturated (gray), to 100%, which is the most saturated form of the color.

    • Value: Also known as brightness, it represents the brightness or darkness of the color. A value of 0% is black, and 100% is the brightest form of the color.

Differences with RGB

RGB represents colors by specifying the intensity of each primary color, making it less intuitive for tasks like adjusting brightness or saturation. HSL and HSV are transformations of the RGB color model designed to be more intuitive for human perception. They allow for easier adjustments of color properties like shade, intensity, and brightness.

HSL and HSV are often used in color picker tools in graphic design software because they offer a more user-friendly way to select and manipulate colors. Moreover, they separate the chromatic information (hue and saturation) from the achromatic information (lightness/value), unlike RGB where all three parameters mix chromatic and achromatic components.

While RGB is suited for electronic displays and color mixing with light, HSL and HSV are more suited for tasks that involve adjusting and fine-tuning colors, like in graphic design and photo editing. In essence, HSL and HSV are used to represent the same colors as RGB but in a way that aligns more closely with how people think about and perceive colors. This makes them particularly useful in interfaces and applications where users need to make precise adjustments to color properties.

YIQ and YUV Color Spaces

YIQ and YUV are color spaces primarily used in the broadcasting industry, particularly in television systems. Both are designed to split a color signal into luminance and chrominance components, but they are used in different television standards.

The YIQ color space was predominantly used in the NTSC color television system, mainly in North America. In YIQ, ‘Y’ stands for the luminance component, which represents the brightness of the image. The ‘I’ and ‘Q’ components represent the chrominance or color information. ‘I’ carries information about the orange-cyan range, while ‘Q’ carries information about the green-magenta range. The separation of luminance and chrominance in YIQ allowed NTSC broadcasts to be compatible with black-and-white televisions. Luminance (Y) could be displayed by black-and-white TVs, while color TVs could use all three components (Y, I, Q) to display the full color image.

YUV is similar to YIQ in that it also separates the color signal into luminance (Y) and two chrominance components (U and V). YUV is used in the PAL and SECAM color television systems, prevalent in Europe and other parts of the world. The ‘Y’ component, like in YIQ, represents the image brightness. ‘U’ represents the blue-luminance difference, and ‘V’ represents the red-luminance difference. This separation was also designed for compatibility with black-and-white TVs, with the added advantage of better color quality compared to NTSC, although at a slightly lower resolution.

Both YIQ and YUV were developed to maximize the efficiency of color transmission in broadcasting and to ensure backward compatibility with black-and-white television systems. They differ from RGB, which is used in electronic displays and combines red, green, and blue light to produce colors. While RGB is more straightforward for generating colors electronically, YIQ and YUV are more efficient for broadcasting purposes because they separate the brightness of the image from the color information, which can be more efficiently compressed and transmitted.

The use of YIQ has declined with the shift towards digital broadcasting, which often uses other color spaces like YCbCr. YUV, on the other hand, is still relevant in many video processing applications and is closely related to the YCbCr color space used in digital video.

CIE Color Spaces

The International Commission on Illumination, known as CIE (Commission Internationale de l’Éclairage), is a significant organization in the field of color and lighting standards. CIE has introduced several critical color spaces, including XYZ, CIELab, and CIELCh, each serving unique purposes in color science.

XYZ

The CIE XYZ color space, established in 1931, is foundational in the field of colorimetry. It’s a device-independent model representing color perceptions of a standard observer. In XYZ, ‘X’ represents a mix of cone response curves, ‘Y’ denotes luminance, and ‘Z’ corresponds to blue stimulation. This color space serves as a reference, allowing for the translation of colors between different systems and devices. The gamut of XYZ encompasses all perceivable colors, making it a comprehensive standard for color representation.

CIELab

The CIELab (or Lab) color space, introduced in 1976, with its broad gamut and perceptually uniform characteristics, is designed to encompass the entire range of colors visible to the human eye. This extensive gamut means it can represent colors that are outside the range of many display systems and printers.

In CIELab:

  • The ‘L’ component (lightness) ranges from 0 to 100, where 0 represents black, and 100 represents white. This vertical axis accounts for the luminance of colors.

  • The ‘a’ component operates on a green to red axis. Negative values of ‘a’ indicate green, while positive values indicate red.

  • The ‘b’ component works on a blue to yellow axis, with negative values representing blue and positive values indicating yellow.

This structure allows for a precise and detailed representation of colors. For example:

  • A strong green might be denoted as (L=50, a=-50, b=50), representing a mid-level lightness with a strong green component and a touch of yellow.

  • A deep red could be represented as (L=40, a=60, b=30), indicating a darker shade (lower lightness) with a dominant red component and some yellow.

The notation in CIELab is quite distinct from RGB. While RGB specifies the intensity of red, green, and blue light to create colors (like RGB(255, 0, 0) for bright red), CIELab describes colors in terms of lightness and color-opponent dimensions, which align more closely with the human perception of colors.

This perceptual uniformity – where a given numerical change corresponds to a roughly equal perceptual change in color – is a key feature of CIELab. It ensures that when colors are altered or compared in this space, the perceived differences are consistent across the color spectrum.

CIELab’s broad gamut and perceptual uniformity make it a preferred choice in industries where accurate color differentiation and measurement are critical, like paint manufacturing, textile production, and quality control in various product design processes. It’s also commonly used in digital imaging and photography for color correction and editing, as it offers more intuitive control over color adjustments than RGB.

A classic example of colors that can be represented in CIELab but are often outside the gamut of many RGB devices are certain highly saturated cyans and blues. For instance, a very bright, saturated cyan might be represented in CIELab as something like (L=90, a=-40, b=-15). This color would be extremely vivid and might not be accurately displayed on a standard RGB monitor, which would struggle to reproduce its intensity and saturation. Similarly, some extremely bright and saturated yellows and greens can also fall outside the typical RGB gamut. These colors are so vivid that they can only be seen under intense lighting conditions, such as direct sunlight, and cannot be fully replicated on standard digital displays.

CIELCh

CIELCh is a color space closely related to CIELab but represented in cylindrical coordinates instead of Cartesian ones. It’s derived from the CIELab color space and is designed to represent color in a way that’s more intuitive and aligned with how humans perceive color changes.

In CIELCh, the components represent:

  1. L (lightness): Just like in CIELab, ‘L’ in CIELCh represents the lightness of the color, with 0 being black and 100 being white.

  2. C (chroma): This is essentially the saturation of the color. Chroma in CIELCh is derived from the a* and b* components of CIELab. It represents the vividness or intensity of the color. Higher chroma values indicate more intense, vivid colors, while lower chroma values result in duller, more washed-out colors.

  3. h (hue angle): Instead of using the a* and b* Cartesian coordinates to define the hue, CIELCh uses an angle in a cylindrical space. This hue angle starts from the positive a* axis and is usually measured in degrees (0° to 360°). Different values correspond to different hues (colors), similar to positions on a traditional color wheel. For example, 0° or 360° represents red/magenta, 90° represents yellow, 180° represents green, and 270° represents blue.

The transformation from CIELab to CIELCh is a conversion from Cartesian to cylindrical coordinates. The lightness (L) remains the same, but the a* and b* values in CIELab are converted to chroma (C) and hue (h) in CIELCh. The formulae for these conversions involve trigonometric functions where chroma (C) is calculated as the square root of (a*^2 + b*^2), and the hue angle (h) is calculated using the arctan function.

CIELCh is useful in various applications that require intuitive color adjustment and selection. The cylindrical representation makes it easier to understand and manipulate hue and saturation independently of lightness, which aligns more closely with how people think about and use color, especially in fields like graphic design, painting, and digital media.

This color space is particularly favored for tasks where color harmony and balance are important, as it allows for a straightforward manipulation of color relationships and contrasts.

CIELUV

CIELUV is a color space introduced by the International Commission on Illumination (CIE) to enable more effective color communication, especially for light emitting or reflecting surfaces. It’s part of the CIE 1976 color spaces, which also include CIELab.

The name CIELUV comes from the CIE Luv* color space. It’s designed similarly to CIELab, with ‘L’ representing lightness. However, while CIELab uses ‘a’ and ‘b’ for color-opponent dimensions, CIELUV uses ‘u*’ and ‘v*’ for chromaticity. These dimensions are based on the CIE 1960 u-v chromaticity diagram, which is a projection of the CIE XYZ color space.

CIELUV is particularly useful for applications like lighting design, video, and other emissive display applications where color gamut is crucial. One of its strengths lies in its ability to accurately represent highly saturated colors, a limitation in the CIELab color space.

In terms of technical details, the ‘L’ in CIELUV represents the perceived lightness, similar to CIELab. The ‘u*’ and ‘v*’ coordinates, however, are calculated differently, focusing on chromaticity. This difference stems from the way the two color spaces project the XYZ space into the color-opponent dimensions. In CIELUV, these projections are designed to better represent the way we perceive color in light-emitting sources.

When comparing CIELUV to CIELab, the key difference lies in their treatment of chromaticity and the types of applications they’re best suited for. CIELab is generally preferred for surface colors (like paint or ink), where color is a result of light reflecting off an object. In contrast, CIELUV is more suited for light-emitting sources (like displays or lights), where color is produced by light itself.

Both color spaces derive from the XYZ model and share the lightness dimension (L*). However, their approach to chromaticity makes them suitable for different applications and types of color processing. CIELUV’s emphasis on chromaticity makes it a valuable tool in industries dealing with light sources, displays, and environments where the light’s color itself is the primary concern.

LCH(ab)

The LCH(ab) color space, often simply referred to as LCH, is a color model derived from the CIELab color space. It represents colors in a more intuitive way compared to the Cartesian coordinates (a* and b*) used in CIELab. The LCH color model is based on cylindrical coordinates rather than Cartesian coordinates and consists of three components:

  1. Lightness (L): Similar to the L* in CIELab, it represents the lightness of the color, where 0 is black, 100 is white, and values in between represent various shades of gray.

  2. Chroma (C): Chroma in LCH is analogous to saturation in other color models. It represents the intensity or purity of the color. Higher chroma values indicate more vibrant colors, while lower values result in more muted tones.

  3. Hue (H): Hue is represented as an angle (in degrees) around a color wheel. It defines the type of color (such as red, blue, green, yellow, etc.). In LCH, hue starts at 0 degrees for red and moves through the spectrum, with green at 120 degrees, blue at 240 degrees, and so forth.

The LCH color space is particularly useful in applications where understanding and manipulating the color relationships and harmonies are important. It’s often used in graphic design, painting, and digital media for this reason. By separating the color components in this way, LCH allows designers to adjust hue and chroma independently of lightness, which can be more intuitive than working with the a* and b* coordinates in CIELab.

In essence, LCH(ab) offers a perceptually-based approach to color representation, aligning closely with how humans perceive and interpret color differences, making it a valuable tool in color-sensitive work.

Color Space as a Mathematical Space Subset

The concept of whether color spaces are subsets of integer or real mathematical spaces can be understood in terms of how they represent color values and the precision with which they operate.

  1. RGB: RGB, commonly used in digital displays and imaging, typically uses integer values in practical applications, especially in 8-bit per channel systems where each color (Red, Green, Blue) is represented by an integer from 0 to 255. However, in more precise applications, such as high dynamic range (HDR) imaging or in professional color grading, RGB values can be represented in a floating-point format (real numbers), allowing for a finer gradation and a wider range of color intensities.

  2. CIELab and CIELuv: Both CIELab and CIELuv are part of the CIE 1976 color space. They are generally considered to be subsets of the real number space. The L*, a*, b* (CIELab) and L*, u*, v* (CIELuv) coordinates are typically represented as real numbers to allow for a high degree of precision, which is crucial in color matching and colorimetric applications. This representation aligns with their design as perceptually uniform spaces, where small changes in values correspond to consistent perceptual differences in color.

  3. HEX: The HEX color notation, used predominantly in web design, is based on integer values. It is essentially a hexadecimal representation of RGB values, where each color channel is represented by two hexadecimal digits, corresponding to an integer value between 0 and 255.

  4. CIE XYZ: The CIE XYZ color space, which serves as a foundation for many other color spaces, including CIELab and CIELuv, represents colors using real numbers. This representation allows for a high degree of precision and is important for scientific and industrial applications where accurate color measurement and reproduction are necessary.

  5. YIQ, YUV, and others: Used primarily in broadcasting and video processing, these color spaces often use real numbers for greater precision, especially in professional applications. However, for standard television broadcast and consumer electronics, these values are typically quantized into integer values.

In summary, while practical implementations of these color spaces in digital devices often use integer values for ease of processing and storage, the theoretical models of most advanced color spaces, especially those used in colorimetry and professional applications, rely on real numbers for greater precision and a more accurate representation of color.

Color Spaces Conversion Libraries

python-colormath

python-colormath is a simple Python module that spares the user from directly dealing with color math. Some features include:

  • Support for a wide range of color spaces. A good chunk of the CIE spaces, RGB, HSL/HSV, CMY/CMYK, and many more.

  • Conversions between the various color spaces. For example, XYZ to sRGB, Spectral to XYZ, CIELab to Adobe RGB.

  • Calculation of color difference. All CIE Delta E functions, plus CMC.

  • Chromatic adaptations (changing illuminants).

  • RGB to hex and vice-versa.

  • 16-bit RGB support.

  • Runs on Python 2.7 and Python 3.3+.

To convert a color from sRGB to CIELab using the Python colormath library, you first need to ensure that colormath is installed in your Python environment. You can install it using pip:

pip install colormath

Once colormath is installed, you can use it to perform the conversion. Here’s a simple example:

from colormath.color_objects import sRGBColor, LabColor, XYZColor, \
                                    LCHabColor, LCHuvColor, HSVColor, \
                                    CMYColor, CMYKColor
from colormath.color_conversions import convert_color

# Define an sRGB color (is_upscaled=True if you're using 0-255 range)
1rgb = sRGBColor(128., 0., 128., is_upscaled=True)

# Convert the sRGB color to other color spaces
2lab = convert_color(rgb, LabColor)      # CIELab
xyz = convert_color(rgb, XYZColor)      # XYZ 
lch_ab = convert_color(rgb, LCHabColor) # LCH(ab)
lch_uv = convert_color(rgb, LCHuvColor) # LCH(uv)
hsv = convert_color(rgb, HSVColor)      # HSV
cmy = convert_color(rgb, CMYColor)      # CMY
cmyk = convert_color(rgb, CMYKColor)    # CMYK

# Print the colors in different color spaces  
3print("CIELab: ", lab)
# CIELab:  LabColor (lab_l:29.7843 lab_a:58.9285 lab_b:-36.4932) 
print("XYZ: ", xyz)         
# XYZ:  XYZColor (xyz_x:0.1280 xyz_y:0.0615 xyz_z:0.2093)
print("LCH(ab): ", lch_ab)  
# LCH(ab):  LCHabColor (lch_l:29.7843 lch_c:69.3132 lch_h:328.2310)
print("LCH(uv): ", lch_uv)  
# LCH(uv):  LCHuvColor (lch_l:29.7843 lch_c:67.8446 lch_h:307.7154)
print("HSV: ", hsv)         
# HSV:  HSVColor (hsv_h:300.0000 hsv_s:1.0000 hsv_v:0.5020)
print("CMY: ", cmy)         
# CMY:  CMYColor (cmy_c:0.4980 cmy_m:1.0000 cmy_y:0.4980)
print("CMYK: ", cmyk)       
# CMYK:  CMYKColor (cmyk_c:0.0000 cmyk_m:1.0000 cmyk_y:0.0000 cmyk_k:0.4980)
1
An sRGB color is defined with the red, green, and blue components. If you’re using values in the 0-255 range, set is_upscaled=True so that colormath knows to scale them down to 0-1.
2
The convert_color function is used to convert the defined sRGB color to the CIELab color space.
3
Finally, the resulting CIELab color is printed out. Other conversions follow.

The output will be the CIELab representation of the given sRGB color. Keep in mind that colormath handles these conversions assuming standard conditions and may not account for specific display or lighting characteristics unless explicitly specified.

Other Libraries

There are several other libraries in Python and other programming languages that can be used to convert between color spaces. Here are a few notable ones:

  1. OpenCV (Python, C++, Java): Primarily known for its extensive functionalities in computer vision, OpenCV also offers color space conversion functions. It can handle conversions between various color spaces, including RGB, HSV, CIELab, and more.

  2. Pillow (Python): The Pillow library, which is an extension of the Python Imaging Library (PIL), includes functions for converting images between different color spaces.

  3. Color.js (JavaScript): A JavaScript library for color conversion and manipulation, it supports a wide range of color spaces and is particularly useful for web development.

  4. D3.js (JavaScript): While primarily a library for producing interactive data visualizations, D3.js also includes methods for color space conversion, useful in the context of web design and visualizations.

  5. Tinycolor (JavaScript): A small, fast library for color manipulation and conversion in JavaScript. It supports RGB, HSV, HSL, and HEX formats.

  6. Colorspacious (Python): A Python library designed to convert and manipulate various color spaces with a focus on perceptual uniformity and color difference calculations.

  7. Matplotlib (Python): Although mainly a plotting library, Matplotlib in Python can convert colors between RGB and other color spaces as part of its plotting functionalities.

Each of these libraries has its own set of features and strengths, and the choice of library can depend on the specific requirements of your project, such as the programming language you’re using, the color spaces you need to work with, and the level of precision or control you need over the color conversion process.

Python Script for CIELab Color Sampling and Conversion

The Python script is designed to uniformly sample the CIELab color space and convert these samples to RGB. It also finds the nearest CIELab color to a given target color, either in CIELab or RGB space, and saves comparison charts. The script contains several key functions:

generate_uniform_lab_samples(n_samples)

This function generates uniformly distributed samples in the CIELab color space. It calculates the number of points per dimension based on the cubic root of the total number of desired samples, creating a grid of points in the CIELab space. If more points are generated than needed, it randomly samples from these points to get the desired number.

lab_to_rgb(lab_arr)

This function converts a batch of CIELab values to RGB and marks any colors that are approximated due to out-of-gamut issues. It uses the skimage library for the CIELab to RGB conversion and checks for any warnings during the conversion process, specifically looking for “negative Z values” which indicate an approximation.

rgb_to_lab(rgb)

This function converts an RGB color to the CIELab color space. It normalizes the RGB values (assuming they are in the 0-255 range) and uses the colormath library to perform the conversion.

create_color_chart_with_spacing(lab_samples, rgb_samples, approx_flags, square_size_cm, spacing_cm, label_font_size, text_spacing_cm, save_path)

This function creates a square image containing color squares with spacing between them. Each square represents a color sample. It calculates the total image size considering the spacing and text space and then uses matplotlib to create and save the image.

find_nearest_color_lab(target_lab, generated_lab_samples)

This function finds the nearest CIELab color to a given target color among generated samples using Delta E. It compares the target color with each generated sample using the delta_e_cie2000 function from the colormath library.

save_comparison_chart(target_lab, nearest_lab, square_size, spacing, save_path)

This function saves an image with two squares: one for the target color and one for the nearest CIELab color. It draws the squares and saves the image using matplotlib.

The script also includes a section at the end for generating samples, converting them, and saving comparison charts.

This code is a comprehensive tool for exploring and visualizing the CIELab color space, its conversion to RGB, and the assessment of color proximity within this space.

Download the Jupyter notebook or open it in Colab (click on the badge below) to sample the CIELab space and get the nearest sample of a given color.

Open In Colab

References

CIE website: International Commission on Illumination official website

Bruce Justin Lindbloom’s website: useful for color spaces conversion formulas

John the Math Guy’s website: outstanding resource for color theory

Back to top