Hacker News new | past | comments | ask | show | jobs | submit login

> However, sRGB is not linear, meaning that (0.5,0.5,0.5) in sRGB is not the color a human sees when you mix 50% of (0,0,0) and (1,1,1). Instead, it’s the color you get when you pump half the power of full white through your Cathod-Ray Tube (CRT).

While true, to avoid confusion, it might be better rephrased without bringing human color perception or even colors into the mix.

sRGB uses non-linear (gamma) values, which are good for 8-bit representation. However, operating on them as normal (linear) numbers using average (expecting blur) or addition, multiplication (expecting addition, multiplication of corresponding light) - gives nonsensical, mathematically and physically inaccurate results, perceived by any sensor, human or animal as not what was expected.

RGB colorspace in it's linear form is actually very good for calculations, it's the gamma that messes things up.

In simplified monochrome sRGB/gamma space, a value v means k·v^g units of light, for some k and gamma g = 2.2. Attempting to calculate an average like below is simply incorrect - you need to degamma¹ (remove the ^g), calculate and then re-gamma (reapply ^g).

  (k*v1^g + k*v2^g)/2 = k*(v1^g + v2^g)/2 != k*((v1+v2)/2)^g
¹ gamma function in sRGB is a bit more complex than f(x) = x^2.2



I always feel we have way too many historical burdens (which were good compromises at the time) in (digital) image/video field.

In no particular order (and some are overlapping), I can immediately think of gamma, RGB/YCbCr/whatever color models, different (and often limited) color spaces, (low-)color depth and dithering, chroma subsampling, PAL/NTSC, 1001/1000 in fps (think 29.97), interlaced, TV/PC range, different color primaries, different transfer functions, SDR/HDR, ..

the list can go on and on, and almost all of them constantly cause problems in all the places you consume visual media (I do agree gamma is one of the worst ones). Most of them are not going anywhere in near future, either.

I often fantasize a world with only linear, 32-bit (or better), perception-based-color-model-of-choice, 4:4:4 digital images (similar for videos). It can save us so much trouble.


That's a bit like saying that we shouldn't use lossy image/video compression.

Do you realize the amount of 'waste' that a 32bpc†, 4:4:4, imaginary color triangle gamut picture would have ?

†it looks like the human eye has a sensitivity of 9 orders of magnitude, with roughly 1% discrimination (so add 2 orders of magnitude). So, looks like you would need at least 37 bits per color with a linear coding, the overwhelming majority of which would be horribly wasted !


I have no issue with lossy compression; but things like 4:2:0 aren't really typical lossy compression. It's like calling resizing an image to half its resolution "compression".

Also lossless compression can reduce plenty of "wasted" bits already (see: png vs bmp).


But they are ! Like other lossy forms of compression, chroma subsampling takes advantage of the human visual system's lower acuity for color differences than for luminance.


I don't think of colorspaces as "historical burdens". I don't like that CRT monitors are brought up every time sRGB is mentioned though. I know it has historical relevance, but it's not relevant anymore, and it's not needed to understand the difference between linear and non-linear colorspaces.


I misunderstood what you mean. Please ignore. On a side note, by colorspace I mainly meant that we can just stick with one with ultra-wide gamut. There are indeed other reasons to have different color spaces.

(Below is my original comment for transparency.)

-------------

Gamma isn't really about CRT; or I should say, they're two different things. The fact CRT has a somewhat physical "gamma" (light intensity varies nonlinearly with the voltage) is likely just a coincidence with the gamma we're talking here.

The reason gamma is used in sRGB is because human eyes are more sensitive to changes in darker area, i.e. if the light intensity changes linearly, it feels more "jumpy" in darker end (which causes perceptible bandings). This is especially an issue with lower color depth. To solve this, we invented gamma space to give darker end more bits/intensity intervals to smooth the perceptive brightness.

>it's not needed to understand the difference between linear and non-linear colorspaces

It absolutely should, since any gamma space would have problem with "averaging", as explained by the GP. Actually, it's so bad that almost all the image editing/representing tasks we have today are doing it wrong (resizing, blurring, mixing..).

