When we’ve gone to the trouble of making a flat field image for a given system configuration and aperture, there are several ways the flat frame can be used to correct vignetting in other images shot with the same configuration and aperture.
Using ImageMagick (version 6.9.2-5 Q16 x64 for this example) is one way to do our processing. ImageMagick is a suite of image processing tools with the advantages of price, power, and precision. The price is right: it’s free. It’s very powerful with a rich set of commands and options covering a broad range of capabilities. It is very detailed in reporting information about an image and enables precision with its robust option set. It lends itself well to automation scripting for large jobs. APIs are available for a variety of programming and scripting languages.
The goal is to exploit the flat field image to correct the vignetting that it manifests itself. This will precisely control the adjustments of the pixel values. Unlike the parametric control technique, this method can correct nearly any type of intensity anomalies including more complex fall-off patterns that are not radially symmetric.
To understand how and why this works, it is helpful to think of the pixel intensity values falling in a range of 0 to 1, where 0 is pure black and 1 is white, the greatest possible pixel value. All other tonal values are represented by some fractional value between 0 and 1. This is, in fact, how ImageMagick and Photoshop perform some of their calculations under the covers.
The following discussion is simplified by ignoring multiple channels. We’ll look at a single channel, understanding that the same exact mechanism and process applies to all channels.
Imagine we’re correcting the vignetted flat field image. We want a process that will convert the varying flat field pixel levels to a uniform single tonality across the entire image (or restated, we want to remove the vignetting or light fall-off). We want to do this in a way that the lightest pixels in our flat field are left alone and the darker pixels are adjusted up to be that brightest level. For typical vignetting, this means we want to leave the central brighter values alone while boosting the darker levels toward the edges and corners.
Every pixel value in a vignetted flat field is divided by a corresponding pixel value in a correction frame so that the resulting pixels are all at the same value. The trick is creating a correction frame that can do that.
For every pixel in the flat field image, we’ll have a corresponding pixel in the correction frame. That corresponding correction pixel will have a value (also between 0 and 1.0) such that when it is divided into the flat field pixel value, the resulting value is the target brightest level we want for the uniform corrected image result.
In the example above, the brightest pixel value is 0.9. A pixel value of 0.7 must be divided by 0.7777… (0.78) to bring it up to the target value of 0.9. Each correction pixel value is calibrated to bring up the darker pixels in the flat field image in just the right amount.
So where do the correction values in the correction frame come from? They are calculated from the original flat field frame. In the example with the brightest flat field value at 0.9, we’ll divide every pixel in the entire flat field frame by 0.9 to create the correction frame. This makes sure that the brightest values are left alone during the correction division (dividing by 1.0 in the 0.9 case) and the darker pixels are adjusted upward proportionally.
So the strategy with using correction frames is deceptively simple: create the correction frame by dividing each pixel in the flat field frame by the highest pixel value in the flat field frame; then use the correction frame on any image by dividing the input image’s pixels by corresponding correction pixels. This correction image can be used with any image shot with the same camera, lens, filters, and f-stop that was used to shoot the flat field used to derive the correction frame.
The methods we’ll be discussing will, by default, perform these operations on all three channels in the image automatically.
Thoroughly confused yet? It really does make sense when you think through the whole thing a few times. Okay, here’s the nutshell version of what we’re going to do:
- Create a correction image by dividing the flat field’s pixels by the lightest pixel value in the flat field.
- Correct subject image vignetting by dividing the subject image by the correction image.
Create A Correction Image
The correction image contains all the pixel values such that when divided into the corresponding subject pixels, the darker pixels are corrected to the desired value.
Using our Lumix 20mm f/2 flat field image (named vig20mmf2.tif) as an example, we first find the brightest levels in the image.
identify -format %[fx:maxima] vig20mmf2.tif
The ImageMagick identify command can display detailed information about our image including the calculated maximum level (-format %[fx:maxima]) which in this case is 0.6604.
Now we can create the correction image.
convert vig20mmf2.tif -evaluate divide 0.6604 vig20mmf2_corr.tif
The ImageMagick convert command simply divides each pixel in our flat field image by 0.6604 (-evaluate divide 0.6604) and outputs our correction image, vig20mmf2_corr.tif.
Apply The Correction Image
This correction image can then be used by another convert command to correct vignetting for any subject image shot with the Lumix 20mm at f/2. Let’s be clever and apply this correction to our original vignetted flat field image to see how well it corrects the vignetting.
convert vig20mmf2.tif vig20mmf2_corr.tif -compose dividesrc \
The convert command takes several command-line options: the subject image name (the one to be corrected), the correction image name, “-compose dividesrc” to indicate the operation we’re performing, “-composite” to perform the divide operation, and finally our output corrected file name. (Note: the backslash is not part of the command above, just an indication that the command continues on the next line.)
One little gotcha to be aware of: if your subject image and correction image have different orientations (one is landscape oriented and the other portrait oriented), the convert command won’t adjust, the operation will divide dissimilar images, and you won’t get the results you intend. In that case, add a -rotate option for your subject image to get them both on the same orientation before it proceeds. You rotate the output image back in post if necessary. Here’s an example of the convert command working on a vertically oriented image with a horizontal correction frame:
convert verticalimage.tif -rotate "90<" vig20mmf2_corr.tif \
-compose dividesrc -composite corrected.tif
See ImageMagick’s documentation for the syntax of the -rotate command-line option.
The resulting vig20mmf2_IM.tif looks indistinguishable from our ideal uniform flat field image. The graph couldn’t look any better either:
Applying a correction image to the Lumix 20mm at f/2 flat field image using ImageMagick shows an excellent resulting graph.
Finally, let’s look at the statistics for the corrected image.
ImageMagick-corrected Lumix 20mm f/2 flat frame
That result is within a gnat’s eyelash of perfect. We can keep the vig20mmf2_corr.tif image and apply it any time we wish to remove vignetting from a photo shot with the Panasonic GH4 with Lumix 20mm lens at f/2.
Obviously you would need to shoot flat field images and convert them to correction images for every camera/lens/filter/aperture combination that you wish to correct in this manner.
Not So Fast
As delighted as we are at how close our correction image comes to correcting our vignetted flat field image, we have to realize we created the correction image from the flat field image so of course it looks great. When used against other real world images, however, all kinds of variables get fired off to thwart perfection. The correction applied this way is a very accurate but not-always-perfect way to correct vignetting. It’s a great start, and often perfectly sufficient, but there may be shooting circumstances where the correction under- or over-compensates for the particular subject shooting conditions. Use discretion and adjust as needed.
Before: sunset rainbow image with visible vignetting. Shot with Lumix 20mm lens at f/2.
After: image with vignetting removed by using a corrective image applied with ImageMagick.
Using a correction image made from a vignetted flat field image shot with the Lumix 20mm lens at f/2, ImageMagick has effectively removed the vignetting.