New Primaries module

Looking forward to seeing the preferred way to work with the new module.

I think this would be a good image to experiment with. If you can find a way to share it (Google Drive or some other share) I would be glad to see what’s going on.

Here is a link to the image with the corresponding xmp: Dropbox - sigmoid filmic.7z - Simplify your life

2 Likes

Hi,
Are there some docs about how the “smooth” preset in sigmoid was created? I’d like to understand the logic behind it.

Thanks in advance!

Coming very soon. :slight_smile:

3 Likes

Are there some docs about how the “smooth” preset in sigmoid was created? I’d like to understand the logic behind it.

There is a good starting point here: sigmoid: introduce custom primaries ("AgX-like" processing) by flannelhead · Pull Request #15104 · darktable-org/darktable · GitHub

Here it is: Introducing "primaries" feature for sigmoid

Basically the answer is “eyeballing”, but let’s have a good discussion over at the new thread :slight_smile:

5 Likes

Did the feature in sigmoid replace the module that is the topic for this thread?

No… there’s been two related new developments. There’s the new sigmoid feature, which lets one tweak sigmoid’s colour handling in highlights, and there is also the new ‘rgb primaries’ module, which is essentially a channel mixer (like in color calibration) with a new interface, and intended for general creative or corrective colour adjustments.
The latter I think was an offshoot from some of the work in sigmoid, but is unrelated operationally.

I stand to be corrected… :slight_smile:

Thanks for the clarification @123sg!

1 Like

@flannelhead, would it be possible to document the actual math for how the matrix is formed in RGB Primaries from the slider values?

Eg as a comment here (we have Latex support in Discourse). My C++ is not good enough to understand from the code.

Tamas without looking at the code I suspect the sliders work in a manner to just move the x,y coordinates’ of each primary that define the colorspace. With hue slider rotating it around and purity moving it in and out relative to the current white-point… In a sense it’s as if you grabbed each point with a mouse and dragged to a new location but with up/down and left/right arrow keys (the sliders)

Having made those selections then those new coordinates would be used in something like the standard matrix math of rgb-xyz-rgb to output the new values for further processing… ??

I am sure the code might have some constraints or other parameters to clean things up if needed but overall that is what I think it is doing…

http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html

Hey,

Right now I don’t have the time to typeset the equations or draw pretty pictures. However, the basic principle is kind of simple and can be explained in a few sentences. In the background it is mostly basic 2D geometry and linear algebra, which I find quite boring. What I find more interesting (and useful) is the intent behind these operations.

  1. Calculate a new set of primaries + whitepoint based on user adjustments. Firstly, the primaries of the working space are rotated (with respect to the white point, in xy coordinates) based on the rotation slider input. It is done such that the rotated primaries trace the edge of the working gamut triangle, in order not to escape the gamut if one uses just the rotations. Secondly, the primaries are scaled based on the purity controls (with respect to white point as well). Optionally, the white point is also offset in the given direction (tint hue) by given offset (tint purity).
  2. Given the new primaries and whitepoint, calculate the RGB to XYZ matrix based on the equations from Bruce Lindbloom’s site. I believe this is how these matrices are almost always calculated. The objective of these equations is to start from unbalanced primaries and obtain a balanced RGB system, adjusting the gains of the primaries such that (1, 1, 1) maps to the given white point. Let us call this matrix M_in.
  3. Obtain also the XYZ to RGB matrix of the working color space. We readily have this precalculated in darktable, but it could be calculated in the same way using the equations from Lindbloom’s site. Let us call this M_out.
  4. The final matrix is M = M_out * M_in. The reason behind this ordering: we interpret the incoming RGB values as if they were in the new primaries we just established. Then transform to XYZ, and from there to the working RGB color space.

Hope this answers at least some of the questions you might have. Please feel free to ask for further clarifications. I could try to find the time to draw some pictures of the geometric operations, as that would be worth a thousand words. I don’t think typesetting the equations is as worthwhile as making some figures.

7 Likes

I understand. If you just want to write them down and PM me a photo, I will typeset the equations and post here. (Or suggest corrections to what I write below).

Let’s call C the matrix that maps from RGB to XYZ, and E the white point, R, G, B the CIE 1931 primaries. Let’s discuss the mapping in XYZ space and call it A, the final mapping will be C^{-1}AC.

My understanding from what you write is that A is calculated so that

  1. \overline{ER}, \overline{EG}, \overline{EB} are rotated and stretched according to the sliders in XYZ space, leaving luminance Y constant, and if red/green/blue purity are at 0 then the resulting R', G', B' respectively are on the gamut edge,
  2. E is translated to E', in the direction specified by tint hue, by the amount tint purity.

These are 8 constraints, and A has 9 values, so we need one more, but it is not clear to me what it is.

Thanks for your patience!

I’ll try to do this but it’ll have to wait until next year.

The calculation is not formulated like this. The rotations and scalings are done in the xy part of xyY, so they are 2D operations. A new balanced RGB system is formed from those xy coordinates based on the equations in Lindbloom’s page. It is not the same as doing those in XYZ while keeping the Y constant.

The remaining degree of freedom is exposure. This module keeps the achromatic response constant (unless one pushes the tint sliders) and it is desirable to have it like this. Exposure would not be very useful as an additional DOF in this module.

1 Like

No worries, it is not urgent at all. I just want to understand eventually.

Then I am confused: you claim that the operation is linear, but a rotation/scaling in xy is not a linear operation in XYZ (xy is a nonlinear projection of the latter).

You can see another way of doing it in Rawtherapee

  • Whether with “Abstract profile” (Color tab), followed for example (there are other uses) by “Color Appearance and Lighting” (Advanced tab)

https://rawpedia.rawtherapee.com/Color_Management#Abstract_Profiles

And available executables
https://github.com/Beep6581/RawTherapee/releases/tag/pre-dev-github-actions

In both cases, you can act on the primaries (and see CIExy diagram), but also on the illuminant (stdA, D50, D60, D65, …) and the TRC (Tone Response Curve).

If you are interested, I can explain the functionalities and algorithms

Excuse my bad English.

Jacques

1 Like

It is indeed linear. That is, first a 3x3 matrix is established based on the user parameters. Then all the pixels (RGB) are multiplied by it. Multiplication of a vector by a matrix is, by definition, linear.

Read my first post again. You will find that the rotations and scaling in xy are done when establishing the matrix, to define a new RGB space. The final matrix is then just a transformation from the user-defined RGB space to the working space.

1 Like

Yes, I understand that this is the claim, but, with respect, it is hard to see this from a verbal description.

I will just have to wait for the math then to understand the details.

Basically look at the math to convert any color space and that is mostly it. The user is just defining a custom one essentially. So not much different than say sRGB to adobe or whatever to whatever… these are well documented…

I appreciate that you are trying to help, but you aren’t. Again, I will be happy to wait for specifics from the author, there is no need for hand waving in the meantime.