Этот пример разрабатывает математическую модель, используя Symbolic Math Toolbox, чтобы не искажать изображение, и имеет локальную функцию в live скрипте.
Любая точка реального мира может быть определено относительно некоторые 3 -D мировые источники.
Относительно объектива камеры эта 3-D точка может быть задана как , что получается вращением и перемещением .
=
Точка 3-D затем проецируется в плоскость изображения камеры как точка 2D, (,).
,
Когда камера захватывает изображение, она не точно захватывает реальные точки, а, скорее, слегка искаженную версию реальных точек, которые можно обозначить (,). Искаженные точки могут быть описаны с помощью следующей функции:
где:
, = коэффициенты радиального искажения объектива
, = тангенциальные коэффициенты искажения объектива
Пример искажения объектива показан ниже; исходное искаженное изображение (слева) и неискаженное изображение (справа).
Обратите внимание на кривизну линий к ребрам первого изображения. Для таких приложений, как реконструкция изображений и отслеживание, важно знать реальное расположение точек в мире. Когда у нас есть искаженное изображение, мы знаем искаженные пиксельные местоположения (,). Наша цель - определить неискаженные пиксельные местоположения (,) данный (,) и коэффициенты искажения конкретной линзы.
В противном случае нелинейная природа искажения объектива делает задачу сложной.
Мы начинаем с определения нашей модели искажения:
% 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 =
Радиальное искажение
Мы строим сетку пиксельных местоположений, принимая, что наша линза имеет радиальный коэффициент искажения . Обратите внимание, что искажение является наименьшим около центра изображения и самым большим около ребер.
% 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 =
Радиальное искажение
Исследуйте чувствительность к изменениям в .
% 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 =
Учитывая коэффициенты искажения объектива камеры и набор искаженных пиксельных местоположений (,), мы хотим иметь возможность вычислить неискаженные пиксельные местоположения (,). Мы рассмотрим конкретный случай, когда все коэффициенты искажения равны нулю, кроме который равен 0,2.
Начнем с определения коэффициентов искажения
syms X Y positive eq1 = X == distortionX
eq1 =
eq2 = Y == distortionY
eq2 =
Зададим уравнения искажения для заданных коэффициентов искажения и решим для неискаженных пиксельных местоположений (,).
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]
Поскольку элемент 1 является единственным действительным решением, мы извлечём это выражение в его собственную переменную.
[Result.x Result.y]
ans =
Теперь у нас есть аналитические выражения для пиксельных местоположений 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