sRGB converter using python - Help needed, please.

Hello all
Excuse me if this will be a noob topic, but I’m a bit lost here.
Also I’m not a big programmer, so that’s why I’m reaching out for help here.

So I have several thousands of brand diffuse colors in sRGB that I need to have converted to ACEScg (in Python) - For reasons we need to have the values as text/values.
I tried googling a bit, and came across this link: Converting linear sRGB to ACEScg with Python
It’s however not giving me results that seem to be correct, so I must be doing something wrong.

I then came across this website by Travis Saul: acescolorspace - convert rgb
And if I select: Utility - sRGB - Texture as source, and ACES ACEScg as target, then my source rgb value in 8bit is exactly as it’s supposed to be ( or at least i think so, see screenshot)

We are using the cg-config-v1.0.0_aces-v1.3_ocio-v2.0.ocio - And basically i want the same conversation that is happening for a sRGB - Texture file. So I looked in the ocio config file and found this:

- !<ColorSpace>
    name: sRGB - Texture
        - !<MatrixTransform> {matrix: [2.52168618674388, -1.13413098823972, -0.387555198504164, 0, 
                                      -0.276479914229922, 1.37271908766826, -0.096239173438334, 0, 
                                      -0.0153780649660342, -0.152975335867399, 1.16835340083343, 0, 0, 0, 0, 1]}
        - !<ExponentWithLinearTransform> {gamma: 2.4, offset: 0.055, direction: inverse}

So i tried using that matrix instead, which gave me wrong results, and then i tried inverting it here
That is giving me some results that are somewhat close but not quite there yet.
So I must be missing a step with the either the gamma or the offset?

My code looks like this at the moment:

import sys
import numpy as np

srgb_to_acescg =   [[0.43260881189592323433, 0.33832109964908098541, -0.17136898545690610829],
                    [0.085943797723621734423, 0.7890671459034856329, -0.093505214619263864719],
                    [0.016946899561880128295, 0.10776750889455422348, 0.8414069615370583996]]

def mult_vector3_matrix3(v, m):
    """ Multiplies the first three components of a vector by a 3x3 matrix. """
    v_out = [m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2],
             m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2],
             m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2]]
    # Remaining components (alpha)
    if len(v) > 3:
        v_out += v[3::]
    return v_out

def calculate_aces_color():
    """ Calculate Color Conversion """
value_srgb = (183/255, 0/255, 0/255)
calculate_acescg = mult_vector3_matrix3(value_srgb, srgb_to_acescg)
value_acescg = np.around([calculate_acescg], decimals=7)

print(value_acescg)

The result of that is: [[0.3104604 0.0616773 0.0121619]]
Which is sort of close.

Is there some kind soul in here that can help me out altering the code for a correct result?
But that can maybe also explain to me where it’s going wrong, and why that is?
I would be forever grateful :pray:

P.S. We are using Maya 2022.

Thank you.

Hello, for anything color manipulation I recommend to have a look at the colour library. That will avoid you a lot of trouble and mistakes.

Here is what you want to achieve using it :

import colour
import numpy

COLORSPACE_sRGB = colour.RGB_COLOURSPACES["sRGB"]
COLORSPACE_ACEScg = colour.RGB_COLOURSPACES["ACEScg"]


def main():
    source = numpy.array([183, 0, 0], dtype=numpy.core.uint8)
    converted = source.astype(dtype=numpy.core.float32) / 255
    converted = colour.RGB_to_RGB(
        converted,
        COLORSPACE_sRGB,
        COLORSPACE_ACEScg,
        chromatic_adaptation_transform="CAT02",
        # remove the sRGB transfer-function
        apply_cctf_decoding=True,
        # ACEScg defined a linear encode so will not do anything anyway
        apply_cctf_encoding=True,
    )
    print(converted)


if __name__ == "__main__":
    main()
1 Like

When looking at the OCIO config you probably need to know that the matrices are going to/from the config’s reference space, so you would need to combine the matrix from ACEScg → ACES 2065-1 and the inverse of the sRGB → ACES 2065-1, which is why you probably did not come up with the right answer.

Liam’s suggestion of using the colour library is doing things directly, but the numbers should be almost bit the same as the config as that is how the numbers in the config are calculated.

Kevin

1 Like

You can use this web app (which uses the Colour Science Python library) to calculate the matrix.

Does that webpage have CIE XYZ? I don’t see it in the drop downs, but perhaps it’s labeled differently?

It wasn’t possible until 5 minutes ago! Previously you had to select a chromatic adaptation transform, which is not normally appropriate for getting an XYZ matrix. Now you can choose DCDM XYZ and “none”.

Thanks @Thomas_Mansencal for updating it based on my suggestion.

E.g. this

I do also have the RGB to XYZ matrices of some common colour spaces on the Colour Space Reference pages of my website (these pages are also generated using Colour Science for Python under the hood).

2 Likes