Я работаю над приложением, в котором мне нужно исправить изображение, снятое с платформы мобильной камеры. Платформа измеряет углы крена, тангажа и рыскания, и я хочу, чтобы это выглядело так, как будто изображение взято прямо сверху, путем некоторого преобразования этой информации.
Другими словами, я хочу, чтобы идеальный квадрат, лежащий плоско на земле, сфотографированный издалека с некоторой ориентацией камеры, трансформировался так, чтобы впоследствии квадрат был идеально симметричным.
Я пытался сделать это с помощью OpenCV (С++) и 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);
Что дает результат:
Если я попытаюсь повернуть изображение на одинаковую величину по осям X или Y, я получу такие результаты:
R = R_z(10)*R_y(0)*R_x(10);
Однако, если я поверну на 10 градусов, разделенных на какое-то огромное число, все будет выглядеть нормально. Но опять же, это результат, который не имеет никакой исследовательской ценности:
R = R_z(10)*R_y(0)*R_x(10/1000);
Может кто-нибудь, пожалуйста, помогите мне понять, почему вращение вокруг осей 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
Исходное изображение:
Размеры платформы камеры в системе координат BODY:
Roll: -10
Pitch: -30
Yaw: 166 (angular deviation from north)
Насколько я понимаю, угол рыскания не имеет прямого отношения к трансформации. Впрочем, я могу ошибаться в этом.
Дополнительная информация:
Я хотел бы уточнить, что среда, в которой будет использоваться установка, не содержит линий (фотографии океана), которые можно надежно использовать в качестве ориентира (горизонта обычно не будет на снимке). Кроме того, квадрат в исходном изображении просто используется как мера, чтобы увидеть, правильно ли преобразование, и его не будет в реальном сценарии.
R
, и это должно помочь. - person scap3y   schedule 08.12.2013