correction - Homografía OpenCV, Transforme un punto, ¿qué está haciendo este código?
homography opencv (2)
Estoy trabajando con una homografía calculada por OpenCV. Actualmente uso esta homografía para transformar puntos usando la función a continuación. Esta función realiza la tarea que requiero, sin embargo, no tengo idea de cómo funciona realmente.
¿Puede alguien explicar, línea por línea exactamente, la lógica / teoría detrás de las últimas 3 líneas de código, entiendo que esto transforma el punto x, y pero no estoy seguro de por qué esto funciona?
¿Por qué se calculan Z
, px
y py
de esta manera, a qué se corresponden los elementos en h
?
Sus comentarios son muy apreciados :)
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);
cvFindHomography()
devuelve una matriz usando coordenadas homogéneas :
Las coordenadas homogéneas son omnipresentes en los gráficos por computadora porque permiten que las operaciones comunes como la traducción, la rotación, la escala y la proyección en perspectiva se implementen como operaciones matriciales
Qué está sucediendo en el código: el punto cartesiano p_origin_cartesian(x,y)
se transforma en coordenadas homogéneas, luego se aplica la matriz de transformación de perspectiva 3x3 h
y el resultado se convierte de nuevo en coordenadas cartesianas p_transformed_cartesian(px,py)
.
ACTUALIZAR
En detalle:
Convierte p_origin_cartesian
en p_origin_homogenous
:
(x,y) => (x,y,1)
Hacer transformación de perspectiva:
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)
Convierte p_transformed_homogenous
a p_transformed_cartesian
:
(tx,ty,tz) => (tx/tz, ty/tz)
Tu código traducido:
px = tx/tz;
py = ty/tz;
Z = 1/tz;
Implementación de OpenCV Python siguiendo la respuesta 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]))