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

Этот пример разрабатывает математическую модель, используя Symbolic Math Toolbox, чтобы не искажать изображение, и имеет локальную функцию в live скрипте.

Фон

Любая точка реального мира 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