Creating a standalone image colorspace converter for ACES

Hey everyone , after using ACES in my workflow since quite some times now I finally had enough Python skills to start developing a stand-alone application to convert textures & such for an ACES utilisation.

This tool target an utilisation in the vfx/animation domain by providing options for converting input image into a desired colorspace with different export options such as the format and others,… This mean video data is not supported and camera manufacturer IDTs will be skipped.

The tool is developed with python using the colour-science package and OpenImageIO.
Right now most of the API and GUI is written but I still need to implement some essential functionalities.

I am here to ask for feedback on my project, to help build a tool which can be the most useful as it can be for its users and be sure that the tool create correct images .

First here is the current look on the interface:

(of course wip, some elements need to be fixed but this is to give a preview of the features).

Functionalities

Utilisation:

Load the images you want to convert .
Assign the corresponding IDT to each image.
Tweak your export Options.
Convert.

Features:

-List view of image on the left ( with planned support for image sequence displayed in one line ; import of folders).

-Target colorspace for all the file
List of target colorspaces:

'ACEScg',
'ACES2065-1',
'ACEScc',
'ACEScct',
'sRGB',
'Adobe Wide Gamut RGB',
'ITU-R BT.2020',

-ODT option: apply an ODT to your file (if export format is Integer).
List of ODT available:

'sRGB(ACES)'
'rec709(ACES)'
'P3D60(ACES)'
'P3D65(ACES)'
'sRGB(EOTF)'
'Gamma 2.2' # don't know if really usefull
'Maybe filmic ?'

Export Options:

Export format: .exr , .jpg, .png

Bit depth(depending of the format): 8bit Int 16bit Int 16bit Half 32bit Float

Compression (for exrs)(a threshold for compression level for dwaa and jpeg is added on the right)
[none, rle, zip, zips, piz, pxr24, b44, b44a, dwaa, dwab]

Per file options:

Input colorspace (IDT), it will be presented like in the ocio config:

'sRGB-Linear',
'sRGB-Texture', 
'rec709-Texture' # not sure about this one just , it mean rec709 primaries with applied oetf
'ACEScg',
'ACES2065-1',
'ACEScc',
'ACEScct',
'XYZ'

More options:

I will probably had some advanced options in the settings like changing chromatic adaptation (currently Bradford), file exported prefix,…


So now if you have any suggestion , you see incorrect naming, … feel free to talk about. Especially for the IDT/ODT/Colorspace lists, i’m trying to keep the essential but I might have missed some of them.

Last point, i don’t know if i can talk about more technical stuff here. To have some feedback about my utilisation of oiio and colour-science.

7 Likes

Hello and welcome @MrLixm,

Quite cool! How are you intending to package it for users?

Cheers,

Thomas

That is the moment.

1 Like

@MrLixm think this is something I’ve been waiting for for a long time. I’d like to convert RAW images from still cameras to ACES so I can use them to make LUTs for onset purposes. I see that you already have SRGB and ADOBE RGB on there so it could work. That being said it would be great to be able to convert directly from RAW/LINEAR to ACES. I’d really like to try it. Is it possible?

1 Like

Is there an ADOBE RGB IDT available?

Thanks Thomas , yes it is intended to be packed and distributed to be used by anyone.

1 Like

@chuckyboilo Thanks for your feedback Charles ;
Converting RAW camera file to ACEScg is something that I have in mind but that will not be implemented now as it requires me to learn more about debayering and stuff like that that I don’t master for now.

I will add the Adobe RGB(1998) and Adobe wide gamut to the idt and target colorspaces list.

Some technical stuff:

(if this is to much out-of-topic for this forum delete the post)
As mentioned I would like to offer an option to apply an ODT when outputting Integers files, which offers the possibility to just import a render(exr) and output a preview of it with the ODT.
As I am not using OCIO I have to apply the ODT manually using OIIO or colour-science.

Right now I am using colour-science reading and applying Lut methods to dot that. From reading the ACES config.ocio I see that Output-sRGB for example is using 2 luts: InvRRT.sRGB.Log2_48_nits_Shaper.spi3d and Log2_48_nits_Shaper_to_linear.spi1d.

With that in mind I assumed that I could apply an ACES ODT using the corresponding lut but I would like to know if this is as simple as that ? Just input float linear ACEScg data, apply the 2 luts in the right order, which output me normalised data that I can save in an Integer format like jpg ?

