Transformer L'Image en utilisant des angles de roulis-tangage-lacet (rectification de L'Image)

je travaille sur une application où je dois rectifier une image prise à partir d'une plateforme de caméra mobile. La plateforme mesure les angles de roulis, de tangage et de lacet, et je veux faire en sorte que l'image soit prise directement au-dessus, par une sorte de transformation à partir de cette information.

en d'autres termes, je veux qu'un carré parfait posé à plat sur le sol, photographié de loin avec une certaine orientation de caméra, soit transformé, de sorte que le carré soit parfaitement symétrique par la suite.

J'ai essayé de le faire à travers OpenCV (C++) et Matlab, mais il semble que je manque quelque chose de fondamental sur la façon dont cela est fait.

Dans Matlab, j'ai essayé le code suivant:

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

où R_z/y / x sont les matrices rotationnelles standard (implémentées en degrés).

Pour certains, le lacet de rotation, tout fonctionne parfaitement:

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

ce Qui donne le résultat:

Image rotated 10 degrees about the Z-image axis

Si j'essaie d' rotation de l'image par la même quantité autour des axes X ou Y, j'obtiens des résultats comme ceci:

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

Image rotated 10 degrees about the X-image axis

cependant, si je tourne de 10 degrés, divisé par un nombre énorme, il commence à sembler OK. Mais encore une fois, il s'agit d'un résultat qui n'a aucune valeur de recherche.--7-->

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

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

quelqu'un peut - il s'il vous plaît m'aider à comprendre pourquoi tourner autour des axes X ou Y rend la transformation sauvage? Est-il de toute façon de résoudre cela sans diviser par un nombre aléatoire et d'autres tours de magie? Est-ce quelque chose qui peut être résolu en utilisant des paramètres D'Euler? Toute aide sera très appréciée!

mise à Jour: installation Complète et mesures

pour être complet, le code de test complet et l'image initiale ont été ajoutés, ainsi que les plateformes Euler angles:

Code:

%% 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 première image:

enter image description here

mesures de la plate-forme de la caméra dans le cadre des coordonnées du corps:

Roll:     -10
Pitch:    -30
Yaw:      166 (angular deviation from north)
<!-D'après ce que j'ai compris, l'angle de lacet n'est pas directement lié à la transformation. Je pourrait, toutefois, être mauvais à ce sujet.

renseignements supplémentaires:

je voudrais préciser que l'environnement dans lequel le programme d'installation sera utilisée ne contient pas de lignes (océanique photo) fiable utilisé comme référence (l'horizon habituellement ne pas être dans l'image). Également de la place dans l'image initiale est simplement utilisé comme une mesure de voir si la transformation est correcte, et ne sera pas là dans un véritable scénario.

16
demandé sur Tormod Haugene 2013-12-07 22:48:20

4 réponses

donc, c'est ce que j'ai fini par faire: je me suis dit qu'à moins que vous ayez réellement affaire à des images 3D, corriger la perspective d'une photo est une opération 2D. En gardant cela à l'esprit, j'ai remplacé les valeurs de l'axe z de la matrice de transformation par des zéros et des uns, et j'ai appliqué une transformation Affine 2D à l'image.

la Rotation de l'image initiale (voir le poteau initial) avec le roulis mesuré = -10 et le pas = -30 a été faite de la manière suivante:

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    ] 

cela implique un rotation de la plate-forme de la caméra vers une orientation virtuelle de la caméra où la caméra est placée au-dessus de la scène, pointant droit vers le bas. Remarque les valeurs utilisées pour le roulis et de tangage dans la matrice ci-dessus.

de plus, si on fait tourner l'image de façon à ce qu'elle soit alignée avec le titre de la plate-forme, on peut ajouter une rotation autour de l'axe z, ce qui donne:

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    ] 

notez que cela ne change pas l'image réelle - elle ne fait que tourner.

en conséquence, l'image initiale effectue une rotation autour de l'axe des X et des axes ressemble à:

enter image description here

le code complet pour effectuer cette transformation, comme indiqué ci-dessus, était:

% 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

Merci pour le soutien, j'espère que cela aide quelqu'un!

7
répondu Tormod Haugene 2013-12-09 19:27:21

je pense que vous pouvez tirer de la transformation de cette façon:

1) laissez vous avoir quatre 3d-points A(-1,-1,0), B(1,-1,0), C(1,1,0) et D(-1,1,0). Vous pouvez prendre n'importe quels 4 points non collinéaires. - Ils pas liés à l'image.

2) Vous avez une matrice de transformation, donc vous pouvez régler votre caméra en multipliant les points coords par la matrice de transformation. Et vous obtiendrez des accords 3d relatifs à la position/direction de la caméra.

3) vous devez obtenir la projection de vos points à l'écran plan. La manière la plus simple est d'utiliser la projection ortographique (en ignorant simplement les coordonnées de profondeur). Sur cette scène, vous avez des projections 2D de points transformés.

4) Une fois que vous avez 2 ensembles de coordonnées de points 2D (l'ensemble de l'étape 1 Sans 3-rd et l'ensemble de l'étape 3), vous pouvez calculer la matrice d'homographie de manière standard.

5) Appliquez la transformation inverse d'homograhy à votre image.

3
répondu Andrey Smorodov 2013-12-09 11:11:16

vous devez estimer une homographie. Pour une solution Matlab standard, voir la fonction vgg_H_from_x_lin.m from http://www.robots.ox.ac.uk/~vgg/hzbook/code/