Преобразование изображения с использованием углов крена-тангажа-рыскания (выпрямление изображения)

Я работаю над приложением, где мне нужно исправить изображение, взятое с платформы мобильной камеры. Платформа измеряет углы крена, тангажа и рыскания, и я хочу, чтобы это выглядело так, как будто изображение взято непосредственно сверху, каким-то преобразованием из этой информации.

Я пытался сделать это через OpenCV(C++) и Matlab, но мне кажется, что мне не хватает чего-то фундаментального о том, как это делается.

в Matlab я попробовал следующее:

%% Transform perspective
img = imread('my_favourite_image.jpg');
R = R_z(yaw_angle)*R_y(pitch_angle)*R_x(roll_angle);
tform = projective2d(R);   
outputImage = imwarp(img,tform);
figure(1), imshow(outputImage);

где R_z/y / x-стандартные вращательные матрицы (реализованные с градусами).

для некоторого рыскания-вращения все работает просто отлично:

R = R_z(10)*R_y(0)*R_x(0);

что дает результат:

Image rotated 10 degrees about the Z-image axis

если я попытаюсь повернуть изображение на ту же сумму о X - или Y-осях, я получаю такие результаты:

R = R_z(10)*R_y(0)*R_x(10);

Image rotated 10 degrees about the X-image axis

однако, если я вращаюсь на 10 градусов, разделенный на какое-то огромное число, он начинает выглядеть нормально. Но опять же, это результат, который не имеет никакого исследовательского значения, что так всегда:

R = R_z(10)*R_y(0)*R_x(10/1000);

Image rotated 10/1000 degrees about the X-image axis

может кто - нибудь, пожалуйста, помогите мне понять, почему вращение вокруг оси X или Y делает преобразование диким? Есть ли способ решить эту проблему без деление на случайное число и другие фокусы? Может быть, это можно решить с помощью каких-то параметров Эйлера? Любая помощь будет высоко ценится!

обновление: полная настройка и измерения

для полноты был добавлен полный тестовый код и начальное изображение, а также углы платформы Эйлера:

код:

%% Transform perspective
function [] = main()
    img = imread('some_image.jpg');
    R = R_z(0)*R_y(0)*R_x(10);
    tform = projective2d(R);   
    outputImage = imwarp(img,tform);
    figure(1), imshow(outputImage);
end

%% Matrix for Yaw-rotation about the Z-axis
function [R] = R_z(psi)
    R = [cosd(psi) -sind(psi) 0;
         sind(psi)  cosd(psi) 0;
         0          0         1];
end

%% Matrix for Pitch-rotation about the Y-axis
function [R] = R_y(theta)
    R = [cosd(theta)    0   sind(theta);
         0              1   0          ;
         -sind(theta)   0   cosd(theta)     ];
end

%% Matrix for Roll-rotation about the X-axis
function [R] = R_x(phi)
    R = [1  0           0;
         0  cosd(phi)   -sind(phi);
         0  sind(phi)   cosd(phi)];
end

исходное изображение:

enter image description here

камера измерения платформы в координатной рамке кузова:

Roll:     -10
Pitch:    -30
Yaw:      166 (angular deviation from north)

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

дополнительная информация:

Я хотел бы указать, что среда, в которой будет использоваться настройка, не содержит линий (океаническая фотография), которые могут надежно использоваться в качестве ссылки (горизонт обычно не будет на картинке). Также квадрат в начальном изображение просто используется в качестве меры, чтобы увидеть, правильно ли преобразование, и не будет там в реальном сценарии.

4 ответов


Итак, это то, что я закончил: я понял, что если вы на самом деле не имеете дело с 3D-изображениями, исправление перспективы фотографии-это 2D-операция. Имея это в виду, Я заменил значения Z-оси матрицы преобразования нулями и единицами и применил 2D аффинное преобразование к изображению.

вращение исходного изображения (см. начальный пост) с измеренным креном = -10 и шагом = -30 было сделано следующим образом:

R_rotation = R_y(-60)*R_x(10); 
R_2d       = [   R_rot(1,1)  R_rot(1,2) 0; 
                 R_rot(2,1)  R_rot(2,2) 0;
                 0           0          1    ] 

Это подразумевает поворот платформы камеры к ориентации виртуальной камеры, где камера расположена над сценой, указывая прямо вниз. Обратите внимание на значения, используемые для roll и pitch в приведенной выше матрице.

кроме того, при повороте изображения так, чтобы оно было выровнено с заголовком платформы, может быть добавлено вращение вокруг оси z, давая:

