Introducing CIECAM02, JCH, etc. in your workflow

I would like to resume the conversation that I started in More on LCH and JCH - #29 by afre. We didn’t really get into the JCH part. In practical processing, in what circumstances do you make use of CIECAM02, JCH, etc., and which software do you rely on? E.g., how do you convert an image to JCH for editing? @Elle @briend and others who generally like to discuss this stuff.

Raw Therapee has some CIECAM controls that look very nice, but I haven’t had a chance to learn more about it. If you want to directly play with CIECAM you might try python w/ colorspacious. This tutorial is pretty easy to follow along and shows some manipulations of saturation, etc:

https://colorspacious.readthedocs.io/en/latest/tutorial.html

Here’s an example of how to change the illuminant. I’m clipping the sRGB to 0-1 which is not good, but it still kinda works for these examples. Also, bear in mind that CIECAM is not just “JCH”, you can substitute “JCh” below with any combination of (J or Q), (C or M or s), and even (H or h). You will get different results when you change these. CIECAM02 - Wikipedia for nitty gritty. I don’t even know if JCh is a good default or if maybe JMh might be better? Has anyone seen/made an exhaustive comparison of these dimensions and their results?

original:
Figure_1-1

hopper_sRGB = plt.imread(matplotlib.cbook.get_sample_data(“grace_hopper.png”))
config_blue = {“name”: “CIECAM02-subset”, “axes”: “JCh”, “ciecam02_space”: colorspacious.CIECAM02Space(colorspacious.cspace_convert((.1,.1, .9), “sRGB1”, “XYZ100”), 20.0, 4.074366543152521,surround=colorspacious.CIECAM02Surround.AVERAGE)}
hopper_cool = cspace_convert(hopper_sRGB, “sRGB1”, “JCh”)
hopper_cool = cspace_convert(hopper_cool, config_blue, “sRGB1”)
hopper_cool = np.clip(hopper_cool, 0, 1)
plt.imshow(hopper_cool)
plt.show()

If you think that looks bad, this was with sRGB (0.1, 0.1, 0.9) as the illuminant. Pure blue is even worse:

Figure_1_pure_blue

We can also use some standard illuminants like “A” which are easier to setup:

config_warm = {“name”: “CIECAM02-subset”, “axes”: “JCh”, “ciecam02_space”: colorspacious.CIECAM02Space(“A”, 20.0, 4.074366543152521,surround=colorspacious.CIECAM02Surround.AVERAGE)}

Figure_1

I haven’t figured out how to do exactly the same in Raw Therapee, but I was able to get pretty close adjusting the viewing condition illuminant to “A”. Here’s RT below. I’m not sure why the brightest white and the dark flag behind is different between them. Maybe @jdc knows more :slight_smile:

Figure_1-1_RT

Finally, since colorspacious seems oriented to sRGB, if you want to manipulate wider gamuts like ProPhoto I think that’s possible if you can convert your image to sRGB without gamut mapping (aka unbounded mode), or for that matter skip sRGB and just use XYZ. Unless I’m mistaken this shouldn’t be a problem since all these manipulations are happening in CIECAM, not RGB.

@briend Thanks for your reply. I still haven’t set up Python on my win7 machine. Just been reading up on the magical world of CAMs here and online and would like to see how it could make my processing more nuanced and otherwise interesting.