Short version
How can I tell if a color (e.g. XYZ) is impossible? (Wikipedia: Imposible color)
For example, this color is impossible:
- XYZ: (15.96, 84.04, 0)
- xyY: (0.1595, 0.8404, 0.8404)
- Lab: (93, -196, 161) (D65 whitepoint)
It's impossible because it lies outside of the chromacity diagram:
How can I know that?
Incorrect code
The goal is for someone to fill in the function:
Boolean IsImaginaryColor(Single X, Single Y, Single Z)
{
//...TODO: Get someone to answer the question.
}
Right now we know that if any of the components of a corresponding LMS color are negative, then the color is imaginary.
That is a necessary, but not sufficient, condition for a color to be real. You can have all three components of LMS be positive, but it still be an imaginary color.
Boolean IsImaginaryColor(Single X, Single Y, Single Z)
{
//If any component of LMS color is negative,
//then the color is definitely imaginary.
LMSColor lms = XYZtoLMS(X, Y, Z);
if ((lms.L < 0) or (lms.M < 0) or (lms.S < 0))
return true;
//The color may still be imaginary,
//but i don't know how to solve that problem
//So as a first approximation i'll say it's real
return false;
}
LMSColor XYZtoLMS(Single X, Single Y, Single Z)
{
//perform Matrix multiplication:
//
// LMS = M * XYZ
//
// Where M is the M_CAT02 transformation matrix from CIECAM02
//
// 0.7328, 0.4296, -0.1624
// -0.7036, 1.6975, 0.0061
// 0.0030, 0.0136, 0.9834
LMSColor result;
result.L = 0.7328*X + 0.4296*Y + -0.1624*Z
result.M = -0.7036*X + 1.6975*Y + 0.0061*Z
result.S = 0.0030*X + 0.0136*Y + 0.9834*Z
}
In the xy
color plane, this gives a good first-approximation (and nice visual indication) of impossible colors:
But the calculation still gives colors outside the chromacity diagram *(technically they're outside the "spectral locus"). So obviously only checking for negative components in LMS is incomplete.
Long Version
I am rendering a color picker. For example:
- to pick an Lab color
- you pick an ab color
- for a given L plane
This is similar to what you can already do in Photoshop:
So in this case I've picked the color:
- Lab: (72, -58, 119)
That color (assuming the D65 whitepoint) corresponds to the XYZ color:
- Lab: (72, -58, 119)
- XYZ: (25.22, 43.66, 0.36)
You can tell if a real color is outside the sRGB color gamut if one of its components is either:
- less than 0
- greater than 255
This XYZ color lies outside of the sRGB color space because one of it's components is negative:
- XYZ: (25.22, 43.66, 0.36)
- Lab: (72, -58, 119) (D65)
- RGB: (106.1, 199.6,
-234.7
) (sRGB)
Photoshop already knows if a color is outside the sRGB color gamut, and will display a gumut warning:
But I'd like to go one step further
I can already know if a color is outside the sRGB color gamut.
But now i want to know if a color is imaginary, so i can continue to show the gamut, but hide completely impossible colors. A conceptual mockup might be:
Warning: I have no idea which of those colors actually are impossible. This is only the idea of the concept.
So what I need to know is if a color is impossible.
Background Theory - What is an example of an impossible color?
The Wikipedia page on Impossible colors notes that while the primaries for the sRGB color space all lie inside the spectral locus - and so are all real colors:
The ProPhotoRGB color space does use some primaries that are impossible:
The ProPhoto RGB color space uses imaginary green and blue primaries to obtain a larger gamut (space inside the triangle) than would be possible with three real primaries. However, some real colors are still irreproducible.
So now I have a concrete example of an impossible color: the green primary of the ProPhoto RGB color space:
| Color | CIE x | CIE y |
|-------|--------|--------|
| red | 0.7347 | 0.2653 |
| green | 0.1596 | 0.8404 | <--- this one
| blue | 0.0366 | 0.0001 |
| white | 0.3457 | 0.3585 |
This impossible color, given different color spaces, is:
- xyY: (0.1596, 0.8404, 0.8404)
- XYZ: (15.96, 84.04, 0)
- LMS: (47.80, 131.43, 1.19)
- Lab: (93.4679, -195.9973, 161.1515)
- LCHab: (93.4679, 253.7415, 140.5725)
How can I tell that this color is impossible?
Given an XYZ color, how can I tell that it is impossible? E.g.:
- XYZ:
15.96
,84.04
,0
Bonus Chatter
It's important to note the difference between
- colors existing outside some gamut
- and imaginary colors
A quick single-image primer would be:
- Gamut: a color may not be displayable on your monitor, or printer, or phone, but it is still a real color - you could get a combination of Electromagnetic Waves of various wavelengths and intensities to generate the color
- Imaginary: No combination of EM waves, of any intensities, of any wavelengths, can generate that response in the Long, Medium, and Short human cones
I already know how to tell if a color exists outside a particular color gamut.
I want to know if a color also exists outside the spectral locus.
In other words: i want to know if it is imaginary.
Bruce Lindbloom has a nice graphic that raises the issues of colors outside the Lab color space when you arbitrary choose to arbitrarily limit the a
and b
component values to +- 128:
This is a duplicate of the answer I gave here: Determine that a Luv Color is non-imaginary which relate to https://stackoverflow.com/a/48396021/931625
I think the safe way is to compute the XYZ volume boundaries and check if you are within or outside.