R_rotation = R_y(-60)*R_x(10)*R_z(some_heading); 
R_2d       = [   R_rot(1,1)  R_rot(1,2) 0; 
                 R_rot(2,1)  R_rot(2,2) 0;
                 0           0          1    ] 

обратите внимание, что это не изменяет фактическое изображение - оно только вращает его.

в результате исходное изображение повернутый вокруг осей Y и X выглядит так:

enter image description here

полный код для этого преобразования, как показано выше, было:

% Load image
img = imread('initial_image.jpg'); 

% Full rotation matrix. Z-axis included, but not used.
R_rot = R_y(-60)*R_x(10)*R_z(0); 

% Strip the values related to the Z-axis from R_rot
R_2d  = [   R_rot(1,1)  R_rot(1,2) 0; 
            R_rot(2,1)  R_rot(2,2) 0;
            0           0          1    ]; 

% Generate transformation matrix, and warp (matlab syntax)
tform = affine2d(R_2d);
outputImage = imwarp(img,tform);

% Display image
figure(1), imshow(outputImage);



%*** Rotation Matrix Functions ***%

%% Matrix for Yaw-rotation about the Z-axis
function [R] = R_z(psi)
    R = [cosd(psi) -sind(psi) 0;
         sind(psi)  cosd(psi) 0;
         0          0         1];
end

%% Matrix for Pitch-rotation about the Y-axis
function [R] = R_y(theta)
    R = [cosd(theta)    0   sind(theta);
         0              1   0          ;
         -sind(theta)   0   cosd(theta)     ];
end

%% Matrix for Roll-rotation about the X-axis
function [R] = R_x(phi)
    R = [1  0           0;
         0  cosd(phi)   -sind(phi);
         0  sind(phi)   cosd(phi)];
end

Спасибо за поддержку, я надеюсь, что это помогает кто-то!


Я думаю, вы можете получить преобразование таким образом:

1) пусть у вас есть четыре 3d-точки A(-1,-1,0), B(1,-1,0), C(1,1,0) и D(-1,1,0). Можно взять любые 4 неколлинеарные точки. Они не связаны с образом.

2) у вас есть матрица преобразования, поэтому вы можете установить камеру, умножая координаты точек на матрицу преобразования. И вы получите 3d-координаты относительно положения/направления камеры.

3) вам нужно получить проекцию ваших точек на плоскость экрана. Самый простой способ - использовать ортографическую проекцию (просто игнорировать координату глубины). На этом этапе у вас есть 2D-проекции преобразованных точек.

4) Как только у вас есть 2 набора 2D-координат точек (набор из Шага 1 Без 3-й координаты и набор из Шага 3), Вы можете вычислить матрицу гомографии стандартным способом.

5) применить обратное преобразование homograhy в ваш образ.


вам нужно оценить гомографию. Готовое решение Matlab см. В разделе функция vgg_H_from_x_lin.m от http://www.robots.ox.ac.uk / ~vgg/hzbook / code/ .

для теории копаться в учебник компьютерного зрения, например, тот, который доступен свободно на http://szeliski.org/Book/ или в главе 3http://programmingcomputervision.com/downloads/ProgrammingComputerVision_CCdraft.pdf


возможно, мой ответ неверен из-за моего неправильного понимания параметров камеры, но мне было интересно, является ли рыскание/шаг/крен относительно положения вашего объекта. Я использовал формулу общие поворотов, и мой код ниже (функций вращения R_x, R_y и R_z были скопированы с ваших, я не вставлял их сюда)

close all
file='http://i.stack.imgur.com/m5e01.jpg'; % original image
I=imread(file);

R_rot = R_x(-10)*R_y(-30)*R_z(166);
R_rot = inv(R_rot);

R_2d  = [   R_rot(1,1)  R_rot(1,2) 0; 
            R_rot(2,1)  R_rot(2,2) 0;
            0           0          1    ]; 


T = maketform('affine',R_2d);

transformedI = imtransform(I,T);
        figure, imshow(I), figure, imshow(transformedI)

результат:

enter image description here

это означает, что вам все еще нужны некоторые операция вращения, чтобы получить "правильное" выравнивание в вашем уме (но, вероятно, не нужно правильное положение в уме камеры). Поэтому я меняюсь R_rot = inv(R_rot); до R_rot = inv(R_rot)*R_x(-5)*R_y(25)*R_z(180);, и теперь он дал мне:

enter image description here

выглядит лучше, как то, что вы хотите. Спасибо.