Live data from Hacker News

Should you normalize RGB values by 255 or 256?

30fps.net

81–90 of 156 posts

Re: Should you normalize RGB values by 255 or 256?

#81

The author is confusing bins with bin edges. In their first plot, the standard approach looks strange because 0-7 should be the bin edges, not the center points as shown in the plot. You can see this confusion again in the histogram example. There are only 255 bins, not 256. If you fix that mistake and remove the 0.5 offset, then the histogram is distributed correctly at both ends.

Sorry, you seem to be confused.

>There are only 255 bins, not 256

There are 256 bins because there are 256 values.

The questions are:

1. What are the boundaries of these bins?

2. Which sample represents a particular bin?

With 1-bit color, we have sample values {0, 1}. What bins do they represent?

Here's one choice:

     [0, 1), [1, 2)
Two equally sized bins, spanning the interval [0, 2] of length 2, each defined by its sample at lower bound.

Alternatively, we could consider these bins:

    [-0.5, 0.5), [0.5, 1.5)
These are also equally sized bins, spanning the interval [-0.5, 1.5] of length 2, defined by samples at the center.

We could also define bins like this:

    [0, 0.5), [0.5, 1]
Two equally sized bins spanning the interval [0, 1] of length 1, where we sample the first bin at the lower bound, and the last bin at the upper bound.

This, in a nutshell is what the author is trying to explain.

Let's look at this again, with 2 bits.

With 2-bit color, we have sample values {0, 1, 2, 3}.

Which bins do they come from?

The three options above yield:

    [0, 1), [1, 2), [2, 3), [3, 4)

    [-.5, 0.5), [0.5, 1.5), [1.5, 2.5), [2.5, 3.5)

    [0, 0.5), [0.5, 1.5), [1.5, 2.5), [2.5, 3]
The first two span an interval of length 4, the third spans an interval of length 3.

In the third case, the tail bins are short (have size ½), and the rest have size 1.

The last bin must be a closed interval in the third case, so that it includes the value we picked to represent it.

None of these choices is inherently invalid or better than the others; and none stems from "confusing bins with edges".

The third option does have the distinction that the first and last bins are smaller than the rest. But it's not necessarily a drawback. Especially when we're talking about color, hardware interpretation, and human perception.

When you remap these bins into the [0, 1] interval, you're "dividing by 4" in the first two cases, and by 3 in the third case.

The maps are:

     x → x/4
     x → (x + ½)/4
     x → x/3
The inverse maps (that yield a sample in {0, 1, 2, 3} given a floating point value in interval [0, 1]) are:

    x → trunc(4x)
    x → round(4x - ½) = trunc(4x)
    x → trunc(3x + ½)
In the first two options, the domain is [0, 1). It might be necessary to apply clipping because the exact value 1.0 falls outside the range of the forward transform.

The 2nd option is the most symmetric, of course, but the 3rd one is the most straightforward (and cheapest) to implement, so that's the default.

The choice amounts to making the highest and lowest bins slightly smaller to make the rest sightly larger.

That's to say, if you generate uniform noise between 0 and 1, you'll get the following samples from your function with equal probability:

    0 or 3
    1
    2
As the author points out, this hardly matters when you are talking about having 256 bins.

That, and with color specifically, the "good" histograms aren't uniform anyway (and any photographer wants to avoid getting much at either extreme).

TL;DR: The author is not confusing anything — but their diagram and explanation are, indeed, a bit confusing.

Re: Should you normalize RGB values by 255 or 256?

#83
post #65

This problem of what exactly a color value means is mostly inconsequential when you have 8 bits per component, the difference in the denominator being either 255 or 256 makes the errors tiny, you must have really good color perception and get really close to the screen to see any difference at all, and your monitor/phone screen is probably not calibrated anyway, so who cares. It becomes a pain in the ass when you're…

You forgot about gamma correction. Before converting a value in the range of 0-255 into a voltage, PCs typically raise that value to the power of 2.2. This makes the difference between small values and large values far more apparent:

2^2.2 = 4.595, 255^2.2 = 196,964.699

Re: Should you normalize RGB values by 255 or 256?

#84
post #71

Earlier quoted context omitted.

It's right up there with the confusion if 2000 was the new year of the 21st century or the last year of the 19th century.

The debate is if 2000 is the first year of the 21st century or the last year of the 20th century. (btw I agree with the latter)

