Symbolic Math Toolbox |
This example uses Symbolic Math Toolbox to develop an algorithm that undistorts pixel locations of an image.
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.
We begin by defining our distortion equations.
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")
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")
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[1]:
X1 := realResult[1][2];
Y1 := realResult[2][2];
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.