Here is my current code:

    def apply_odt(self, in_rgb, odt):
        """
        in_rgb:pixel data as numpy array
        """
        lut_path = os.path.join(self.resources_path, "luts")  # linking the path to the  luts folder
        lut_list = ODT_DICO.get(odt) # get the lut path corresponding to the choosen odt
        lut_1 = colour.io.read_LUT_SonySPI3D(os.path.join(lut_path, lut_list[0]))  # linking the path to the .spi3d luts
        lut_2 = colour.io.read_LUT_SonySPI3D(os.path.join(lut_path, lut_list[1]))
        apply_lut_1 = lut_1.apply(in_rgb)
        apply_lut_2 = lut_2.apply(apply_lut_1)
        return apply_lut_2

What i am missing right now is the interpolation mode which should be tetrahedral for the first lut and linear for the second one. Even with reading the colour-science doc I can’t figured who to do that for now.

So am I in the right direction ?

Thanks.
Liam.

@MrLixm Cool! Can’t wait to try it out with ADOBE RGB and SRGB. It’s still very usable!

There’s a bunch of people that can help out with this (not me! hahahaha).

@nick come to mind for me. @ACES maybe could help a little bit also?

Thanks!

You need to apply the .sp1D shaper LUT first, followed by the .spi3D LUT. But the shaper LUT needs to be applied in the reverse direction, as it is a log to linear LUT, and you are applying it to linear ACES data. I am not sure if Colour has a simple way to apply 1D LUTs in the reverse direction. That is probably a question for @Thomas_Mansencal. However, if you are using the ACES 1.1 OCIO config, I believe the shaper LUTs are in fact simply a 1D ACEScc curve, so you could use the colour.models.log_encoding_ACEScc function instead of the 1D LUT.

Regarding the tetrahedral interpolator, you would use from colour.algebra import table_interpolation_tetrahedral and then pass the argument intepolator=table_interpolation_tetrahedral to LUT.apply as described here.

EDIT:
I just checked, and the table values of Log2_48_nits_Shaper_to_linear.spi1d in the ACES 1.1 config (not the ACES 1.0.3 config) are indeed the results of colour.models.log_decoding_ACEScc(np.linspace(0, 1, 4096))

1 Like

@nick Tkank you very much for your answer ! It seems that i didn’t see that there was .sp1d luts used .
So I used your tips of using the colour method instead of the lut + applying the lut but it seems that i have a red filter on my output image when comparing to my Nuke’s reference.

Here is my code

    def apply_odt(self, in_rgb, odt):
       #  lut_path = os.path.join(self.resources_path, "luts")
        # lut_list = ODT_DICO.get(odt)
        lut_rrt = colour.io.read_LUT_SonySPI3D('/path/Log2_48_nits_Shaper.RRT.sRGB.spi3d')
        lin_to_log = colour.models.log_encoding_ACEScc(in_rgb)
        log_to_rrt = lut_rrt.apply(lin_to_log, interpolator=table_interpolation_tetrahedral)
        return log_to_rrt

EDIT1: By experimenting in Nuke it seems that i have to input an ACES AP0 render to get the correct look. Don’t now where this come from i keep experimenting.

That’s correct. The OCIO display transform LUTs need AP0 input. Nuke/OCIO is applying a conversion from the ACEScg working space to ACES2065-1 under the hood before applying the LUTs.

1 Like

Thanks, so it seems there is a mistake in the colour-science documentation as it specified the input is AP1.

So great the ODT system is now working, let’s finish this UI now.

No. The documentation is correct. ACEScc uses AP1 primaries. The OCIO shaper simply uses the curve of ACEScc as a shaper, but applies it to ACES2065-1 (AP0) image data.

Most renderers supporting OCIO (and so ACES) can output the ODT to the file. Some don’t fully support it but it’s just a question of time. Still a nice feature to have though but nothing high priority in my opinion.

Nice work, keep it up Liam. Looking forward to it.
Best

1 Like

@nick Right my bad. Thanks for the help :+1:
@kn9 You are right i don’t think it is essential but as long as the biggest products like Adobe’s one doesn’t support it i think it is necessary.
Thanks for the feedback !

Absolutely. Just a level of priority on your end.

what is the advantage of this converter comparing to ocioconvert-app?
i compiled sucsessfully all the ocio-apps for windows and use that as a batch converter…
by providing the ocio config, i can use all neccassary input IDTs or output ODTs for converting.
if someone has interest on the windows-build, i can share it here…

1 Like

It would be great to share it of course !
Here i’m providing a graphical interface instead of a command line tool which is a bit easier. Furthermore it allow me to implement whatever i want or what people exactly need.
I’m just trying to simplify the workflow for converting.

Also you can batch convert a lot of file very easily with just a simple drag & drop.

But if you are look for more specific features of course use ocio/oiio build apps

1 Like

yeah, this is cool…is it public yet?

here the windows build of the ocio-apps…maybe they are also usefull for your ui converter…

link:
http://www.soulcage-department.de/ocio_apps.rar

1 Like

Great thanks ! Not released yet. I will post anew topic when it is online.

2 Likes