Here is a physical analogy to clarify why nonlinear coding is important.

I can easily perceive the difference in weight between a 1.6 kg boulder and a 2.4 kg boulder. But when I put each of them on a digital bathroom scale that properly rounds to the nearest kilogram, they both read the identical value, 2 kg.

My brother Allen is a lot heavier than either of these boulders, but last time I saw him, I could pick him up. He weighed about 56 kg. But I couldn't perceive whether he was lighter or heavier than my other brother, Dave, who weighed 57 kg.

Now suppose I have two digits worth of data channel capacity in which
to telegraph to you the weight of an object. I telegraph the scale readings
for the boulders (2 kg and 2 kg), on a scale 00 to 99 kg.
To the best of the information available to you at the receiving end, you
will conclude the objects have have the same weight. When I telegraph the
scale readings for my brothers, you conclude they have different weights.
This system works physically, but it fails for the purpose of perception.
You *can* perceive the difference between the weights of the boulders,
but linear coding in two digits reports the same value. You *cannot*
perceive the difference in weight between Allen and David, but linear coding
reports them as different. In this application, linear coding results that
do not accord with perception.

Perhaps you are selling boulders by the kilogram. You might want to use
two digits to telegraph an indication of the physical weights of objects.
In that case, use linear coding. But if you want to use two digits to telegraph
an indication of how you would *perceive* the weights of objects, you'll
need nonlinear coding. Start with a precision much greater than one kilo,
0.1 kg, for example. Take the weight, divide that number by 100 ("full
scale"), take the square root, round it to two digits (0.0 to
9.9), and send *those* two digits. The boulders report square roots
of 1.3 and 1.5, representing the fact that I can perceive that difference.
For my brothers, 56 and 57 round to the same value (7.5), parallelling
my perceptual inability to tell the difference.

Perhaps your task at the receiving end of the two-digit link is to put flour into a sack, so that the sack will be perceived as having the same weight as the original object. In that application, you can reconstruct an approximation to the weight of the original object by squaring the value that was telegraphed.

My ability to detect a difference in two weights is proportional to the
*ratio* of the weights. I can tell that there's a difference in the
weight of two things when the *ratio* of their weights is more than
a certain fraction. With nonlinear coding, the reconstructed value is accurate,
plus or minus a rounding error *that mimics perception.* The coding
preserves the values to some extent, but more importantly, preserves the
*ratios.*

Consider the weigh scale:

To properly represent perceptible weights (technically, mass), you must start with a weigh scale that senses mass. If you quantize to 100 codes (increments of 1 kg over the range 0 to 99 kilograms full scale), coding the mass of an object (in kilograms) linearly into that range will erase easily-perceptible differences among lightweight objects, while preserving imperceptible differences among heavy objects. If you have only 2 digits to express the

perceptionof weight, you must start with mass values having precision better than 1 kg, and you must assign code values from 0 to 99 nonlinearly: The step sizes must be nonuniform.

Translate the principle to image data:

To properly represent perceptible intensities of light (technically, luminance), you must start with a camera or scanner that senses luminance. If you quantize to 256 codes (increments of one LSB in 8 bits, 0 to 255 full scale), coding the luminance of a scene element (in normalized candelas per meter squared) linearly into that range will erase easily-perceptible differences among the dark shades, while preserving imperceptible differences among the light shades. If you have only 8 bits to express the

perceptionof luminance, you must start with luminance values having precision better than 8 bits, and you must assign code values from 0 to 255 nonlinearly: The step sizes must be nonuniform.

*See also: Gamma FAQ
- Linear and nonlinear coding*

Charles Poynton

Copyright © 1998-03-12