En el caso de detectar una sola marca te devuelve una matriz de transformación que representa la posición de la marca con respecto a la cámara. La salida del programa es la siguiente:
ARToolKitPlus: CamSize 320 , 240
ARToolKitPlus: Dist.Factor 159.00 139.00 -84.90 0.98
Found marker 100 (confidence 100%)
Pose-Matrix:
0.28 0.58 -0.77 0.00
0.96 -0.20 0.20 0.00
-0.04 -0.79 -0.61 0.00
6.29 -3.43 265.68 1.00
La duda que se plantea es cómo pasar de una matriz 3x3 a tres ángulos de rotación (uno por eje).
Teniendo en cuenta que la matriz de transformación esta basada en la matriz de OpenGl, la matriz de rotación se obtiene de la multiplicación de la multiplicación de las tres las matrices de rotación:

Realizando las siguientes simplificaciones: cx=Cos(x), cy=Cos(y), cz=Cos(z), stx=Sin(x), sty=Sin(y), stz=Sin(z), y multiplicando las tres rotaciones nos que daría la siguiente matriz:
[R] = | rotate about z (last rotation)
| * ( | rotate about y (second rotation)
| * | rotate about x (first rotation)
| ) |
[R] =
cy * cz | sx*sy*cz-cx*sz | cx*sy*cz+sx*sz |
cy * sz | sx*sy*sz +cx*cz | cx*sy*sz-sx*cz |
-sy | sx*cy | cx*cy |
De donde es fácil ver que:
Ang x = atan(r[2][1]/r[2][2])
Ang y = asin(-r[2][0])
Ang z = atan(r[0][0]/r[0][1])
De estas operaciones se observa que se puede producir "Gimbal Lock" si se divide por algún seno o coseno que tenga valor 0. Como para este caso solo hace falta saber el giro del eje Y, y se obtiene de asin(-sy) solo puede valer 0 en -90 o +90 grados, lo que no se da nunca porque con esa inclinación la cámara no ve la marca. En cualquier caso, si se diera esta problema puede consultarse el siguiente enlace para resolverlo [1].
Ang y = asin(-r[2][0])
Ang z = atan(r[0][0]/r[0][1])
De estas operaciones se observa que se puede producir "Gimbal Lock" si se divide por algún seno o coseno que tenga valor 0. Como para este caso solo hace falta saber el giro del eje Y, y se obtiene de asin(-sy) solo puede valer 0 en -90 o +90 grados, lo que no se da nunca porque con esa inclinación la cámara no ve la marca. En cualquier caso, si se diera esta problema puede consultarse el siguiente enlace para resolverlo [1].
Por otro lado también comentar que si queremos la posición de la cámara respecto a la marca, se llamará a la función arUtilMatInv de artoolkit ya que artoolkit plus no incluye esta función.
Por ahora es todo.
[1] http:/www.j3d.org/matrix_faq/matrfaq_latest.html#Q37
Por ahora es todo.
[1] http:/www.j3d.org/matrix_faq/matrfaq_latest.html#Q37

1 comentario:
Buenas.
Estoy trabajando con artoolkitplus para un trabajo.
He conseguido dibujar un objeto sobre una marca correctamente. Ademas rota y se mueve correctamente. El problema esta en obtener los angulos de giro de los ejes.
He llegado a las mismas conclusiones que comentas en tu log. Obtengo la misma matriz R que tu obtienes. Pero a partir de aqui no entiendo de donde sacas:
Ang x = atan(r[2][1]/r[2][2])
Ang y = asin(-r[2][0])
Ang z = atan(r[0][0]/r[0][1])
Aun asi, sin entender el porque realizo estas operaciones y no salen bien los angulos.
Otro problema, que puede ser el que ocasione que no salgan bien los angulos puede ser que en las simplicicaciones que haces para operar las matrices (cx=Cos(x), cy=Cos(y), cz=Cos(z), stx=Sin(x), sty=Sin(y), stz=Sin(z)), no se lo que es x,y,z.
Yo he utilizado para las operaciones x como la posicion x del centro, y como la posicion y del centro, z como la posicion z del centro. Es muy probable que sea esta suposicion la que provoque el error.
A ver si me puedes ayudar. Te paso aqui una ModelViewMatrix que obtengo al detectar una marca y a ver si me puedes comentar como sacar un angulo, para ver como es y despues yo sacar el resto:
-0,93 0,37 0,02 0,00
0,33 0,86 -0,4 0,00
-0,17 -0,36 -0,92 0,00
-17,24 -30,68 233,3 1,00
Gracias de antemano.
Publicar un comentario