18 votes

Homographie OpenCV, Transformer un point, que fait ce code ?

Je travaille avec une homographie calculée par OpenCV. J'utilise actuellement cette homographie pour transformer des points en utilisant la fonction ci-dessous. Cette fonction accomplit la tâche dont j'ai besoin, mais je n'ai aucune idée de la manière dont elle fonctionne réellement.

Est-ce que quelqu'un peut expliquer, ligne par ligne exactement, la logique/théorie derrière les 3 dernières lignes de code, je comprends que cela transforme le point x,y mais je ne comprends pas pourquoi cela fonctionne :

Pourquoi les Z , px y py calculés de cette manière, que font les éléments de h correspondent ?

Vos commentaires sont très appréciés :)

double h[9];
homography = cvMat(3, 3, CV_64F, h);
CvMat ps1 = cvMat(MAX_CALIB_POINTS/2,2,CV_32FC1, points1);
CvMat ps2 = cvMat(MAX_CALIB_POINTS/2,2,CV_32FC1, points2);

cvFindHomography(&ps1, &ps2, &homography, 0);

...

// This is the part I don't fully understand
double x = 10.0;
double y = 10.0;
double Z = 1./(h[6]*x + h[7]*y + h[8]);
px = (int)((h[0]*x + h[1]*y + h[2])*Z);
py = (int)((h[3]*x + h[4]*y + h[5])*Z);

34voto

Ben Points 1187

cvFindHomography() retourne une matrice en utilisant coordonnées homogènes :

Les coordonnées homogènes sont omniprésentes dans le domaine de l'infographie car elles permettent d'effectuer des opérations courantes telles que la translation, la rotation, la mise à l'échelle et la projection en perspective sous forme d'opérations matricielles.

Ce qui se passe dans le code : Le point cartésien p_origin_cartesian(x,y) est transformée en coordonnées homogènes, puis la matrice de transformation de perspective 3x3 h est appliquée et le résultat est reconverti en coordonnées cartésiennes p_transformed_cartesian(px,py) .

UPDATE

En détail :

Convertir p_origin_cartesian a p_origin_homogenous :

(x,y)  =>  (x,y,1)

Faites une transformation de perspective :

p_transformed_homogenous = h * p_origin_homogenous =

(h0,h1,h2)    (x)   (h0*x + h1*y + h2)   (tx)   
(h3,h4,h5)  * (y) = (h3*x + h4*y + h5) = (ty) 
(h6,h7,h8)    (1)   (h6*x + h7*y + h8)   (tz)

Convertir p_transformed_homogenous a p_transformed_cartesian :

(tx,ty,tz)  =>  (tx/tz, ty/tz) 

Votre code a été traduit :

px = tx/tz;
py = ty/tz;
Z  = 1/tz;

5voto

Flayn Points 532

Implémentation OpenCV Python suivant la réponse de @Ben

p = np.array((x,y,1)).reshape((3,1))
temp_p = M.dot(p)
sum = np.sum(temp_p ,1)
px = int(round(sum[0]/sum[2]))
py = int(round(sum[1]/sum[2]))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X