matlab opencv image-processing image-rotation euler-angles

matlab - Transforme la imagen utilizando los ángulos Roll-Pitch-Yaw(rectificación de imagen)



opencv image-processing (4)

Creo que puedes derivar la transformación de esta manera:

1) Deje que tenga cuatro puntos 3d A (-1, -1,0), B (1, -1,0), C (1,1,0) y D (-1,1,0). Puedes tomar cualquiera de los 4 puntos no colineales. No se relacionan con la imagen.

2) Tiene una matriz de transformación, por lo que puede configurar su cámara multiplicando los puntos por la matriz de transformación. Y obtendrá coords 3D relativos a la posición / dirección de la cámara.

3) Necesitas obtener una proyección de tus puntos en el plano de la pantalla. La forma más sencilla es usar la proyección ortográfica (simplemente ignorar la coordenada de profundidad). En esta etapa tienes proyecciones 2D de puntos transformados.

4) Una vez que tenga 2 conjuntos de coordenadas de puntos 2D (el conjunto del paso 1 sin la tercera coordenada y el conjunto del paso 3), puede calcular la matriz de homografía de manera estándar.

5) Aplica la transformación de homografía inversa a tu imagen.

Estoy trabajando en una aplicación en la que necesito rectificar una imagen tomada desde una plataforma de cámara móvil. La plataforma mide los ángulos de balanceo, inclinación y desvío, y quiero que se vea como si la imagen se tomara directamente desde arriba, mediante algún tipo de transformación a partir de esta información.

En otras palabras, quiero que se transforme un cuadrado perfecto que se acueste en el suelo, fotografiado desde lejos con cierta orientación de la cámara, para que el cuadrado quede perfectamente simétrico después.

He estado tratando de hacer esto a través de OpenCV (C ++) y Matlab, pero parece que me falta algo fundamental sobre cómo se hace esto.

En Matlab, he intentado lo siguiente:

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

Donde R_z / y / x son las matrices de rotación estándar (implementadas con grados).

Para algunos giros de giro, todo funciona bien:

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

Lo que da el resultado:

Si trato de rotar la imagen en la misma cantidad sobre los ejes X o Y, obtengo resultados como este:

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

Sin embargo, si lo roto por 10 grados, dividido por un número enorme, comienza a verse bien. Pero, de nuevo, este es un resultado que no tiene ningún valor de investigación:

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

¿Puede alguien ayudarme, por favor, a entender por qué rotar sobre los ejes X o Y hace que la transformación se vuelva loca? ¿Hay alguna forma de resolver esto sin dividir entre un número aleatorio y otros trucos de magia? ¿Es esto tal vez algo que se pueda resolver utilizando los parámetros de Euler de algún tipo? Cualquier ayuda será muy apreciada!

Actualización: configuración completa y medidas

Para completar, se han agregado el código de prueba completo y la imagen inicial, así como los ángulos de Euler de las plataformas:

Código:

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

La imagen inicial:

Medidas de la plataforma de la cámara en el marco de coordenadas del CUERPO:

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

Por lo que entiendo, el ángulo de Yaw no es directamente relevante para la transformación. Sin embargo, podría estar equivocado acerca de esto.

Información adicional:

Me gustaría especificar que el entorno en el que se usará la configuración no contenga líneas (foto oceánica) que puedan usarse de manera confiable como referencia (el horizonte generalmente no estará en la imagen). Además, el cuadrado en la imagen inicial se usa simplemente como una medida para ver si la transformación es correcta y no estará allí en un escenario real.



Por lo tanto, esto es lo que terminé haciendo: pensé que a menos que esté tratando con imágenes en 3D, rectificar la perspectiva de una foto es una operación en 2D. Con esto en mente, reemplacé los valores del eje z de la matriz de transformación con ceros y unos, y apliqué una transformación Afín 2D a la imagen.

La rotación de la imagen inicial (ver publicación inicial) con el Rollo medido = -10 y el Paso = -30 se realizó de la siguiente manera:

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 ]

Esto implica una rotación de la plataforma de la cámara a una orientación de cámara virtual donde la cámara se coloca por encima de la escena, apuntando hacia abajo. Tenga en cuenta los valores utilizados para roll y pitch en la matriz anterior.

Además, si gira la imagen de manera que esté alineada con el rumbo de la plataforma, se puede agregar una rotación sobre el eje z, dando:

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 ]

Tenga en cuenta que esto no cambia la imagen real, solo la gira.

Como resultado, la imagen inicial girada alrededor de los ejes Y y X se ve así:

El código completo para hacer esta transformación, como se muestra arriba, fue:

% 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

Gracias por el apoyo, espero que esto ayude a alguien!


Tal vez mi respuesta no sea correcta debido a mi falta de comprensión de los parámetros de la cámara, pero me preguntaba si la Yaw / Pitch / Roll es relativa a la posición de su objeto. R_x la fórmula de rotaciones generales , y mi código está debajo (las funciones de rotación R_x , R_y y R_z se copiaron de las suyas, no las R_z aquí)

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)

El resultado:

Esto indica que aún necesita alguna operación de rotación para obtener la alineación ''correcta'' en su mente (pero probablemente no sea necesaria la posición correcta en la mente de la cámara). Así que cambio R_rot = inv(R_rot); a R_rot = inv(R_rot)*R_x(-5)*R_y(25)*R_z(180); , y ahora me dio:

Se ve mejor como lo que quieres. Gracias.