2013-12-07 6 views
15

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

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

Я пытаюсь сделать это через 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/у/х являются стандартными вращательными матрицы (реализован с градусами).

Для некоторых рыскания вращения, все это работает просто отлично:

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-оси делает преобразование идти дикой природы ? Есть ли способ решить это без деления на случайное число и другие магические трюки? Возможно, это что-то, что можно решить с помощью параметров Эйлера? Любая помощь будет высоко оценена!

Update: Полная настройка и измерения

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

Код:

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

Из того, что я понимаю рыскания угол не имеет прямого отношения к трансформации. Возможно, я ошибаюсь.

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

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

+0

Не могли бы вы загрузить исходное изображение и реализацию матрицы вращения? – scap3y

+0

Привет, Scap3y! Я добавил полный набор информации и код для проблемы в вышеприведенном сообщении. –

+2

Хорошо, я думаю, вы пропустили важный шаг: найти гомографию по отношению к горизонтальным проекциям линий на изображении. Пожалуйста, обратитесь к [этой ссылке] (http://notbrainsurgery.livejournal.com/40465.html), чтобы получить представление о том, как заставить его работать. После того, как вы рассчитали гомографию, вы можете подключить ее вместо своей матрицы «R», и это должно сделать трюк. – scap3y

ответ

7

Итак, это то, что я закончил: я понял, что, если вы на самом деле не имеете дело с 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 ] 

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

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

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 

Благодарим вас за поддержку, надеюсь, это поможет кому-то!

3

Я думаю, что вы можете получить этот путь трансформации:

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

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

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

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

5) Применение обратного преобразования гомограхи к вашему изображению.

+0

Вы, безусловно, правы, что это 2D-преобразование. Спасибо! :) –

2

Может быть, мой ответ не является правильным из-за мое неправильное понимание параметров камеры, но Мне было интересно, является ли Yaw/Pitch/Roll относительно позиции вашего объекта. Я использовал формулу general rotations, и мой код ниже (функции вращения 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

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

+1

Спасибо за ваш ответ! Я более или менее заключил одно и то же мгновение назад (см. Третий пост этой темы). Вращательные значения имеют смысл, если вы поместите вращения в порядке YXZ и рассмотрите, каково фактическое состояние цели кадра камеры (камера направлена ​​вниз сверху над сценой). Для этого вам необходимо повернуть рамку камеры на оставшуюся часть (90 градусов) градусов против часовой стрелки по оси y и положительный угол поворота по часовой стрелке по оси x. Вращение рыскания очень необязательно и имеет значение только в том случае, если у вас есть платформа для поиска в северном направлении. :-) –

Смежные вопросы