Documentation

This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English verison of the page.

Note: This page has been translated by MathWorks. Please click here
To view all translated materals including this page, select Japan from the country navigator on the bottom of this page.

Developing an Algorithm for Undistorting an Image

This example develops a mathematical model using the Symbolic Math Toolbox to undistort an image and features a local function in the live script.

Background

Any real world point can be defined with respect to some 3-D world origin.

Relative to a camera lens, this 3-D point can be defined as p0, which is obtained by rotating and translating P.

=

The 3-D point p (0) is then projected into the camera's image plane as a 2D point, (x (1) , y (1) ).

,

When a camera captures an image, it does not precisely capture the real points, but rather a slightly distorted version of the real points which can be denoted (x (2) , y (2) ). The distorted points can be described using the following function:

where:

k (1) , k (2) = radial distortion coefficients of the lens

p (1) , p (2) = tangential distortion coefficients of the lens

r =

Distortion

An example of lens distortion is shown below; original distorted image (left) and undistorted image (right).

Note the curvature of the lines toward the edges of the first image. For applications such as image reconstruction and tracking, it is important to know the real world location of points. When we have a distorted image, we know the distorted pixel locations (x (2) , y (2) ). It's our goal to determine the undistorted pixel locations (x (1) , y (1) ) given (x (2) , y (2) ) and the distortion coefficients of the particular lens.

While otherwise straighforward, the nonlinear nature of the lens distortion makes the problem challenging.

Define distortion model

We begin by defining our distortion model:

% Parameters
syms k_1 k_2 p_1 p_2 real
syms r x y
distortionX = subs(x * (1 + k_1 * r^2 + k_2 * r^4) + 2 * p_1 * x * y + p_2 * (r^2 + 2 * x^2), r, sqrt(x^2 + y^2))
distortionX = 

distortionY = subs(y * (1 + k_1 * r^2 + k_2 * r^4) + 2 * p_2 * x * y + p_1 * (r^2 + 2 * y^2), r, sqrt(x^2 + y^2))
distortionY = 

Radial Distortion

We plot a grid of pixel locations assuming our lens has a radial distortion coefficient k (1) = 0.1. Note that distortion is smallest near the center of the image and largest near the edges.

% Set Parameters
parameters = [k_1 k_2 p_1 p_2];
parameterValues = [0 0 0 0];
plotLensDistortion(distortionX,distortionY,parameters,parameterValues)
spacing = 0.2000
distortionX = 

distortionY = 

Radial Distortion

Explore the sensitivity to changes in

% Set Parameters
parameters = [k_1 k_2 p_1 p_2];
parameterValues = [0.15 0 0 0];
plotLensDistortion(distortionX,distortionY,parameters,parameterValues)
spacing = 0.2000
distortionX = 

distortionY = 

Calculate Inverse Distortion Model

Given a camera's lens distortion coefficients and a set of distorted pixel locations (x (2) , y (2) ), we want to be able to calculate the undistorted pixel locations (x (1) , y (1) ). We will look at the specific case where all distortion coefficients are zero except for k (1) which equals 0.2.

We begin by defining the distortion coeffcients

syms X Y  positive
eq1 = X == distortionX
eq1 = 

eq2 = Y == distortionY
eq2 = 

We define the distortion equations for given distortion coefficients, and solve for the undistorted pixel locations (x (1) , y (1) ).

parameters = [k_1 k_2 p_1 p_2];
parameterValues = [0.2 0 0 0];
eq1 = expand(subs(eq1, parameters, parameterValues))
eq1 = 

eq2 = expand(subs(eq2, parameters, parameterValues))
eq2 = 

Result = solve([eq1, eq2], [x,y], 'MaxDegree', 3,'Real',true)
Result = struct with fields:
    x: [1x1 sym]
    y: [1x1 sym]

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

[Result.x Result.y]
ans = 

Now we have analytical expressions for the pixel locations X and Y which we can use to undistort our images.

Function for drawing the lens distortion

function plotLensDistortion(distortionX,distortionY,parameters,parameterValues)
% distortionX is the expression describing the distorted x coordinate
% distortionY is the expression describing the distorted y coordinate
% k1 and k2 are the radial distortion coefficients 
% p1 and p2 are the tangential distortion coefficients 

syms x y

% This is the grid spacing over the image
spacing = .2

% Inspect and parametrically substitue in the values for k_1 k_2 p_1 p_2
distortionX = subs(distortionX,parameters,parameterValues)
distortionY = subs(distortionY,parameters,parameterValues)

% Loop over the grid
for x_i = -1:spacing:1
    for y_j = -1:spacing:1
        
        % Compuute the distorted location 
        xout = subs(distortionX, {x,y}, {x_i,y_j});
        yout = subs(distortionY, {x,y}, {x_i,y_j});
        
        % Plot the original point
        plot(x_i,y_j, 'o', 'Color', [1.0, 0.0, 0.0])
        hold on
       
        % Draw the distortion direction with Quiver
        p1 = [x_i,y_j];                     % First Point
        p2 = [xout,yout];                   % Second Point
        dp = p2-p1;                         % Difference
        quiver(p1(1),p1(2),dp(1),dp(2),'AutoScale','off','MaxHeadSize',1,'Color',[0 0 1])
        
    end
end
hold off
grid on

end

Copyright MathWorks 2016

Was this topic helpful?