Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE]: Add colourspace XYB from JPEG-XL #1118

Open
zeroby0 opened this issue Mar 9, 2023 · 3 comments
Open

[FEATURE]: Add colourspace XYB from JPEG-XL #1118

zeroby0 opened this issue Mar 9, 2023 · 3 comments
Labels

Comments

@zeroby0
Copy link

zeroby0 commented Mar 9, 2023

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 zeroby0 added the Feature label Mar 9, 2023
@KelSolaar
Copy link
Member

Hi @zeroby0,

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

Cheers,

Thomas

@zeroby0
Copy link
Author

zeroby0 commented Mar 18, 2023

Awesome!

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

@facelessuser
Copy link

facelessuser commented May 1, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants