Я работаю над приложением, где мне нужно исправить изображение, взятое с платформы мобильной камеры. Платформа измеряет углы поворота, высоты тона и угла поворота, и я хочу, чтобы это выглядело так, будто изображение берется из непосредственно выше, каким-то образом преобразуется из этой информации.
Другими словами, мне нужен идеальный квадрат, лежащий на земле, сфотографированный издалека с некоторой ориентацией камеры, который должен быть преобразован, чтобы квадрат был совершенно симметричным впоследствии.Я пытаюсь сделать это через 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)
Из того, что я понимаю, угол Yaw не имеет прямого отношения к трансформации. Возможно, я ошибаюсь.
Дополнительная информация:
Я хотел бы указать, что среда, в которой будет использоваться установка, не содержит строк (океаническая фотография), которые могут быть надежно использованы в качестве ссылки (горизонт обычно не будет на картинке). Также квадрат в исходном изображении просто используется в качестве меры для проверки правильности преобразования и не будет присутствовать в реальном сценарии.