exponenta event banner

Разработка алгоритма для отмены искажения изображения

В этом примере создается математическая модель с помощью инструментария «Символьная математика» (Symbolic Math Toolbox) для отмены искажения изображения и имеет локальную функцию в живом сценарии.

Фон

Любая точка реального мира P (X, Y, Z) может быть определена относительно некоторого 3-D мирового происхождения.

Относительно объектива камеры эта точка 3-D может быть определена как p0, которая получается вращением и переводом P.

p0 = (x0, y0, z0) = RP + t

Точка 3-D p0 затем проецируется в плоскость изображения камеры как точка 2D (x1, y1).

x1=x0z0, y1=y0z0

Когда камера захватывает изображение, она точно не захватывает реальные точки, а, скорее, слегка искаженную версию реальных точек, которые можно обозначить (x2, y2). Искаженные точки могут быть описаны с помощью следующей функции:

x2=x1 (1+k1r2+k2r4) +2p1x1y1+p2 (r2+2x12)

y2=y1 (1+k1r2+k2r4) +2p2x1y1+p1 (r2+2y12)

где:

k1, k2 = коэффициенты радиального искажения объектива

p1, p2 = коэффициенты тангенциального искажения линзы

r = x12 + y12

Искажение

Пример искажения линзы показан ниже; исходное искаженное изображение (слева) и неискаженное изображение (справа).

Обратите внимание на кривизну линий по направлению к краям первого изображения. Для таких приложений, как восстановление и отслеживание изображений, важно знать реальное местоположение точек. Когда мы имеем искаженное изображение, мы знаем искаженные местоположения пикселей (x2, y2). Наша цель - определить неискаженные местоположения пикселей (x1, y1), заданные (x2, y2), и коэффициенты искажения конкретной линзы.

Хотя в остальном это просто, нелинейный характер искажения линзы делает проблему сложной.

Определение модели искажения

Мы начинаем с определения нашей модели искажения:

% 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 = p23x2+y2+xk2x2+y22+k1x2+y2+1+2p1xyp_2*(3*x^2 + y^2) + x*(k_2*(x^2 + y^2)^2 + k_1*(x^2 + y^2) + 1) + 2*p_1*x*y
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 = p1x2+3y2+yk2x2+y22+k1x2+y2+1+2p2xyp_1*(x^2 + 3*y^2) + y*(k_2*(x^2 + y^2)^2 + k_1*(x^2 + y^2) + 1) + 2*p_2*x*y

Радиальное искажение k1 = 0

Мы строим сетку местоположений пикселей, предполагая, что наша линза имеет коэффициент радиального искажения k1 = 0. Заметим, что искажение является наименьшим вблизи центра изображения и наибольшим вблизи краев.

% 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 = xx
distortionY = yy

Figure contains an axes. The axes contains 242 objects of type line, quiver.

Радиальное искажение k1 = 0,15

Изучите чувствительность к изменениям в k1.

% 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 = 

x3x220+3y220+1x*((3*x^2)/20 + (3*y^2)/20 + 1)

distortionY = 

y3x220+3y220+1y*((3*x^2)/20 + (3*y^2)/20 + 1)

Figure contains an axes. The axes contains 242 objects of type line, quiver.

Расчет модели обратного искажения

Учитывая коэффициенты искажения объектива камеры и набор искаженных местоположений пикселей (x2, y2), мы хотим иметь возможность вычислить неискаженные местоположения пикселей (x1, y1). Рассмотрим конкретный случай, когда все коэффициенты искажения равны нулю, за исключением k1, который равен 0,2.

Мы начинаем с определения коэффициентов искажения

syms X Y positive
eq1 = X == distortionX
eq1 = X=p23x2+y2+xk2x2+y22+k1x2+y2+1+2p1xyX == p_2*(3*x^2 + y^2) + x*(k_2*(x^2 + y^2)^2 + k_1*(x^2 + y^2) + 1) + 2*p_1*x*y
eq2 = Y == distortionY
eq2 = Y=p1x2+3y2+yk2x2+y22+k1x2+y2+1+2p2xyY == p_1*(x^2 + 3*y^2) + y*(k_2*(x^2 + y^2)^2 + k_1*(x^2 + y^2) + 1) + 2*p_2*x*y

Мы определяем уравнения искажений для заданных коэффициентов искажений и решаем для неискаженных местоположений пикселей (x1, y1).

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

X=x35+xy25+xX == x^3/5 + (x*y^2)/5 + x

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

Y=x2y5+y35+yY == (x^2*y)/5 + y^3/5 + y

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

Поскольку элемент 1 является единственным реальным решением, мы извлекаем это выражение в его собственную переменную.

[Result.x Result.y]
ans = 

(Xσ1Yσ1)where  σ1=σ2-5Y23X2+Y2σ2  σ2=5Y32X2+Y2+25Y64X2+Y22+125Y627X2+Y231/3[(X*(((5*Y^3)/(2*(X^2 + Y^2)) + sqrt((25*Y^6)/(4*(X^2 + Y^2)^2) + (125*Y^6)/(27*(X^2 + Y^2)^3)))^sym(1/3) - (5*Y^2)/(3*(X^2 + Y^2)*((5*Y^3)/(2*(X^2 + Y^2)) + sqrt((25*Y^6)/(4*(X^2 + Y^2)^2) + (125*Y^6)/(27*(X^2 + Y^2)^3)))^sym(1/3))))/Y, (((5*Y^3)/(2*(X^2 + Y^2)) + sqrt((25*Y^6)/(4*(X^2 + Y^2)^2) + (125*Y^6)/(27*(X^2 + Y^2)^3)))^sym(1/3) - (5*Y^2)/(3*(X^2 + Y^2)*((5*Y^3)/(2*(X^2 + Y^2)) + sqrt((25*Y^6)/(4*(X^2 + Y^2)^2) + (125*Y^6)/(27*(X^2 + Y^2)^3)))^sym(1/3)))]

Теперь у нас есть аналитические выражения для местоположений пикселей X и Y, которые мы можем использовать для отмены искажения наших изображений.

Функция рисования искажения объектива

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 = 0.2

% Inspect and parametrically substitute 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
        
        % Compute 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