December 13, 2008

vignetting correction and per-color scaling

by Andrey Filippov

This is a combination of two features I just added together as I had to get into the data pipeline in the FPGA.

First is correction of lens and sensor vignetting –  http://en.wikipedia.org/wiki/Vignetting (Micron sensor have some of this capabilities on-chip, but not really nice and not portable to other sensors). This can be especially important for wide angle lenses and fish eyes. It is better to do this correction in-camera even if higher order compensation (not just quadratic) may be done in post-processing. In-camera has advantage of doing it before gamma-tables that compresses 12-bit data to just 8, so it is possible to save somewhat on S/N ratio and increase the overall dynamic range.

In addition to the vignetting of the lens that is usually rather symmetrical around the axis, sensor may add asymmetry related to the microlenses. Kodak KAI11002 used in book scanning have very different sensitivity vs. angle functions in vertical and horizontal directions.

So I implemented separate coefficients for X and Y (and am proud of remembering how to calculate such functions without a single multiplication 🙂 ) This functions is common for all color channels (it will not be difficult to make it individual if needed). The F(x,y) is 17-bit (limited by the on-chip-multiplier used to apply the F(x,y) to the pixel data), so if I set x1.0 (in the center) 15 bits up to x4 correction can be applied.

Second feature is just per-color scaling before the gamma tables is just to reduce CPU load and provide  more flexibility. Currently the color scaling is performed it 2 ways – re-calculating gamma tables and sensor analog gain. Analog gain is not very precise and have large steps so it is not enough for color balancing. Scaling gamma tables works good when the tables are really gamma (not arbitrary ones) where scaling of input can be replaced by scaling of the output. With the new feature it is possible to scale the before-gamma table without re-calculating/reloading the gamma tables to the FPGA. These (4 of them) coefficients are also 17 bit, and there is an additional scaler (shifter) after, so if you do not need 4:1
range but 2:1 is enough you can increase the precision by assigning x1.0 to 0x10000 instead of the 0x8000 (16 bits vs 15 bits).

I’m testing it and will include control into the drivers. It will be rather easy to make a auto-correction by integrating pixel data (raw data inside the camera is available as a file but it is better to handle it in C rather than PHP) in say 16 zones (4×4) and then calculating the required parameters. In some cases it can be used to compensate for a uneven illumination (in the center), not just the lens/sensor.

img_wtf05
Black area is still a bug, not a feature. It should stay at maximum gain, not zero.


« Previous Page