Symbolic Math Toolbox

Developing an Algorithm to Undistort Pixel Locations of an Image

This example uses Symbolic Math Toolbox to develop an algorithm that undistorts pixel locations of an image.

Background

When a camera captures an image, it does not precisely capture the real points, but rather a slightly distorted version of the real points that can be denoted (x2, y2). The distorted pixel locations can be described using the following equations:

math

math

where:
x1, y2 = undistorted pixel locations
k1, k2 = radial distortion coefficients of the lens
p1, p2 = tangential distortion coefficients of the lens
r = (x_1^2 + y_1^2)^(1/2)

An example of lens distortion is shown below. Note the curvature of the lines toward the edges of the first image.

Original (distorted) image Undistorted Image

Camera Lens Undistortion - Original (distorted) image

Camera Lens Undistortion - Undistorted Image

For applications such as image reconstruction and tracking, it is important to know the precise location of points. Our goal is to determine undistorted pixel locations (x1, y1) given the distorted pixel locations (x2, y2) and the distortion coefficients of a particular lens.

Define the Distortion Model

We begin by defining our distortion equations.

x_2:= x_1*(1+k_1*r^2+k_2*r^4)+2*p_1*x_1*y_1+p_2*(r^2+2*x_1^2) |
      r = sqrt(x_1^2 + y_1^2);

y_2:= y_1*(1+k_1*r^2+k_2*r^4)+2*p_2*x_1*y_1+p_1*(r^2+2*y_1^2) |
      r = sqrt(x_1^2 + y_1^2);

math

math

Visualize Pixel Locations of Distorted and Undistorted Images

No Distortion

We created a custom MuPAD function called PlotLensDistortion.mu that plots a grid of distorted and undistorted pixel locations. We call this function for the condition where there is no lens distortion, and see that the distorted points and undistorted points lie on top of one another and cannot be distinguished.

k_1:=0: k_2:=0: p_1:=0: p_2:=0:
read(NOTEBOOKPATH."PlotLensDistortion.mu"):
PlotLensDistortion(x_2, y_2, k_1, k_2, p_1, p_2, "No Distortion")

math
MuPAD graphics

Radial Distortion (k1 = 0.1)

We now plot pixel locations assuming our lens has a radial distortion coefficient k1 = 0.1. The tips of the blue lines represent the distorted pixel locations. Note that distortion is smallest near the center of the image and largest near the edges.

k_1 := 0.1:
PlotLensDistortion(x_2, y_2, k_1, k_2, p_1, p_2, "k1 = 0.1")

Camera Lens Undistortion

Calculate Inverse Distortion Model

Given a camera's lens distortion coefficients and a set of distorted pixel locations (x2, y2), we calculate the undistorted pixel locations (x1, y1). We look at the case where all distortion coefficients equal zero except for k1 which equals 0.2.

We begin by defining the distortion coefficients.

delete x_2, y_2;
k_1:=0.2: k_2:=0: p_1:=0: p_2:=0:

We define the distortion equations for these coefficients and solve for the undistorted pixel locations (x1, y1).

eqx := x_2 = x_1*(1+k_1*r^2+k_2*r^4)+2*p_1*x_1*y_1+p_2*(r^2+2*x_1^2) |
       r = sqrt(x_1^2 + y_1^2);

eqy := y_2 = y_1*(1+k_1*r^2+k_2*r^4)+2*p_2*x_1*y_1+p_1*(r^2+2*y_1^2) |
       r = sqrt(x_1^2 + y_1^2)

math
math

Result := solve([eqx,eqy], [x_1,y_1], IgnoreSpecialCases, MaxDegree=3);

math
Click on image to see enlarged view.

Since element 1 is the only real solution, we extract that expression into its own variable.

realResult := Result[1]:
X1 := realResult[1][2];
Y1 := realResult[2][2];

math
math

We can read this equation into MATLAB using the getVar function in Symbolic Math Toolbox, and use it as the basis of an image undistortion algorithm.