wow, yeah, that's quite the miss on my part.

Re: Should you normalize RGB values by 255 or 256?

#85
There are only two real solutions after factoring in the need to preserve black as zero.

They are "rgb / 255.0" vs. "rgb / 256.0". Both have different tradeoffs. Pick your poison. (If you're using a 8 bit display signal then you better match whatever value the OS picked for the mapping back to the display, so your RGB values pass through unchanged)

Re: Should you normalize RGB values by 255 or 256?

#86
post #74

The entire issue arises from the use of truncation, right? It guarantees that only an exact 1.0 could land in the 255 bin so the net effect is a reduction of 256 bins to 255 bins. (Using random numbers as shown also guarantees no 1.0.) Why not scale to fill the available bins, though? i.e. trunc(result * 255.999)?

> Why not scale to fill the available bins, though? i.e. trunc(result * 255.999)? That’s half of the mid-riser staircase quantizer discussed in the article. (The other half is coming up with the reverse.) (I would implement it as min(floor(x * 256), 255).)

Kind of. According to the article, the mid-riser vs mid-tread distinction correlates to where the 0.5 is applied in the transform. I’m proposing that there is no 0.5 applied at all. Instead of counteracting the compression of the truncation operation by adding a fixed offset, it multiplies by a scale factor.

Possibly my proposal doesn’t hold up to repeated transforms and operations. It might skew toward 255 in real operations.

Re: Should you normalize RGB values by 255 or 256?

#87
post #50

Earlier quoted context omitted.

How do you fit 256 distinct values into 255 bins?

By counting the edges

I see what you’re saying - index 0 holds values from 0-1, index 2 from 1-2 etc, but then you have index 255 holding values between 255 and 256. So you’re sort of arguing that the 0-255 8-bit quantization is actually representing ‘real’ values of 0-256?…

Edit: somehow missed alterom’s reply - they explain it much better than my question above does.

Re: Should you normalize RGB values by 255 or 256?

#88
post #65

This problem of what exactly a color value means is mostly inconsequential when you have 8 bits per component, the difference in the denominator being either 255 or 256 makes the errors tiny, you must have really good color perception and get really close to the screen to see any difference at all, and your monitor/phone screen is probably not calibrated anyway, so who cares. It becomes a pain in the ass when you're…

[deleted]

Re: Should you normalize RGB values by 255 or 256?

#89
post #65

This problem of what exactly a color value means is mostly inconsequential when you have 8 bits per component, the difference in the denominator being either 255 or 256 makes the errors tiny, you must have really good color perception and get really close to the screen to see any difference at all, and your monitor/phone screen is probably not calibrated anyway, so who cares. It becomes a pain in the ass when you're…

> That means you don't get to see any pure grays -- the closest ones will have bit of blue or yellow tint, depending on the direction of the difference.

OMG I remember as a kid staring at static-y CRT displays, and seeing these faint blue and yellow lines at the borders of them. I’d always wondered why they appeared and why they were specifically blue and yellow. I finally know! (at least, assuming those specific artifacts are due to the same thing)

Re: Should you normalize RGB values by 255 or 256?

#90
This was a genuinely thought provoking article. I had to challenge some personal assumptions.

Coming from an electrical engineering background, I disagree with how the author presented "Two types of quantizers". Mathematically rigorous, but not grounded in practical systems.

In ADCs, there is always an inherent +-1/2 LSB of quantisation uncertainty. The transfer characteristic is always mid-tread sampling, or at least I haven't come across any counter examples. This is true for bipolar or unipolar ADCs.

The lowest code is negative voltage reference, and the highest code the positive reference. The transfer characteristic plot will show what the author has demonstrated, that the highest and lowest bins will effectively be 1/2LSB in width.

In a unipolar system, this has the consequence of not being able to represent the midpoint voltage precisely, or in other words, the gray problem. In a bipolar system, 0V will be mid-tread N/2 value, but that doesn't mean it has "256 ranges".

So, I'll be sticking with (VREF+ - VREV-) * k / (2^N - 1). Or in other words I agree with the normalisation by 255. It's the fence post error all over again, you have N values, but N-1 ranges. If you have less ranges than you do values, you need to distribute 1 of those ranges between two values, hence the 1/2LSB range endpoints.

Post reply on HN