pythonimage-processingcolorsopenimageio

python OCIO colour space conversions - colour issue


I have a test 16bit tiff file that is using ACEScc colour space: acess_cc

I want to process it using OCIO to, for instance, linear sRGB. OCIO provides examples of how to do it: https://opencolorio.readthedocs.io/en/latest/guides/developing/developing.html and it seems quite trivial to use:

import cv2
import numpy as np
import PyOpenColorIO as OCIO

path = "ACEScc.tif"

input_cs = "ACES - ACEScc"
output_cs = "Utility - Linear - sRGB"

img = cv2.imread(path)

#I use the default config downloaded from OCIO website
config = OCIO.Config.CreateFromFile("config.ocio")
in_colour = config.getColorSpace(input_cs)
out_colour = config.getColorSpace(output_cs)
processor = config.getProcessor(in_colour, out_colour)
cpu = processor.getDefaultCPUProcessor()

#this seems to be missing in the docs. the processor seems to expect floating point values 
#scaled to 0-1 range. Here I might be doing it wrong and this might be causing the colour issues.

img2 = img.astype(np.float32) / 255.0

cpu.applyRGB(img2)

#take it back to 8bit to have something to look at:
img3 = (img2*255.0).astype(np.uint8)

cv2.imwrite(r"ocio_test.tif", img3)

the resulting image is linearised correctly. the values that are out of 8 bit range are clipped (this to be expected and I didn't handle it in any way). However the colours that are not clipped are not right. What am I missing?

srgb linear

here is a closeup of the macbeth chart showing the problem with the colour (left is correct, right is what I get from the above python)

compare

some colour are ok but yellows and oranges are shifted towards pink. I also didn't expect the green plant to be out of range. I tested both with ocio v1 and v2 configs downloaded from here: https://opencolorio.readthedocs.io/en/latest/quick_start/downloads.html

I'm not sure what is the problem here and would love any suggestions.


Solution

  • The problem here lies in the TIFF file that was used to test. It turns out that openCV loaded the the file as BGR (I expected it to sanitise internally and always store data as RGB). Obviously this order is not expected by the matrices in OCIO and was screwing the colours. A simple fix here is to rearrange the channels from BGR to RGB before passing to OCIO:

    img = img[:,:,::-1]