RYB and RGB Color Space Conversion

15.2k Views Asked by At

I am working on a project where I need to convert colors defined in RGB (Red, Green, Blue) color space to RYB (Red Yellow Blue).

I managed to solve converting a color from RYB to RGB space based on the article - Paint Inspired Color Mixing and Compositing for Visualization.

I convert a color from RYB to RGB with this "algorithm":

So the values of r (red), y (yellow), and b (blue) are known, also these arrays/sets are constants:

white: [1, 1, 1]
red: [1, 0, 0]
yellow: [1, 1, 0]
blue: [0.163, 0.373, 0.6]
violet: [0.5, 0, 0.5]
green: [0, 0.66, 0.2]
orange: [1, 0.5, 0]
black: [0.2, 0.094, 0.0]

here is how I calculate the value of red for the RGB space based on the parameters above:

i = 1;
rgb_red = white[i] * (1 - r) * (1 - b) * (1 - y) + 
red[i] * r * (1 - b) * (1 - y) + 
blue[i] * (1 - r) * b * (1 - y) + 
violet[i] * r * b * (1 - y) + 
yellow[i] * (1 - r) * (1 - b) * y + 
orange[i] * r * (1 - b) * y + 
green[i] * (1 - r) * b * y + 
black[i] * r * b * y);

for rgb_green exactly the same thing but for i=2, and i=3 for rgb_blue.

My problem is that now I want to convert from RGB to RYB back. In other words, knowing the values of rgb_red, rgb_green and rgb_blue I want to calculate the values of r, y, and b. So I need a kind of inverse function for this, but I don't know how to get it.

Any help is appreciated.

3

There are 3 best solutions below

1
On

When i wrote a program to convert between all majorly used color formats, i used the following algorithms for $RYB \rightarrow RGB$ and $RGB \rightarrow RYB$ conversion: http://www.insanit.net/tag/rgb-to-ryb/ (link to archive.org, original site is gone)

Now I don't know if this solution works perfectly with the conversion you already have, it looks like some kind of matrix multiplication. If we split $(1-r)(1-b)(1-y) = 1 - r - b - y + rb + ry + by -ryb$ we have 8 components. Also we have 8 components white[i], red[i], orange[i], yellow[i], ... so you can make it a matrix multiplication and add the values of the resulting vector to obtain $r$ (when $i=1$). Now to make an inverse matrix we need more information about the resulting vector. If we just add everything that is in the vector, we lose that information. I still think it is possible to do it with a matrix, but i dont know how to create one, other than making some assumptions like $\text{white}[i]=[1,1,1]$ (which i think will be for inverse as well), and explain why that would be true.

2
On

Having read the linked paper, I now understand a lot more of what you are doing here than what you have explained. And I think I can help solve your problem.

The authors perform the conversion from RYB to RGB via a trilinear interpolation. In essence, they provide explicit values of a mapping from RYB to RGB on the corners of an RYB cube—i.e. every point $(r,y,b)$ where $r$, $y$, and $b$ are all $1$ or $0$—and they linearly interpolate along the three axes everywhere else.

Let us call that mapping $f: \textrm{RYB} \rightarrow \textrm{RGB}$, where $f$ takes an $(r,y,b)$ triplet to an $(R,G,B)$ triplet. (I will use lowercase for RYB and uppercase for RGB throughout.) The interpolation is defined by the following facts: $$\begin{align} \textrm{RYB}&\rightarrow\textrm{RGB}\\ f(0,0,0)&=(1,1,1)\\ f(0,0,1)&=(0.163, 0.373, 0.6)\\ f(0,1,0)&=(1,1,0)\\ f(0,1,1)&=(0, 0.66, 0.2)\\ f(1,0,0)&=(1,0,0)\\ f(1,0,1)&=(.5,.5,0)\\ f(1,1,0)&=(1,.5,0)\\ f(1,1,1)&=(0.2, 0.094, 0.0)\\ f(r,y,b)&=f(0,0,0)(1-r)(1-y)(1-b)+f(0,0,1)(1-r)(1-y)b\\ &\;+f(0,1,0)(1-r)y(1-b)+f(1,0,0)r(1-y)(1-b)\\ &\;+f(0,1,1)(1-r)yb+f(1,0,1)r(1-y)b\\ &\;+f(1,1,0)ry(1-b)+f(1,1,1)ryb \end{align}$$ where the subscript $c$ denotes a value at the corners.