This topic has been discussed extensively on Internet, so I'm not going to go into detail too much. A good start point is [1][2].

[1] https://www.youtube.com/watch?v=LKnqECcg6Gw [2] http://blog.johnnovak.net/2016/09/21/what-every-coder-should...


> It absolutely should

The GP just pointed out that the CRT link is not needed to motivate the talk about linear vs non-linear.


You're right, I misunderstood (overlooked the CRT part in OP's article.)


I don't see why you would avoid talking about it.

As far as I've understood, CRT monitor gamma has basically evolved to become the inverse of human eye gamma :

http://poynton.ca/PDFs/Rehabilitation_of_gamma.pdf

(With some changes for a less accurate, but more visually pleasing/exciting replication of brightness levels ?)

Now, with many modern, digital screens (LCD, LED, e-ink?), as far as I've understood the electro-optical hardware response is actually linear, so the hardware actually has to do a non-linear conversion ?

I'm still somewhat confused about this, as I expected to have to do gamma correction when making a gradient recently, but in the end it looked like I didn't have to (or maybe it's because I didn't do it properly : didn't do it two-way?).

Note that the blog author might be confused there too, as just after he says :

> With these conversions in place, dithering produces (more) accurate results:

– you can clearly see that the new dithered gradient doesn't correspond to the undithered one ! (Both undithered gradients seem to be the same.)


sRGB gamma is often approximated to 2.2 [1], but the actual function has a linear section near 0, and a non-linear section with gamma of 2.4, possibly to avoid numerical difficulties near 0.

The document you cite claims that CRT gamma is typically between 2.35 and 2.55.

Human eye gamma can probably be approximated with cieLAB, that is designed to be a perceptually uniform colorspace, which seemingly has a gamma of 3 [2], although it also has a linear section, so maybe slightly lower overall gamma. ciaLAB is not state of the art though in perceptually uniform colorspaces.

[1] https://en.wikipedia.org/wiki/SRGB

[2] https://en.wikipedia.org/wiki/CIELAB_color_space

What I don't like about this whole CRT/gamma topic:

1. It brings in perceptually uniform colorspaces to the discussion, while it's completely unnecessary. Perceptually uniform colorspaces are mostly unsuitable for arithmetic on colors like any other non-linear colorspace.

2. While the sRGB colorspace and a colorspace defined by a CRT monitor's transfer function are closer to perceptually uniform than a linear colorspace, they are still pretty damn far from it. sRGB still does a decent job to prevent banding in dark areas.

3. The sRGB colorspace is not identical to a colorspace defined by a CRT monitor's transfer function.

4. "gamma" is a crude approximation for transfer functions, assuming they follow a power function on all of their domain.

5. This whole thing about CRTs and gamma doesn't matter if you just want to understand that if you want to do arithmetic on color components, then you most probably want it represented in a linear colorspace (didn't even talk about it yet), and most color values you encounter is actually encoded in sRGB, so you want to convert that to linear first, then convert the result back, depending on what your output requires. This is the most widespread bug in computer color and you don't need the history of CRTs to do that, and in fact this has nothing to do with perceptually uniform colorspaces.


> ciaLAB is not state of the art though in perceptually uniform colorspaces.

Which are state of the art ?

> 1. It brings in perceptually uniform colorspaces to the discussion, while it's completely unnecessary. Perceptually uniform colorspaces are mostly unsuitable for arithmetic on colors like any other non-linear colorspace.

I don't get what you mean, linearity (dL'star') being defined wrt perceptual uniformity, isn't CIELAB 76 linear by definition (to an approximation) ?? And color arithmetic pretty much by definition implies dealing with distances and angles in a perceptually uniform color space, doesn't it ??

(I would really like to know, since it actually is the very topic of 'practical work' that we have to do for mid-January. We were told to do the transformations to CIELAB 76 and, after the modifications, back to sRGB, using the D65 illuminant.)

Otherwise, I didn't mention the finer details about CRT transfer functions because it didn't seem to be relevant enough.

