colour icon indicating copy to clipboard operation
colour copied to clipboard

[FEATURE]: Add colourspace XYB from JPEG-XL

Open zeroby0 opened this issue 2 years ago • 3 comments

Description

Hi!

Please add support for colour space XYB. There is two variants of XYB, one defined in Google/Butteraugli and the other in JPEG-XL (and PIK)

Here is numpy code to convert to and fro from XYZ and Jpeg-XL's XYB. I'll create a pull request after 20th March if no one has done so by then :)

def xyz_to_xyb(xyz):
    mat_xyz_to_lms = np.matrix([
        [ 0.3739,  0.6896, -0.0413],
        [ 0.0792,  0.9286, -0.0035],
        [ 0.6212, -0.1027,  0.4704]
    ])

    mat_lms_to_xyb = np.matrix([
        [ 0.5, -0.5, 0.0],
        [ 0.5, 0.5, 0.0],
        [ 0.0, 0.0, 1.0],
    ])

    xyb_bias = 0.00379307
    xyb_bias_cbrt = pow(xyb_bias, 1/3)

    lmslin = np.inner(mat_xyz_to_lms, xyz).T
    
    lms = np.cbrt(lmslin + xyb_bias) - xyb_bias_cbrt

    return np.inner(mat_lms_to_xyb, lms).T

def xyb_to_xyz(xyb):
    mat_lms_to_xyz = np.matrix([
        [ 2.7253, -1.9993,  0.2245],
        [-0.2462,  1.2585, -0.0122],
        [-3.6527,  2.9148,  1.8268]
    ])

    mat_xyb_to_lms = np.matrix([
        [ 1.0, 1.0, 0.0],
        [ -1.0, 1.0, 0.0],
        [ 0.0, 0.0, 1.0],
    ])


    xyb_bias = 0.00379307
    xyb_bias_cbrt = pow(xyb_bias, 1/3)

    lms = np.inner(mat_xyb_to_lms, xyb).T
    
    lmslin = np.power(lms + xyb_bias_cbrt, 3) - xyb_bias

    return np.inner(mat_lms_to_xyz, lmslin).T

xyz= np.array([
  [1, 2, 3],
  [10, 20, 30]
])

xyb = xyz_to_xyb(xyz)

Credits to Raph Levien for the original code in JS which I ported to Python/Numpy.

zeroby0 avatar Mar 09 '23 14:03 zeroby0

Hi @zeroby0,

Thank you, great idea! This seems to follow the typical IPT-like colour model structure, which we generalise:

  • https://github.com/colour-science/colour/blob/develop/colour/models/ipt.py
  • https://github.com/colour-science/colour/blob/develop/colour/models/common.py#L287

Cheers,

Thomas

KelSolaar avatar Mar 09 '23 19:03 KelSolaar

Awesome!

Once I figure out how to do that, I'll add the procedure here and close the issue. Thank you for the links!

zeroby0 avatar Mar 18 '23 09:03 zeroby0

This seems to be kind of obscure and not documented well, but this tweet seems to indicate the default format of the color space subtracts Y from B to make X = B = 0 for achromatic colors: https://twitter.com/jonsneyers/status/1605321352143331328

You can achieve this by just adjusting the matrix:

[
    [0.5, -0.5, 0.0],
    [0.5, 0.5, 0.0],
    [0.0, -1.0, 1.0],
]

This gives the color space a more practical Lab-like orientation where Y operates as your lightness and X and B change the hue and contrast.

newplot

I guess there are a lot of people implementing it without this adjustment. Anyways, hope this helps.

facelessuser avatar May 01 '23 16:05 facelessuser