You now want to solve the opposite problem. You want a function $f^{-1}: \textrm{RGB} \rightarrow \textrm{RYB}$ which takes a triplet $(R,G,B)$ to a triplet $(r,y,b)$. It seems to me that an easier problem to solve is to go through the same process as the authors of the linked paper did: find the RYB values of all the colors at the corners of an RGB cube and interpolate between them. This will give you a function $F: \textrm{RGB} \rightarrow \textrm{RYB}$ which might not be exactly equal to $f^{-1}$ but will hopefully be close enough for what you need.

$$\begin{align} \textrm{RGB}&\rightarrow\textrm{RYB}\\ F(0,0,0)&=?\\ F(0,0,1)&=?\\ F(0,1,0)&=?\\ F(0,1,1)&=?\\ F(1,0,0)&=(1,0,0)\\ F(1,0,1)&=?\\ F(1,1,0)&=(0,1,0)\\ F(1,1,1)&=(0,0,0)\\ F(R,G,B)&=F(0,0,0)(1-R)(1-G)(1-B)+F(0,0,1)(1-R)(1-G)B\\ &\;+F(0,1,0)(1-R)G(1-B)+F(1,0,0)R(1-G)(1-B)\\ &\;+F(0,1,1)(1-R)GB+F(1,0,1)R(1-G)B\\ &\;+F(1,1,0)RG(1-B)+F(1,1,1)RGB. \end{align}$$

The task that remains is to fill in those blanks. I would recommend coding up $f$ in something like Mathematica and finding the values $(r,y,b)$ where $f(r,y,b)=(R_c,G_c,B_c)$ for the values at the corners of the RGB cube. Then set $F(R_c,G_c,B_c)=(r,y,b)$ for the values you just found. Good luck!

1
On

I want to sketch another approach which constructs a conversion functions between $RGB$ to $RYB$ color spaces. Especially I give a proper solution for conversion back to $RYB$.

First of all let's observe that $F: RYB\to RGB$ is an into function and transforms $RYB$ unit cube into a polyhedron included in the RGB unit cube. So we need to find a way to create $F^{-1}$ which transforms polyhedron to the $RYB$ cube.

To make this happen we can make the following:

  1. Decompose a cube into a six tetrahedra (this answer describes the coordinates and tests: https://cs.stackexchange.com/a/90011)
  2. Create an affine transformation with the following procedure for finding a mapping between any two tetrahedra both ways, which is described: https://people.sc.fsu.edu/~jburkardt/presentations/cg_lab_mapping_tetrahedrons.pdf

Having above we will end up with six functions from $RYB$ to $RGB$ and another six functions from $RGB$ to $RYB$. One pair per each tetrahedron.

Now we face a problem of selecting proper mapping. For:

The last problem is: is it possible to find a mapping from whole $RGB$ cube into some extension of $RYB$ space? I think we can use the closest tetrahedron and its mapping. An open question is: which is the closest? Possibly that which has lowest sum of abs of barycentric coordinates.

EDIT: the above procedure has one disadventage, transition between colors is not smooth. Mainly due to not uniform transformation of tetrahedra.

The other approach I found is to use general barycentric coodinates. Wachspress coordinates are quite easy to calculate and transform. See:

  • p. 11, 4.4 Barycentric mapping
  • p. 26, 8 Coordinates in higher dimensions

in the following paper: https://www.mn.uio.no/math/english/people/aca/michaelf/papers/gbc.pdf