> This is the most widespread bug in computer color and you don't need the history of CRTs to do that, and in fact this has nothing to do with perceptually uniform colorspaces.

Yeah, I know, and while just doing this kind of transformation might be just good enough for the most common color arithmetic, is it really good enough for all use cases ? To take an example from our practical work, seeing this kind of effect :

https://en.wikipedia.org/wiki/Impression,_Sunrise#Luminance

You know what, I think I'm going to try and do this practical work in two versions, one using just linear sRGB (and back). I'll see if I get noticeable differences. But that will have to wait a week or so, I'm too busy searching for internships right now (and have already spent too much time in this discussion...)


> I don't get what you mean, linearity (dL'star') being defined wrt perceptual uniformity, isn't CIELAB 76 linear by definition (to an approximation) ?? And color arithmetic pretty much by definition implies dealing with distances and angles in a perceptually uniform color space, doesn't it ??

No. Linearity is about physical light intensities relating to perceived color. Imagine having two light sources on the same spot that you can turn on or off separately. If you turn the first one on you perceive a certain color, if you turn the other on you perceive an other color and if you turn both on you perceive a third one. It turns out the perceivable colors (under normal viewing conditions) are representable in a three dimensional vector-space (for most people) so that the first two colors add up to the third color for every possible two light sources. Such a linear colorspace is XYZ for example [1].

This has nothing to do with perceptual uniformity. Perceptual uniformity is about the capability of distinguishing near colors. This defines a distance between colors, and there are three dimensional colorspace representations where the Euclidean distance approximate this perceptual distance well. cieLAB is such a colorspace, but AFAIK there are better state of the art colorspaces for the same purpose. I'm not very well versed in this, I learned from them from this video [2].

[1] https://en.wikipedia.org/wiki/CIE_1931_color_space

[2] https://www.youtube.com/watch?v=xAoljeRJ3lU

edit: gimp 2.10 now defaults to use a linear colorspace (not perceptually uniform!) for most if not all of its functionalities. This affects alpha-blending layers, the paintbrush, resizing, blur, and pretty much everything that involves adding/averaging colors. There is still a "legacy" option on these tools to turn back to the probably wrong sRGB methods, probably for compatibility with old gimp files. There is a dramatic difference when you use a soft green brush on a red background for example, it's worth to try out.


Ok, my bad, I should have re-read our lesson more carefully : we're actually supposed to do sRGB => XYZ > CIELAB (and later back).

And it looks like that you can either have an Euclidean vector (linear) space (linear sRGB, XYZ), or a perceptually uniform one (CIELAB), but not both !?

(I guess that I should have figured that out myself, sigh… this is why it isn't CIELAB that is used for monitor calibration, but CIELU'V' ? EDIT : Nope : "[CIELUV is] a simple-to-compute transformation of the 1931 CIE XYZ color space, but which attempted perceptual uniformity. It is extensively used for applications such as computer graphics which deal with colored lights. Although additive mixtures of different colored lights will fall on a line in CIELUV's uniform chromaticity diagram (dubbed the CIE 1976 UCS), such additive mixtures will not, contrary to popular belief, fall along a line in the CIELUV color space unless the mixtures are constant in lightness. ")

So you have to pick the best color space for the job, in the case of doing color averages that would be one of the linear ones (linear sRGB, XYZ), while if you are trying to design a perceptually uniform gradient for data visualization, you would better pick a perceptually uniform space (CIELAB, CIELUV) ?


See the recent Oklab post[0] for guidance on choosing a perceptually uniform color space for gradients. It's better than CIELab and CIELuv, both of which I would consider inferior to newer alternatives. In particular CIELab has particularly bad hue shifts in the blue range.

I'm also working on a blog post on this topic (there's an issue open in the repo for my blog, for the curious).

[0]: https://news.ycombinator.com/item?id=25525726


> I expected to have to do gamma correction when making a gradient recently, but in the end it looked like I didn't have to

If you don't explicitly specify the color space you're working in, then you're using some implicitly defined color space in which case you basically need to know what that is (at least roughly).

