Suppose I have a triple of coordinates in the Luv color space. What is the best way to determine that these correspond to a real color?
-
What do you mean for "imaginary"? Impossible to build a spectral distribution of light on such colour, or just non displayable (out of gamut) e.g. in one RGB colour space? Note L is in principle unlimited (and independent of what we choose for white). – Giacomo Catenazzi May 16 '18 at 06:17
2 Answers
Assuming your L* is in domain [0, 100], you can construct the boundaries of the Visible Spectrum and then determine if your CIE L*u*v* coordinates are within it.
import colour
import numpy as np
def generate_square_waves(samples):
square_waves = []
square_waves_basis = np.tril(np.ones((samples, samples)))[0:-1, :]
for i in range(samples):
square_waves.append(np.roll(square_waves_basis, i))
return np.vstack((np.zeros(samples), np.vstack(square_waves),
np.ones(samples)))
def XYZ_outer_surface(samples):
XYZ = []
wavelengths = np.linspace(colour.DEFAULT_SPECTRAL_SHAPE.start,
colour.DEFAULT_SPECTRAL_SHAPE.end, samples)
for wave in generate_square_waves(samples):
spd = colour.SpectralPowerDistribution(
wave, wavelengths, interpolator=colour.LinearInterpolator).align(
colour.DEFAULT_SPECTRAL_SHAPE)
XYZ.append(colour.spectral_to_XYZ(spd))
return np.array(XYZ).reshape(len(XYZ), -1, 3)
mesh = XYZ_outer_surface(43).reshape((-1, 3))
E = colour.ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['E']
XYZ1 = colour.Luv_to_XYZ([50, 50, 50], E)
print(colour.is_within_mesh_volume(XYZ1, mesh))
# True
XYZ2 = colour.Luv_to_XYZ([50, 250, -250], E)
print(colour.is_within_mesh_volume(XYZ2, mesh))
# False
I would highly recommend caching the mesh as it is quite heavy to compute.

- 3,660
- 1
- 23
- 29
-
Can you explain what this algorithm is doing? Bruce Lindbloom's only explanation is *"obtained by passing square pulses through the conversion from spectrum to XYZ"*. -What is the pulse -Is it moving -In what direction is it moving -How is the movement represented -How do you pass it through something -what do the five numbers represent -what is the `1` doing. It would be great if Bruce documented his algorithm. – Ian Boyd Aug 26 '18 at 12:47
-
CIE Illuminant E, is the theoretical illuminant that fully stimulates the Human Visual System (HVS): for every bin in the range of our sensitivity to light, its value is equal to one. The spectral pulses are simply all the possible slices of Illuminant E from a slice full of zeros to a slice that fully represent it, i.e. full of ones. Each of this spectral pulse / slice upon conversion to CIE XYZ tristimulus values yields a point in space. The collections of those points is what define the Visible Gamut. The order the spectral pulses does not really matter. – Kel Solaar Aug 26 '18 at 20:11
-
Why do the bins not go `0 0 0 0 0` and then `0 0.1 0 0 0` and then `0 0.2 0 0 0` and then `0 0.3 0 0 0`? Is the idea to try to cover each range of every frequency bin? Does each number represent a frequency bin? Does that mean that each digit is a range of wavelengths? If so: where does Illuminant E fit into this; illuminat E is a specific SPD; but instead we are constructing arbitrary Spectral power distributions. – Ian Boyd Aug 27 '18 at 18:34
-
These are all questions where i'm trying to get someone to back-document the algorithm - to explain the algorithm - to explain **what** is being done. Because without knowing what's going on, the algorithm is being obscured by code (which in this case is a highly specialized set of python libraries, which have non-obvious names (`tril` `align` `reshape` `ones` `0:-1: 0`) – Ian Boyd Aug 27 '18 at 18:36
-
> Why do the bins not go 0 0 0 0 0 and then 0 0.1 0 0 0 and then 0 0.2 0 0 0 and then 0 0.3 0 0 0? The reason is that at a given wavelength you need to fully stimulate the HVS in order to get the outer surface, otherwise you only get a point within the volume. > instead we are constructing arbitrary Spectral power distributions. Absolutely not please re-read my second comment, we are constructing slices of E, and not a random number of slices but all of them for the given number of bins. – Kel Solaar Aug 28 '18 at 07:22
-
> These are all questions where i'm trying to get someone to back-document the algorithm. Well the issue here is that there is not really a clearly defined algorithm nor there is a single path to the result. Getting to that result requires a LOT of work if you are starting bare but the concept behind it is actually super simple although one needs rudimentary in colour science. I will try to write a blog post about it and see if it is possible to retrofit that here. – Kel Solaar Aug 28 '18 at 07:31
You have Lu'v'
coordinates. You may want to check L
and limit the allowable value. Often we do not allow L
being larger then L
of white, but reality (and old television standard) allowed it, just for small period or small surface (else it will become the new white, because of eye adaption).
First step: convert it into XYZ (or any tristimulus coordinates). Wikipedia has one of the formula in https://en.wikipedia.org/wiki/CIELUV#The_reverse_transformation , but care that this is for one specific u
and v
range and specific gamma correction.
Then you convert it to LMS colour space, according e.g. https://en.wikipedia.org/wiki/LMS_color_space
Finally: check that L
, M
, and S
are positive (L, M, S of LMS colour space: note L
is not the same L
of LUV, it this case it stands for Long cone type).
If LMS coordinates are positive, the colour is real and visible. On the other case it is impossible to produce such light.
LSM stands for eye cone response of L, M, and S cone types, so it is the definitive answer on visibility of colours. The problem is: it is difficult to measure single eye cone responses. For this reason you see various conversion matrices between XYZ and LMS. On the other hand the results are similar. Note: because of difficulty of direct measurements, the matrices where derived also indirectly (using method similar to Kel answer, but not just for the surface).

- 8,519
- 2
- 24
- 32
-
1While it is true that if any LMS component is negative it means it is an imaginary color, the opposite is not true. It is not true that a color with all positive LMS components are real. For example the LMS color (1,0,0) is impossible; because if you have some stimulation of the Long cone, you will always have some (small) stimulation of the Medium and Short cones. LMS being positive is necessary, but not sufficient, to decide if a color is non-imaginary. – Ian Boyd Aug 02 '18 at 02:20
-
@IanBoyd: you are right, I forgot that. One may see all such colours, but not all colours are real. On some special experiment one could have just one cone type excited, but this will not happens on real world. So you are correct. – Giacomo Catenazzi Aug 02 '18 at 03:19