Gamma Correction

A note on gamma correction and images

Graeme W. Gill 16 May 1993

What is all this gamma stuff anyway?

Although it would be nice to think that "an image is an image", there are a lot of complications. Not only are there a whole bunch of different image formats (gif, jpeg, tiff etc etc), there is a whole lot of other technical stuff that makes dealing with images a bit complicated. Gamma is one of those things. If you've ever downloaded images from BBS or the net, you've probably noticed (with most image viewing programs) that some images look ok, some look too dark, and some look too light. "Why is this ?" you may ask. This, is gamma correction (or the lack of it).

Why do we need gamma correction at all?

Gamma correction is needed because of the nature of CRTs (cathode ray tubes - the monitors usually used for viewing images). If you have some sort of real live scene and turn it into a computer image by measuring the amount of light coming from each point of the scene, then you have created a "linear" or un-gamma-corrected image. This is a good thing in many ways because you can manipulate the image as if the values in the image file were light (ie. adding and multiplying will work just like real light in the real world). Now if you take the image file and turn each pixel value into a voltage and feed it into a CRT, you find that the CRT _doesn't_ give you an amount of light proportional to the voltage. The amount of light coming from the phosphor in the screen depends on the the voltage something like this:
    Light_out = voltage ^ crt_gamma
So if you just dump your nice linear image out to a CRT, the image will look much too dark. To fix this up you have to "gamma correct" the image first. You need to do the opposite of what the CRT will do to the image, so that things cancel out, and you get what you want. So you have to do this to your image:
    gamma_corrected_image = image ^ (1/crt_gamma)
For most CRTs, the crt_gamma is somewhere between 1.0 and 3.0.

If that is all it is, why does it seem so complicated?

The problem is that not all display programs do gamma correction. Also not all sources of images give you linear images (Video cameras or video signals in general). Because of this, a lot of images already have some gamma correction done to them, and you are rarely sure how much. If you try and display one of those images with a program that does gamma correction for you, the image gets corrected twice and looks way to light. If you display one of those images with a program that doesn't do gamma correction, then it will look vaguely right, but not perfect, because the gamma correction is not exactly right for you particular CRT.

Whose fault is all this?

It is really three things. One is all those display programs out there that don't do gamma correction properly. Another is that most image formats don't specify a standard gamma, or don't have some way or recording what their gamma correction is. The third thing is that not many people understand what gamma correction is all about, and create a lot of images with varying gamma's.

At least two file formats do the right thing. The Utah Graphics Toolkit .rle format has a semi-standard way of recording the gamma of an image. The JFIF file standard (that uses JPEG compression) specifies that the image to be encoded must have a gamma of 1.0 (i.e. a linear image - but not everyone obeys the rules).

Some image loaders (for instance xli - an X11 image utility) allow you to specify not only the gamma of the monitor you are using, but the individual gamma values of image you are trying to view. Other image viewers (e.g. xv another X11 image program) and utilities (eg. the pbm toolkit) provide ways of changing the gamma of an image, but you have to figure out the overall gamma correction yourself, allowing for undoing any gamma correction the image has, and then the gamma correction you need to suite your CRT monitor.

[Note that xv 2.21 doesn't provide an easy way of modifying the gamma of an image. You need to adjust the R, G and B curves to the appropriate gamma in the ColEdit controls. Altering the Intensity in the HSV controls doesn't do the right thing, as it fails to take account of the effect gamma has on H and S. This tends to give a tint to the image.]

How can I figure out what my viewer does, or what gamma my screen has?

The simplest way to do that is to try loading the file chkgamma.jpg (provided with xli distribution), which is a JFIF jpeg format file containing two grayscale ramps. The ramps are chosen to look linear to the human eye, one using continuous tones, and the other using dithering. If your viewer does the right thing and gamma corrects images, then the two ramps should look symmetrical, and the point at which they look equally bright should be almost exactly half way from the top to the bottom. (To find this point it helps if you move away a little from the screen, and de-focus your eyes a bit.)

If your viewer doesn't do gamma correction, then left hand ramp will have a long dark part and a short white part, and the point of equal brightness will be above the center.

