Correcting Chromatic Aberration with PanoTools Radial Shift

How to find your own individual values for a, b, c, & d for each color channel.

This tutorial assumes that use are somewhat familiar with panorama Tools and you already know how to find Radial Shift values to correct pin cushioning and barreling.


Chromatic aberration or distortion happens when different colors of light do not line up across the entire image.  More detailed description.  Every lens tends to have various amounts of chromatic distortion.  For zoom lens the distortion will change with zoom.  The amount of distortion changes and tends to get worse the further from the center of the image.  There are two types of Chromatic aberration; Longitudinal and Lateral ( or Transverse).  Lens can and do have both of these problems at the same time.

Lateral (Transverse) Chromatic Aberration is when colors are in focus but placed adjacent to each other.  Lateral CA can be corrected with Panorama Tool's Radial Shift.

Longitudinal Chromatic Aberration is when colors are focused on different planes. Colors will have different degrees of sharpness.  Longitudinal CA can not be corrected with Panorama Tool's Radial Shift.

Chromatic aberration is not blooming ( or purple fringe).  Blooming is related to overexposing highlights using digital camera, which causes the overflow of charge from one pixel sensor to an adjacent sensor.  This is ofter observed as a purple fringe.  There is no opposite color as with chromatic aberration, but the fringe does radiate and get worse further from the center.

The Fisheye lens (FC-E8) I use with my Nikon CoolPix995 suffers with chromatic aberation problem greatly.  Several times I have tried to come up with good values to correct this but ever time I would correct it for one location in the image it would get worse else where.  Now after much trial and error I have a way for you to come up with your own values for your own lenses.


Update: New Method Oct 17, 2004

The methods below is now obsolete. The easier method to calculate chromatic distortion is using PTShift by Eric Gerds.

PTShift works with Photoshop CS using Java scripts, Photoshop Actions, and Panorama Tools to speed up the process of determining abcd parameters to use in Panorama Tools.  PTShift uses the idea below but makes it much easier.  In a graphical interface specify how much channel shift is needed throughout an image.  Let PTShift calculate and save the parameters.  The math is now hidden and unnecessary.


How Radial Shift Works

From your image editing software open and select file to edit and start Radial Shift from the plugin menu Filters|Panorama Tools|Correct, Select Radial Shift Press Options.


Unlike correcting for pin cushioning and barreling, chromatic distortion requires separate values for each color channel.

The formula used is r_src = a X r_dest^4 + b X r_dest^3 + c X r_dest^2 + d X r_dest

d values make linear changes to the image.
a,b, & c values make polynomial changes to the image.
The internal unit used for r_src and r_dest is the smaller of the width or height divided by 2.
With a=b=c=0 & d=1 the image will remain unchanged.
When a+b+c+d=1 the image width will remain unchanged.

I have drawn circles to show how the image is effected with the a, b, & c parameters when d is also changed, such that d = 1 - a + b +c.

At Z and X there will be no change.

At Y there will be some change.  Moving from Z to X the amount of change starts at nothing and gradually get more approaching Y then descends to nothing at X again.

At W there will be most of the change.

A change in a has the most effect.
A change in b has a middle effect.
A change in c has the least effect. 


I created these graphs from an Excel spread sheet that I modified from Peter Reimer @

Click and Drag the graph to see how the parameters change the image.

SRC: Use this value when source image looks like this.
DEST: This is the result.

How changes in d will effect the image.

The image changes all over at the same rate.

How changes in a, b, & c will effect the image when d is also modified to keep a+b+c+d=1

There is no change at X (1 on the graph) and big changes at W.  The change at Y is opposite to the change at W

Step 1 take test images 

For the purpose of determining the right values the best test images should have:

The image does not need to have a grid pattern but some great subject would be a tiled room, bricked walls, office building with lots of windows.

Because of the tendency to get purple fringe pictures of tree against a cloudy sky might not be a good choice.

If it is not possible to fill the entire image with texture (fisheye lens - 1/3 building, 2/3 sky) it is possible to take several pictures each covering a different part of the image.  Combine the different parts of the images into one image.  This is not trying to create a panorama here just a collage of detail.

Here are some details of the test image above at 200% enlargement.



Step 2 calculate d value

Because a, b, & c values have no effect on the pixels at r_src it is best to find d first.

It help to draw two circle like mine, one the width of the image and one half of that size, both centered on the image.

Go to the channels pallet, select the channel that has the most shift at the circle  X.
Turn the other two channels on too by clicking on the eye.
Zoom in on the area 200 to 300%
Select the move tool[V]

I have used the edge of the patio door on the left side of the image.  I have choose the Red channel, because I can see some Red / Cyan edges.

Using the keyboards arrow keys, move the channel, by counting the number of key presses it takes to line them up. 

You can also record a dummy action so that you can read the value. 

