Creating a standalone image colorspace converter for ACES

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

Hey Wilhelm! Super interested in the batch converter. I tried a few ways to set it up myself, but my Python skills are, well, not really skills lol. I am able to run ocioconvert.exe from command line and convert single textures one at a time. Trying to get it to batch convert textures from a specific folder or directory is where things start to get hairy for me. Ay share of what you have would be killer, or even just insight on how to set that up myself would be appreciated.

That said, what you’ve got going @MrLixm looks absolutely kick ass. Having a standalone app with GUI is exactly what I’ve been looking for. Can’t wait to see it.

2 Likes

hi ryan,

i am doing the batch converting directly in maya with a python script at the moment by selecting textures in the filepath editor and auto-replacing with the converted textures in the file node, but the maya script is very rudimental (no ui, hardcoded) and is suited to redshift renderer.
but i think that a simple .bat with a loop inside can do the job by iterating files in a directory…but i am not so familiar with the .bat syntax…

Hi @MrLixm! Just wondering if you had advanced the GUI version of you app since June. Would be keen on trying it out. Cheers!

1 Like

Hey Charles,
the script is finished since July and you can find it’s topic here:

I will be happy to have your feedback on it ^^