3

When we look at the 1931 CIE chromaticity diagram, represented within the x y plane of xyY space, it renders white colors (or close to white) at points of luminance like the D65 point highlighted here with E.

1931 cie chromaticity diagram

But why is this the case? The point for D65 is supposed to be represented at x = 0.33, y = 0.33. Given the formula Y = 1 - x - y, wouldn't that mean Y is 0.34?

The sRGB correlate or xyY at 0.33,0.33,0.34 is 158.4182, 155.5676, 176.8565 according to every converter I found. This is a light brown and not the near-white seen in every 1931 chromaticity diagram.

It seems like I need to scale the Y to get the proper luminance value for every channel.

Using the Y = 1 - x - y formula, my diagram looks like this, a muted diagram:

Wrong chromaticity diagram

What don't I understand?

Edit

Setting Y = 1 and the diagram looks like the below, better.

enter image description here

Edit

Now looks like the below.

enter image description here

Union find
  • 7,759
  • 13
  • 60
  • 111

2 Answers2

2

The white point of CIE 1931 is not in x=1/3, y=1/3, and white color is not x=1/3, y=1/3, Y = 1/3.

According to Wikipedia:

The CIE 1931 color space chromaticity coordinates of D65 are
x=0.31271
y=0.32902

Since D65 represents white light, its co-ordinates are also a white point, corresponding to a correlated color temperature of 6504 K. Rec. 709, used in HDTV systems, truncates the CIE 1931 coordinates to x=0.3127, y=0.329.

The meaning of x=1/3, y=1/3 is different:

Light with a flat power spectrum in terms of wavelength (equal power in every 1 nm interval) corresponds to the point (x, y) = (1/3, 1/3).

Important: D65 is not a "flat power spectrum".

Computer systems (PCs) uses sRGB color format.
In sRGB the color components are after gamma (in contrast to CIE 1931 which applies linear curve).

In xyY color space, x,y are the chromaticity and Y is the luminance.
x=0.31271, y=0.32902 is the chromaticity without luminance and applies gray chromaticity.
For white color use Y = 1


Rec. 709, used in HDTV systems, truncates the CIE 1931 coordinates to x=0.3127, y=0.329

Lets compute sRGB of x=0.3127, y=0.329, Y = 1:

X = (Y/y)*x = 0.95046
Y = 1
Z = Y/y*(1-x-y) = 1.0891

Rlinear 3.240600 -1.537200 -0.498600 X 0.99984
Glinear = -0.968900 1.875800 0.041500 * Y = 1.00010
Blinear 0.055700 -0.204000 1.057000 Z 1.00007

Assume result is 1, 1, 1.

Last stage is applying gamma for converting "Linear sRGB" to sRGB.
Since all values are 1, the result is sRGB = 1, 1, 1.


We can repeat the computation for Y = 0.2, and the result is Linear sRGB = 0.2, 0.2, 0.2.

Apply gamma:
gamma(u) = 1.055*u^(1/2.4) - 0.055 for u > 0.0031308

1.055*0.2^(1/2.4) - 0.055 = 0.48453
So sRGB = 0.48453, 0.48453, 0.48453.

For converting to the standard range of [0, 255] (one byte per color channel), we need to scale by 255 and round the result: RGB888 = 124, 124, 124.