1 pixel was not quite enough and 2 was a little too much.  So I need to shrink the Red channel by about 1.5 pixels at X

I prefer to enlarge a channel rather than shrink one.  If a channel has shrunk then there is a border around the image that will not be useful.  So instead of shrinking the Red channel I will enlarge the Green and Blue channels.

new_d = org_d X width/2 / (width/2 + expansion)

Calculate d

  Small Dimension: pixels
Original d val:
Enlarge by: pixels


My image is 1536 wide.  The radius is half that 768
1 X 768 / (768+1.5) = 0.99805

I'll will use 0.998 as the d value for Green and Blue channels leaving everything else alone, and see what the result looks like.

On the Channels Pallet select RGB
Undo your nudge changes and any other test that might be in your history.
Run the Radial Shift plugin.

After examining the results and testing again by nudging the channels I can still that I need to expand Blue about .5 pixel.

new Blue d = 0.998 X 768 / (768 + 0.5) = 0.99735

I end up with d values of Red=1 Green=0.998 and Blue=0.9974

Here are the details of the results after step 2.  Images at 200% enlargement.


At X the image cleanup completely, but there is still a little problem at Y and lots at W.

Step 3 calculate a, b, & c values

Use the modified version of the image from Step 2.
Create a snapshot of this in the History Pallet to make it easy to get back to.
Use the same method to calculate what change is needed at both W and Y.

I find that at Y I need to shrink Red .4 pixels and at W I need to enlarge Red 2 pixels and shrink Blue 4 pixels.

Again I do not want to shrink the image at W so in stead of shrinking Blue, I will enlarge Red and Green.  That make 6 pixels.  I am testing this in the corner with and need to move channel 6 pixels over and 6 pixels up or  SQRT(6^2+6^2) = 8.5 pixels diagonally.  The 4 pixels over and 4 up for Green becomes 5.6 pixels diagonally.

At Y I need to shrink Red .4 pixel.
At W I need to Enlarge Red 8.5 pixels, Enlarge Green 5.6 pixels.

Distance Y from center is width/4 = 1536/4 = 384

My measurement for W was not in the exact corner but 83 pixels in and 76 pixels down.  Plug in the number into this formula SQRT( (width/2-offset_w)^2 + (height/2-offset_h)^2 ).  This make my distance from center to this point.

I took the formula r_src = a X r_dest^4 + b X r_dest^3 + c X r_dest^2 + d X r_dest and substituted  with  1 + a + b + c and then solved for each of a, b, and cd is also recalculated each time to maintain the size of the image at X.

Calculate a b c

Width: pixels
Height: pixels
x position: pixels
y position: pixels
Enlarge by: pixels


SQRT( (1536/2 - 83 )^2 +(2048/2 - 76)^2 )
1170 pixels from the center

For now we will use the image from Step 2 which is already corrected at X.

At this point we want to make sure the image does not change at X, so with any change to a, b, & c there must be a change to d.

These changes will enlarge Red channel to make it line up at W or Y but different changes are need at each.  With the Green channel we do not want any change at Y.

Fix 8.5 pixels Red at W Fix 0.4 pixels Red at Y Fix 5.6 pixels Green at W
a -0.00157 -0.00092 -0.00104


-0.00083 -0.00143
c -0.00285 -0.00069 -0.00188

For the Red channel the a correction is closest together.  But Red a as -0.00157 will over compensate at Y.  The same is true for the Green a as -0.00104  Changing a has the least effect at Y.

Changes in a cause the least effect at Y and greatest at W

Changes in c cause the most effect at Y and the lest at W

By adding a little change to c which has the greater effect at Y and less at W we can satisfy both places.  For Red if c is set to 0.0005 then we calculate a = -0.00184 and d = 1.00134

Doing something similar to Green.  If we set c to 0.001 then we calculate a = -0.00159 and d = 1.00059 and the change at Y is virtually negated.  I can verify this on the Excel spreadsheet.

The results were really close but at W, Red needs to be enlarges .5 pixels and Green decreased .5 pixels.

Make sure there is no change to the image at X.  If there is then d was not updated correctly.

Here are some details of the results after step 3 image above at 200% enlargement. Place mouse over image to see the original before correction.


There is a little bit of color still showing in the last image at W but this is the best results I have ever had.


Step 4

Combine the numbers from Step 2 and 3 These can also be combined with pin cushioning or barreling corrections that You may have.

Multiply the d values to update the values in Step 3.

R  1.0      X  1.00143  = 1.00143 
G  0.998   X  1.0005   = 0.9985
B  0.9974  X  1.0        = 0.9974

Here are my before and after shot.

Original   Corrected

I hope this was of some help.  I welcome any feedback or comments you may have with this tutorial.

References, Links, and Notes:

Page last modified October 20, 2007
All content is 1991-2007 All Rights Reserved.
All trademarks are property of their respective owners.