I'm doing some image processing and I need an automatic white balancing algorithm that's not too intensive in terms of CPU computation time. Any recommendations?
EDIT: and if it's relevant to efficiency, I'll be implementing it in Java with color images as an array of integers.
One recently published algorithm is the Color Distribution algorithm and it can be found here: http://www.comp.nus.edu.sg/~brown/pdf/ColorConstancyJOSAv10.pdf In the paper there is also the reference to the Matlab source code (http://www.comp.nus.edu.sg/~whitebal/illuminant/files/illuminantEstimator.m). It's a simple algorithm that can be easily programmed and the results show it to be very fast.
If you need additional fast and at the same time accurate white balancing (color constancy) algorithms, you should check this site: http://www.fer.unizg.hr/ipg/resources/color_constancy/
There are several algorithms with their respective source coded that might be just the ones you look for.
GIMP apparently uses a very simple algorithm for automatic white balancing. http://docs.gimp.org/en/gimp-layer-white-balance.html
There is a bit more tweaking than is described here since my first attempt at implementing this works seems to work for most photos but other photos seem to have artifacts or contain too much of either red green or blue :/
@Charles Ma has suggested to use the
Gimp
white balance algorithm. Inpython
andnumpy
this could look like this:it's fast, simple and provides pretty decent results
White balancing algorithms are hard. Even digital cameras get the wrong once in a while, even though they know a lot of extra info about the picture - such as whether the flash was used, and the light level.
For starters, I would just average red, green, and blue, and use that as the white balance point. Set limits on it - stay within the ranges for tungsten, flourescent, and daylight. It won't be perfect, but when its wrong, it will be relatively easy to explain why.
A relatively simple algorithm is to average the hues (in HSV or HSL) of the brightest and darkest pixels on the screen. In a pinch, go with the brightest pixel only. If the hues between brightest and darkest are too different, go with the bright pixel. If the dark is near black go with the bright pixel.
Why even look at the dark pixel? Sometimes the dark is not near black, and hints at the ambient light or fog or haze.
This will make sense to you if you're a heavy Photoshop user. Highlights in a photo are unrelated (or weakly related) to the underlying color of the object. They are your best representation of the color cast of the light, unless the image is so overexposed that everything has overwhelmed the CCDs.
Then adjust the hues of all pixels.
You'll need fast RGB to HSV and HSV to RGB functions. (But maybe you can work in RGB for the pixel corrections with a LUT or linear interpolation.)
You don't want to go by average pixel color or most popular color. That way lies madness.
To quickly find the brightest color (and the darkest one), you can work in RGB, but you should have multipliers for green, red, and blue. On an RGB monitor, 255 green is brighter than 255 red which is brighter than 255 blue. I used to have good multipliers in my head, but alas, they have fled my memory. You can probably google for them.
This will fail in an image which has no highlights. A matte painted wall, for example. But I don't know what you can do about that.
There are many improvements to make to this simple algorithm. You can average multiple bright pixels, grid the image and grab bright and dark pixels from each cell, etc. You'll find some obvious tweaks after implementing the algorithm.