6

Imagine a typical device gamut on CIE xy diagram:

enter image description here

x and y coordinates for primary colors (red, green and blue) is defined and known, how to calculate secondary colors (cyan, magenta and yellow)?

mattdm
  • 143,140
  • 52
  • 417
  • 741
Jeka
  • 163
  • 4
  • 2
    This is interesting, and obviously color is relevant to photography in general, but could you spell out the particular photographic application you have in mind here? – mattdm Mar 01 '16 at 17:39
  • @mattdm I working with projectors and color matching between them – Jeka Mar 02 '16 at 15:35
  • What are cyan, magenta, yellow which you are talking about? Are they blue+green, red+blue, red+green respectively? – Euri Pinhollow Aug 02 '16 at 21:21
  • @EuriPinhollow As I mentioned before I am working with color matching system with projectors. In each projector menu I have to set real measured CIE xy coordinates for primaries R,G,B. Then I have to calculate common reachable gamut. It's is easy to calculate R,G,B coordinates of it, but projector also require C, M, Y, which I have to calculate somehow. – Jeka Aug 03 '16 at 10:07
  • @jeka: should not they be measured too? If you have a LUT (i.e. not matrix) profile for your projector you can deduce those coordinates from it. – Euri Pinhollow Aug 03 '16 at 10:14

1 Answers1

6

Performing the operation directly using the chromaticity coordinates (ie: taking the midpoint between the two chromaticity coordinates) will yield incorrect results as the chromaticity diagram is highly non uniform.

Assuming you are using linear light values you could perform the following chain of computations:

  • CIE xy to CIE xyY (Optional) for each pair of chromaticity coordinates where the Y Luminance value is retrieved from the sRGB normalised primary matrix. It is important to acknowledge that when you are using chromaticity coordinates alone you don't have any Luminance information which can also produce unexpected results.
  • CIE xy to CIE XYZ for each pair of chromaticity coordinates
  • CIE XYZ to sRGB for each pair of tristimulus values
  • sRGB add of your pair of RGB values
  • sRGB to CIE XYZ of you resulting RGB values
  • CIE XYZ to CIE xy

Now this is likely more dedicated to SO but you could use colour to perform those computations:

% matplotlib inline

import numpy as np
import pylab

import colour
from colour.plotting import *

# Conversion from RGB to chromaticity coordinates.
# Defining RGB values for reference.
RGB_r = np.array([1, 0, 0])
RGB_g = np.array([0, 1, 0])

# We assume they are encoded in *sRGB* colourspace.
XYZ_r = colour.sRGB_to_XYZ(RGB_r, apply_EOCF=False)
XYZ_g = colour.sRGB_to_XYZ(RGB_g, apply_EOCF=False)

# Conversion to chromaticity coordinates.
xy_r = colour.XYZ_to_xy(XYZ_r)
print(xy_r)
# [ 0.64  0.33]

xy_g = colour.XYZ_to_xy(XYZ_g) 
print(xy_g)
# [ 0.3  0.6]


# Conversion to CIE xyY in order to maintain Luminance ratios.
# Using sRGB Luminance ratios, second row of the NPM.
xyY_r = [0.64, 0.33, colour.sRGB_COLOURSPACE.RGB_to_XYZ_matrix[1, 0]]
xyY_g = [0.3, 0.6, colour.sRGB_COLOURSPACE.RGB_to_XYZ_matrix[1, 1]]

xy_s = colour.XYZ_to_xy(
    colour.sRGB_to_XYZ(
        colour.XYZ_to_sRGB(colour.xyY_to_XYZ(xyY_r), apply_OECF=False) +
        colour.XYZ_to_sRGB(colour.xyY_to_XYZ(xyY_g), apply_OECF=False)))
print(xy_s)
# [ 0.41930366  0.50525886]

# Plotting.
RGB_colourspaces_CIE_1931_chromaticity_diagram_plot(
    ('sRGB', ),
    bounding_box=(-0.1, 0.9, -0.1, 0.9), 
    standalone=False)

pylab.plot(xy_r[0], xy_r[1], 'o', markersize=15, color=RGB_r)
pylab.plot(xy_g[0], xy_g[1], 'o', markersize=15, color=RGB_g)
pylab.plot(xy_s[0], xy_s[1], 'o', markersize=15, color=RGB_s)

Secondary Chromaticity Coordinates

Kel Solaar
  • 849
  • 4
  • 7
  • I stand corrected :-). Nice Python package BTW. – TFuto Mar 02 '16 at 14:27
  • Thanks, looks promising, I am going to implement it in C++ but thanks for python code. Could you explain why we should use sRGB. Also I have luminance data (cd/m2 or foot-lambert) can it be helpfull? to de honest I don't understand optional part where you a sugesting to convert xy to xyY – Jeka Mar 02 '16 at 16:01
  • I have troubles running your code: Traceback (most recent call last): File "C:/Users/Жека/PycharmProjects/SecondaryColors/colors.py", line 6, in from colour.models.rgb.derivation import xy_to_z ImportError: No module named 'colour.models.rgb.derivation'; 'colour.models.rgb' is not a package

    Is xy_to_z is just 1 - x - y?

    – Jeka Mar 02 '16 at 20:16
  • Could you explain why we should use sRGB. I choose sRGB because we have convenient wrappers around it but you could have chosen any RGB colourspace really (XYZ_to_RGB, RGB_to_XYZ). > to de honest I don't understand optional part where you a sugesting to convert xy to xyY With using only the chromaticity coordinates, you don't know what the Luminance is. You may want to pick a Luminance value per chromaticity coordinates that preserve the ratios of human visual system sensitivity to brightness.

    – Kel Solaar Mar 04 '16 at 18:54
  • But this is optional, if you have the Luminance values then it is even better. > I have troubles running your code Ah yeah I'm running that from latest develop branch on Github: github.com/colour-science/colour – Kel Solaar Mar 04 '16 at 18:54
  • By the way we have a Gitter room (gitter.im/colour-science/colour), feel free to pop in or email me directly to further discuss about that as the comments section make it highly inconvenient. :) – Kel Solaar Mar 04 '16 at 18:54
  • Wavelength markers are not clearly visible when you export the file for some purpose. Can you make it better so that it can be useful for purpose. – vishal Aug 02 '16 at 19:13
  • @vishal: Just change the color argument in the three last lines (pylab.plot(xy_s[0], xy_s[1], 'o', markersize=15, color=RGB_s)) to whatever you like: color='black', etc... – Kel Solaar Aug 02 '16 at 20:48
  • @KelSolaar Thank you for this snippet! Can you please explain how to use it for other primaries? I just changed red and green with green and blue and get 0.154|0.0.76 as secondary but this is wrong ... – FLX Mar 04 '24 at 17:39