So traditionally in Windows, way back, when you created a bitmap, wrote some data to it and then drew it, there was no explicit mention of a color space. Instead it was implicit, and it was de-facto non-linear.

These days you can specify[1][2] the color space you're working in, and Windows will then transform the colors into the specified device color space. So then you can specify if you want to work in linear RGB space or say non-linear sRGB.

Unity has something similar[3], which affects how you write shaders, how your textures should be saved etc.

[1]: https://docs.microsoft.com/en-us/previous-versions/windows/d...

[2]: https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf...

[3]: https://docs.unity3d.com/Manual/LinearRendering-LinearOrGamm...


Yes, and in almost all of these discussions, the implicit color space is (non-linear) sRGB. (IIRC Macs might have used a different default color space one-two decades ago ?)

Also, I'm on Linux, and doing picture manipulation with Octave, but thank you for the links anyway !


Yeah I was just using Windows because that's what I was familiar with. I guess on Linux is can vary a lot more on the setup.

So yeah for Octave you need to know what Octave does with the data afterwards. If it's saving a matrix to a PNG say, it could assume the matrix is linear and convert to sRGB which would be a good choice if it also supported say OpenEXR files. However it could also just take the values raw, assuming you'd convert the data to sRGB before saving. Or even allow you to specify the color space in the iCCP chunk, which would give you more power.

Again, what it actually does is something that needs to be looked up.


Yeah, since we're learning, we're not doing anything fancy on that side (at least yet), so (so far) working with sRGB bmp/png/jpg input and sRGB bmp output.


Are you sure about sRGB being already good enough for averaging ? (As long as we don't want to go to a wider color space of course.)

We have been recently taught how to do it 'properly', and we had to go through CIELAB 76 (which, AFAIK, is still an approximation, as human perception is actually non-euclidean).


If you want physically accurate averaging (resize, blur etc), then RGB is fine, as long as you use linear values (or do long-winded transformed math). AFAIU it is by definition 100% physically accurate. As was said, sRGB uses gamma values, where typical math creates ill effects, as in many if not most typical programs.

If you want to do perceptually uniform averaging of colors, color mixing / generating / artistic effects, that's something else entirely.


I'm not sure what you mean by "physically accurate" ?

No color reproduction is going to be physically accurate, except by accident, since color is an (average) human qualia, not a physical observable.

And especially because whatever the way that the colors are going to be reproduced, there's no guarantee that they will correspond to the same light spectrum than the original, since there's an infinity of spectra corresponding to the same impression for a specific color.

And if you want to do perceptually accurate averaging, you're going to have to work in a perceptually uniform color space ! Which (even linear) sRGB isn't.

All that said, it's perfectly possible that linear sRGB is just good enough for most use cases of averaging, even despite not being perceptually uniform. Especially in OP's example with just 2 shades : black and white.


Yes, color is a human concept for certain stimuli, no recording or reproduction is 100% accurate and even the model is not perfect (different people have shifted color sensitivities, some are even tetrachromats and we are ignoring rods vs. cones altogether).

However, the stimuli is predominantly light, which can be quantified and certain operations with light are well studied. Not all, but most noticeable ones are and that is what is used when doing photorealistic rendering etc.

If you do a 2x downscale, you need to average 4 pixels together. Linear RGB should (by theory and definition) give you a (theoretically) physically accurate result, as if you did a physical 2x downscale by putting it further away in a uniformly lit room or whatever. You can't reproduce that precisely, but neither can you reproduce 1l + 1l of milk = 2l of milk.

This is in stark contrast to downsizing, blur or whatever "performed" in sRGB, where images get curiously darker and slightly off-color (or is it lighter?).

I'm not sure what is perceptual average of colors, but if you mix pixels in 1:1 ratio and apply blur / look from far away, there is only one correct result, and linear RGB average (is one way that) gives you the single correct result. (ignoring screen color reproduction deviations from what they are supposed to be)


My bad, I was wrong – can't have both linearity and perceptual uniformity, and I guess that in use cases like dithering, linearity is more important ?

https://news.ycombinator.com/item?id=25648490




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: