COLOR CORRECTION USING ARITHMETIC
“Under the Hood”
(Or “How I Got There For the Mathematically Inclined”)
Figuring out the percentage of grey for each color channels is easy – divide each channel by the maximum value and you’ll see the percentage of grey that each channel contains. In this case: R=65.1%, G=59.6%, and B=60.8%. Unfortunately, that information is useful only for identifying whether or not the pixel chosen is close to neutral. In this case, it is. The challenge then becomes how to use that information to make a global change to all pixels, so that the color casting channel is reduced in “primacy.” The easiest way to do that is by using the Levels or Levels (Individual Controls) effect. Since I prefer to use Levels (Individual Controls) for its ease of access to individual controls, I chose that effect.
I wanted to preserve the overall level of luminosity in the footage, rather than darken it, so I chose to work from the input white channels of the effect, rather than darken the image by working from the input black. Knowing that the brightest channel in a mid-grey area would reveal the color cast, I had to find a way to preserve the full color value of the brightest color, while bring the other pixels up in value. The input white value of each channel represents the maximum brightness of the brightest pixel in a color channel. Assuming that there is even one pixel in an image that is at full brightness, then all of the other pixels are appropriately placed in value. On the other hand, if there are no pixels in a color channel at full brightness, then the image will have a color cast – the lower in value the brightest pixel happens to be, the greater the color cast. By adjusting the input white value in the Levels (Individual Controls), you can shift the brightness of a particular color channel so that the brightest pixel in an image will be changed to 255. For those who love expressions, it’s like using the linear() method on a color channel.
The answer to finding that value lay in reversing my initial process – instead of finding out the percentage of grey that each color channel represented, I needed instead to produce a number that would represent the inverse of the percentage – 1.536 (rounded up to 1.54) – allowing me to decrease the threshold for the input white for the other two channels. Multiplying them by this number would result in the appropriate amount of channel-specific white input decrease, yielding a color corrected image. Of course, this rests upon my initial choice of neutral pixel. If I chose the wrong one, then my efforts were useless. After that, finding the right gamma balance was a matter of personal taste . Did I want the image to have greater contrast? Then I should push the gamma toward the brighter pixels. Did I want it to have less? Then I should push it toward the darker pixels.
Technically, the process could work in reverse – dividing 255 by the darkest color value, and adjusting the input black levels of all the values – but some rather unpleasant, if technically correct, results are generated that way. Also, this process does have the net effect of brightening your image, so be careful of generating new hotspots, but by knowing the correct input white value, taken from the relationship between color channel values in a spot that SHOULD be neutral grey, it is possible to remove a color cast from virtually any image in a relatively short amount of time using simple arithmetic.