If your viewer does have a way of setting the right amount of gamma correction for a display, then if the equal brightness point is above center increase the gamma, and decrease it if it is below the center. The value will usually be around 2.2

[with xli for instance, you can adjust the display gamma with the -dispgamma flag, and once you've got it right, you can set the DISPLAY_GAMMA environment variable in your .profile]

How do I figure out what the gamma of an image is?

This is the most tricky bit. As a general rule it seems that a lot of true color (i.e. 24 bit, .ppm .jpg) images have a gamma of 1.0 (linear), although there are many about that have some gamma correction. It seems that the majority of pseudo color images (i.e. 8 bit images with color maps - .gif etc.) are gamma corrected to some degree or other.

If your viewer does gamma correction then linear images will look good, and gamma corrected images will look too light.

If your viewer doesn't do gamma correction, then linear images will look too dark, and gamma corrected images will ok.

Why Linear images are sometimes not such a good thing

One of the reason that many high quality formats (such as Video) use gamma correction is that it actually makes better use of the storage medium. This is because the human eye has a logarithmic response to light, and gamma correction has a similar compression characteristic. This means images could make better use of 8 bits per color (for instance), if they used gamma correction. The implication though, is that every time you want to do any image processing you should convert the 8 bit image to 12 or so linear bits to retain the same accuracy. Since little popular software does this, and none of the popular image formats can agree on a standard gamma correction factor, it is difficult to justify gamma corrected images at the popular level.

If some image formats can standardize on a particular gamma, and if image manipulation software takes care to use extra precision when dealing with linearized internal data, then gamma corrected distribution of images would be a good thing.

(I am told that the Kodak PhotoCD format for instance, has a standard gamma correction factor that enables it to get the highest quality out of the bits used to hold the image).

Olin Lathrop, Cognivision, 6 Oct 1993

Gamma correction is largely a crock because the fundamental assumption is wrong. Yes, there is a (reasonably) reliable relationship between voltage and phosphor emission power that the standard "gamma" formula models well enough for our purposes. Unfortunately, this is not at all what the relationship from pixel intensity value to visible brightness actually looks like. Major reasons why not include the monitor offset (black level) control, and the CRT's reflection of ambient light. The amplifiers can also be quite non-linear at low voltage levels.

All this amounts to black not really being black, which throws a big wrench into the gamma formula. Here is how I think of and deal with the problem:

The problem really comes down to mapping an image with a large dynamic range (256:1) to an output medium with considerably less. Ektachrome slides can get to 150:1, glossy prints with careful illumination 80:1, matte prints maybe 40:1, newspapers 15:1. A well adjusted monitor in a dark room maybe 100:1 if everything is perfect. Figure 40:1 (if that much) for more normal monitor situations. Contrast this to real world scenes in a office, which can easily reach 500:1.

Clearly, something needs to get squashed in the process displaying or making a hard copy of most images. The quest is to squash while maintaining the highest perceived "likeness" to the true image. Humans perceive intensities logarithmically, not linearly. Since we want to do image manipulations in perceptual linear space, this means manipulating brightnesses in mathematical log space. Humans also tend to "tune out" details in dark areas of a scene. There was a lot of interesting research on this stuff done by Kodak back in the 1930s.

Between the black level problem, the way our perception system works, and a host of unpredictable environmental variables, it seems pointless to try to come up with a formula that can then be "corrected" for. Even if you could come close, my points are:

  1. Such a formula couldn't be reasonably approximated by anything as simple as one "gamma" exponential.
  2. Even if the function was known, you don't want to "correct" for the best linear mapping anyway. You want the best logarithmic mapping.
So, here's what I do. My software can map the input black to white range to any other range, and can independently apply a "brightness" factor. The brightness factor is exponential in nature, but doesn't affect full black or full white. A value of 0 leaves everything alone. Positive values increasingly slosh intensities smoothly to the white end, while negative values slosh towards black. This doesn't try to model what the hardware is actually doing, but provides enough controls to make things look good.

I have used this technique to pre-treat images for film recorders, printers, and other output media with great results.