# 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:

where:
x1, y2 = undistorted pixel locations
k1, k2 = radial distortion coefficients of the lens
p1, p2 = tangential distortion coefficients of the lens
r =

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

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);

### 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")

#### 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")

### 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)

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

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

realResult := Result:
X1 := realResult;
Y1 := realResult;

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.