New color quality metrics

I finished working on spectral upsampling methods about two weeks ago. Since then I've been working on a different part of the library, the quality submodule. As described in the original project idea, the goals are:

  • Adding support for CIE 224:2017 Colour Fidelity Index.
  • Adding support for ANSI/IES TM-30-18, a standard defining the same index and a couple more.
  • Adding support for creating TM-30-18 Color Rendition Reports. This part I proposed myself after seeing an open issue for it.

The first two are already complete, see the pull request. The last goal is being worked on in a separate repository, since I'm not yet sure how exactly I want to implement the reports (just Matplotlib, HTML, something else?).

Color rendering

There are infinitely many light spectra that humans perceive as white (see metamerism). In principle it's enough to combine just two monochromatic sources. Just for fun I searched for a spectrum like that and found this:

λ [nm] 449 450 451 567 568 569 570
s [a.u.] 0.000000 0.619473 0.000000 0.000000 0.166711 0.833289 0.000000

This combination of deep blue and orange laser light, showing up as two very narrow peaks on a plot, will match the standard CIE D65 daylight illluminant perfectly. Of course, if you tried to light up a room with it, you'd notice that it's not “proper” white. Because there would be no light other than blue and orange to reflect off surfaces, everything would look blue, orange, or something in between.

Fluorescent lamps are infamous for having very peaky emission spectra as well. This Wikimedia Commons image shows that the peaks are emission lines of various rare elements inside the lamp. Just like in case of my theoretical lamp, objects lit with such lamps don't have quite the right colors. The same problem applies to LEDs as well. The effect a light source has on colors of things is called color rendering.

Below is a chart showing how colors are affected by various daylight (6500 K) illuminants. D65 is the reference, Kinoton is some sort of a projector, FL1 is a standard fluorescent lamp, a LED, a mercury lamp (a bit too blue) and my made up spectrum.

A visualization of differences in color rendering. The names refer to spectral distributions from Colour's SDS_ILLUMINANTS and SDS_LIGHT_SOURCES, with the exception of my artificial 'Twin peaks' lamp.

Color rendering indexes

A high-CRI LED lamp.

The most common way to quantify how good the color rendition of a lamp is the CIE color rendering index (CRI). Colors of a set of test color samples are compared between a test illuminant and a reference (a black body or a daylight model, depending on the temperature), much like in my chart above. For each sample a special CRI (SCRI) is computed based on the color difference. The arithmetic mean of eight1) SCRIs is called the CRI or $R_a$.

A perfect lamp has CRI equal to 100. The worse the color rendering, the lower the number. For example, FL1 has a CRI of 76 and my made-up lamp has a CRI of -7. Negative numbers are possible, but rare. Manufacturers sometimes specify $R_9$, the SCRI of a very saturated red sample, and it does tend to be very low or negative.

Color fidelity index (CFI) is an updated version of CRI, using many more test color samples (99) and better, more accurate colorimetry. Even the problem of negative indexes was fixed. TM-30-18 adds a few more metrics, notably the gamut area index, quantifying how intense colors can get when a given illuminant is used. This is quite useful, since washed out colors (caused by a low gamut area lamp) can look worse than inaccurate colors (caused by a low color fidelity lamp).

TM-30-18 also details how to create a color rendition report, which presents all the information in a nice and organized way. Work on that is still in progress, so I'll leave the details for another post.

A (partial) TM-30-18 color rendition report for the high-CRI OSRAM LED mentioned above. Work in progress. Information is accurate but the layout is still a bit messy and needs polishing.
There are 14, but it seems that nobody cares about the last 5.