В этом примере создается математическая модель с помощью инструментария «Символьная математика» (Symbolic Math Toolbox) для отмены искажения изображения и имеет локальную функцию в живом сценарии.
Любая точка реального мира Z) может быть определена относительно некоторого 3-D мирового происхождения.
Относительно объектива камеры эта точка 3-D может быть определена как , которая получается вращением и переводом .
z0) RP + t
Точка 3-D затем проецируется в плоскость изображения камеры как точка 2D (, y1).
,
Когда камера захватывает изображение, она точно не захватывает реальные точки, а, скорее, слегка искаженную версию реальных точек, которые можно обозначить (, y2). Искаженные точки могут быть описаны с помощью следующей функции:
где:
, = коэффициенты радиального искажения объектива
, = коэффициенты тангенциального искажения линзы
y12
Пример искажения линзы показан ниже; исходное искаженное изображение (слева) и неискаженное изображение (справа).

Обратите внимание на кривизну линий по направлению к краям первого изображения. Для таких приложений, как восстановление и отслеживание изображений, важно знать реальное местоположение точек. Когда мы имеем искаженное изображение, мы знаем искаженные местоположения пикселей (, y2). Наша цель - определить неискаженные местоположения пикселей x1y1), заданные 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 =
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 =
Радиальное искажение 0
Мы строим сетку местоположений пикселей, предполагая, что наша линза имеет коэффициент радиального искажения 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 =
distortionY =

Радиальное искажение 0,15
Изучите чувствительность к изменениям в .
% 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 =

Учитывая коэффициенты искажения объектива камеры и набор искаженных местоположений пикселей (, y2), мы хотим иметь возможность вычислить неискаженные местоположения пикселей x1y1). Рассмотрим конкретный случай, когда все коэффициенты искажения равны нулю, за исключением k1, который равен 0,2.
Мы начинаем с определения коэффициентов искажения
syms X Y positive eq1 = X == distortionX
eq1 =
eq2 = Y == distortionY
eq2 =
Мы определяем уравнения искажений для заданных коэффициентов искажений и решаем для неискаженных местоположений пикселей (, y1).
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