Rotem
  • 30,366
  • 4
  • 32
  • 65
  • Got it. Looks like just updating my Y value to 1 did the trick. I will digest all of this, though. It's fantastic. – Union find Jun 19 '19 at 15:07
  • I had a final project in my MSc degree about the subject, and it is extremely confusing. At start I also though that XYZ = `1/3, 1/3, 1/3` is white. – Rotem Jun 19 '19 at 15:10
  • I read that somewhere.. There is a lot of mixed information out there. – Union find Jun 19 '19 at 15:11
  • I can't understand what the other respondant said. Do you know what he means about clipping? in your step, should I get the maxsrgbLinear(r,g,b) and normalize all the linear srgb values before applying gamma? – Union find Jun 21 '19 at 17:13
  • In case you select Y in range [0, 1] the linear srgb result is normalized to range [0, 1]. Clipping is required in cases where linear srgb falls outside the gamut of srgb (when x,y are outside the triangle - colors that can't be displayed in sRGB color space). – Rotem Jun 21 '19 at 22:01
  • Is it normalized before the gamma or after? – Union find Jun 21 '19 at 22:04
  • Before and after... The gamma formula (as defined in my answer) is from range [0, 1] to range [0, 1]. – Rotem Jun 21 '19 at 22:11
  • In case x,y are outside the triangle, I don't really know how to clip it correctly (before the gamma for sure). Normalization after clipping may be needed. – Rotem Jun 21 '19 at 22:14
1

There is some imprecision on the interpretation of chromacity diagrams.

CIE xyY is a 3D figures. Often we see only a projections (often not a intersecting plane, just a projection).

One common projection is the "additive" xy chromacity diagram. You may notice it because it has yellow at border, and the white somewhere near the center. In such projection you show the maximum Y given a chromacity x,y.

Common is also the "subtractive" diagram, like your second one. No yellow, no white. This diagram has just the subtractive mix of the primaries, so the brighter colour are the primaries, and you get darken between them.

Note: usually the chromacity diagram are also extended also out of gamut, so the primaries are no more the real primaries, and white could not be white, and the yellow could be cut off, as your diagrams. You may try at first just the triangle between primaries, then expand. It is easier to debug.

The white will be just on top of 3D figure. In the first case, you take the outer surface of gamut, so you get the white. In the second case, you get a plane inside the figure, so you will never get white. But it is still a xy chromacity diagram.

On your case, I think you clipped the colour values (Note 1), which it is wrong: by clipping you will not get the correct chromacities (by clipping, one remove a certain value of a colour, so the ratio between channel is not maintained). One should use float or larger numbers for calculations, before to normalize (channel values in range 0 to 255). [Normalize (in this case): keep chromacity, but adapt Y so that final colour is in gamut]. In practice: you get the maximum value between R, G, B, and you multiply every channels by 255/max(R,G,B).

Note: this is not fully correct/precise. The above normalization should be done in linear space (light mix linearly), and only after normalization, the gamma funtion should be applied. On the other hand, on above figures, we do not have the correct colour for every point x,y. We can do it correctly only on a triangle (of gamut). By expanding the available colour on screen to full xz chromacity, we create errors/imprecisions. So normalization before or after gamma correction is not more so relevant (and it just change slightly the colours).

Note 1: From comment: this (clipping) it is not true, OTOH the very tiny part of blue (dark blue), and too much magenta and cyan, make me thinking about some numerical prolem)

Giacomo Catenazzi
  • 8,519
  • 2
  • 24
  • 32
  • Can you clarify the last paragraph a bit? I had a hard time understanding. – Union find Jun 20 '19 at 15:52
  • I did not clip the rgb values. – Union find Jun 20 '19 at 20:38
  • 1
    @Learningstatsbyexample: I updated the last part of the answer. You didn't clip? There is something strange: you have just a very small region of blue (dark blue/indigo), and too large regions magenta and cyan. – Giacomo Catenazzi Jun 21 '19 at 06:03
  • I updated my question to show how the diagram looks with Y = 0.9749629514078465; I need to look into the blue issue. – Union find Jun 21 '19 at 12:10
  • I'm really having a hard time understanding your answer. You're saying, before applying the gamma transform, get the max(r,g,b) and multiply every channel by 255/max(R,G,B)? – Union find Jun 21 '19 at 16:58
  • I updated my answer to show the latest diagram. I took the largest value after the linear sRGB scale (1.52), then multiplied all r,g,b values by (1/1.52) before the gamma transform to get sRGB'. Multiplied by 255 to get sRGB8 ([0 to 255 scale]) – Union find Jun 21 '19 at 17:32
  • More clearly stated: I updated my answer to show the latest diagram. I first did the BradfordD65 transformation on XYZ. Then I took the XYZ and did the linear sRGB scale transformation. The largest value is about 1.4. So I multiplied all r,g,b values by (1/1.4) before the gamma transform to get sRGB'. I then multiplied by 255 to get sRGB8 ([0 to 255 scale]) – Union find Jun 21 '19 at 17:49
  • I have also hard time to understand exactly your question: we lack of your code and what you are doing. Giorgianni and other great experts on colours tell us NEVER EVER to use colours in CIE xy diagrams, because this would just confuse people. So never think it will describe correctly the colours (so do not use it to try to understand colours). I think you should tell in the question what it is the use of your diagram (so what the information you want to tell users): colour mixing (which one? which use?), comparing gamuts? Comparing hues? And you should tell us how you are generating your fig. – Giacomo Catenazzi Jun 23 '19 at 08:55
  • There is a lot of things we can tell you, but stackoverflow is also not a good site for generic questions, and explainations. If you want to understand colours, you may ev. only display colours within the gamut. It is a lot easier, and you have a lot less problems. Your Y=1 is good, but you should understand that monitor gamut (so RGB) can have Y-1 only on white. So it depends on how you transform colours to RGB (some algorithms try to keep Y as good as possible, my method will keep hue (and chromacity) as precise as possible. (but is it what you want?) – Giacomo Catenazzi Jun 23 '19 at 08:59