# Calculating average of two RGB values

Having 2 RGB values:

• 255, 23, 22
• 201, 18, 122

I want to average them, this link says that really I need to square them first, average, then find the square root. I've seen a few other points that say the same, or closer to the power of 2.2 (and a video of why computer colour is wrong).

Is this really the right way to do it and what is the term for the squaring method? I know the ACTUAL best way is LAB space, but I can't be dealing with that.

• you can read about linear vs gamma color spaces. – filip Aug 16 '18 at 12:17
• Im not sure that Lab is best (and yes its L a b with small a and b) because its not really intended for imterpolation so that would be worng in many ways. Probably better in XYZ – joojaa Aug 16 '18 at 13:07

R (255+201)/2 = 228

G (23+18)/2 = 20.5

B (22+122)/2 = 72

This will depend on your concept of "average".

If it is the average between black and white, I would expect the result to be 128 and the gamma correction done by the graphics card.

But the perceptual reason behind that link is interesting.

The point is that there is not only one way to average, you need to remember that color space is a 3D model, not a linear one.

Take a look at this other posts related:

In this post I show 4 different routes for a color transition between red and green... and that is only on a normal color wheel.

Generating a series of colors between two colors

But the color is not only a 2D surface but a solid, that comes in a lot of shapes, and models.

How do you find an inverse colour?

So, there is not just one universal way to average colors. This depends on a lot of things.

• so am i right (probably not!) that saying taking the rgb's and squaring (or preferably the power of 2.2) is the same process really but is accounting for the gamma (so more in line with how we ACTUALLY see colour?) – karl jones Aug 16 '18 at 13:07
• You would probably need to add "more perceptually correct" to your question. :) – Rafael Aug 16 '18 at 13:08
• so with the case of "more perceptually correct" to work with the power of 2.2, is there any evidence of it? Like anywhere online that says it's more accurate than just averaging? – karl jones Aug 18 '18 at 14:31

Probably youd be better served under computer graphics than graphic design, since it bread and butter there and a bit too much math here. But sice you are allready here. Actually both of the reasonings are close approximations.

It is true that the image is not linear. So you can not assume that adding values results in their sum, therefore not average either. If you want to be correct you need to do a profile to profile conversion*. Tehcnically you would probably assume the profile is sRGB which indeed is close to a gamma correction of 2.2. where the gamma is defined as:

Vout= VinƔ

Except it isn't quite a gamma of 2.2 because it is in fact linear under the values of 0.04045 (or below integer values of 10 in 8 bit color channels). Then because the color planes are independent you can convert it to linear first and calculate and convert back to nonlinear.

* However depends on your definition of correct, if its correct as in as it work in real life then no this does not really work. Since color values used by computers cant capture natural light. You would need spectral data to do this properly. But this is a infinite rabbi thole. Color is not really as easy as most of us think, its harder than they can imagine.

TL;DR Good enugh

The Minute Physics video Computer Color is Broken is good at explaining the problem, but it done has some (small) issue.

He notes that RGB operates on a square root compressed version of actual intensity:

``````+--------------+                      +-----+
| Linear Light |----> √r, √g, √b ---->| RGB |
+--------------+                      +-----+
``````

And so before you try to mix RGB, you need to convert it back to "linear light" by applying the inverse:

``````+--------------+                      +-----+
| Linear Light |<---- r², g², b² <----| RGB |
+--------------+                      +-----+
``````

But the Internet, and nearly all electronics and consumer devices, have agreed to a standard (called sRGB), where they apply something's not quite a square root.

• What you know as a square root can be expressed as: r1/2
• What sRGB calls for is close, but subtly different: r1/2.4

So it's something that's not quiiiiite a square (and square root to undo it).

## sRGB companding is also non-linear

The formula used by sRGB to convert linear light into sRGB encoded light is non-linear:

• for Rlinear > 0.0031308
• Rsrgb = 1.055×Rlinear1/2.4 - 0.055
• otherwise
• Rsrgb = 12.92×Rlinear

In other words, it's very close to simply square-rooting: With the only gotcha of the linear section when you get down really close to zero.

# Math

So typically you need a function that applies this nearly-square root sRGB companding function:

``````r = SrgbCompanding(Rlinear);
g = SrgbCompanding(Glinear);
b = SrgbCompanding(Blinear);
``````

Before you start averaging or mixing colors in RGB, you need to apply the inverse:

``````Rlinear = SrgbInverseCompanding(r);
Glinear = SrgbInverseCompanding(g);
Blinear = SrgbInverseCompanding(b);
``````

Once your R, G, and B are in linear light, you can average them:

``````R3 = (SrgbInverseCompanding(r1) + SrgbInverseCompanding(r2)) / 2;
G3 = (SrgbInverseCompanding(g1) + SrgbInverseCompanding(g2)) / 2;
B3 = (SrgbInverseCompanding(b1) + SrgbInverseCompanding(b2)) / 2;
``````

And then you have to reapply the sRGB companding:

``````R3 = SrgbCompanding(R3);
G3 = SrgbCompanding(G3);
B3 = SrgbCompanding(B3);
``````