PFC SIMOCAP 10 Matrícula de Honor

9 07 2010

Pues ya presente el proyecto Simocap como Proyecto fin de carrera de Ingeniería Superior en Informática en mi Escuela, (Escuela Técnica Superior de Ingeniería Informática de la Universidad de Sevilla), y he recibido la clasificación de Sobresaliente 10 Matrícula de Honor,  además esto se une a la Mención Especial recibida en el Premio local de Sevilla del Concurso Universitario de Software Libre.

Dejo aquí los vídeos de una demostración de uso del software.

Y con esto voy a denener el desarrollo del proyecto hasta nuevo aviso.

La dirección de descarga del software y de la documentación es la siguiente:

https://forja.rediris.es/projects/cusl4-simocap/





Tutorial Instalación de Artoolkit (y ejecución) en Ubuntu

18 06 2010

Bueno hace unos días tuve que instalar de nuevo artoolkit en otra máquina con Ubuntu 10.04 y hacía tanto tiempo de la primera vez, que no me acordaba muy bien, así que para que no me pase más he escrito un pequeño manual de instrucciones / tutorial con los pasos para la instalación y la ejecución de las aplicaciones de ejemplo en Ubuntu (probado en Ubuntu 10.04).

Y como la mayoría de visitas que recibe este blog es por este motivo, pues aquí lo dejo:

Instalación Artoolkit

Paso1. Instalar los siguientes paquetes o la versión actual más parecida desde Synaptic aceptando también la instalación de todas las dependencias que nos proponga

freeglut3-dev
libgstreamer0.10-dev
libgstreamer-plugins-base0.10-dev  (quizas este no es necesario)
libxi-dev
libxmu-headers
libxmu-dev
libjpeg62-dev
libglib2.0-dev
libgtk2.0-dev

Paso2.  Descargar artoolkit, la última versión libre es esta:

ARToolKit-2.72.1.tgz

para otros sistemas operativos:

http://sourceforge.net/projects/artoolkit/files/

Paso3. Descomprimir desde un terminal en la ubicación deseada con el comando:

tar zxvf ARToolKit-2.72.1.tgz

Paso4. Ir dentro de la carpeta de artoolkit y configurar desde un terminal con el comando

./Configure

elegir opción 5 Gstreamer Media Framework y responder sí (yes) a las siguientes preguntas (no he probado con las otras opciones la verdad).

Paso5. En la misma carpeta ejecutar desde el terminal el comando make

make

(cruzar los dedos para que todo se compile bien, y ya está terminada la instalación, los ejecutables de los ejemplos estarán en la carpeta bin)

Ejecución Artoolkit

Para la opción de instalación seleccionada supongo que lo que la mayoría desconoce es que hay que darle valor a la variable de entorno ARTOOLKIT_CONFIG

Ejecución de Ejemplos con webcam

Para ejecutar ejemplos de artoolkit con video proveniente de una webcam ejecutar antes el siguiente comando en un terminal para darle valor a la variable de entorno:

export ARTOOLKIT_CONFIG="v4l2src device=/dev/video0 use-fixed-fps=false ! ffmpegcolorspace ! capsfilter caps=video/x-raw-rgb,bpp=24 ! identity name=artoolkit ! fakesink"

donde pone video0 puede que sea otro número video1 por ejemplo, depende de donde instale la webcam o cuando.

Ejecución de ejemplos con archivos de vídeo en disco

Hay que ejecutar primero el siguiente comando desde un terminal cambiando la ruta de location=/…   por nuestra.

export ARTOOLKIT_CONFIG="filesrc location=/home/alberto/Escritorio/proyectos/prueba.MOV ! decodebin ! ffmpegcolorspace ! capsfilter caps=video/x-raw-rgb,bpp=24 ! identity name=artoolkit ! fakesink"

Nos fijamos que el valor que se le da a location es la ruta del vídeo que queremos usar como entrada de vídeo, el resto mejor dejarlo como está.

Ejemplo con otra ruta:

export ARTOOLKIT_CONFIG="filesrc location=/home/nosotros/Escritorio/prueba.MOV ! decodebin ! ffmpegcolorspace ! capsfilter caps=video/x-raw-rgb,bpp=24 ! identity name=artoolkit ! fakesink"

Y listo, ahora podemos ir a la carpeta bin, o donde tengamos el ejecutable y llamarlo desde línea de comandos, siempre con ./ delante.

ejemplo:

./simpleTest





Descripción del Formato BVH

8 04 2010

En un post anterior ya hablé de los formatos de archivo para la captura de movimientos corporales.

En este quiero explicar uno en contrato el formato BVH (Biovision Hierarchical Data) de paso añado algo de documentación sobre él en la red ya que se usa mucho pero parece que a nadie le ha dado por documentarlo, supongo también que esto se debe a que existen multitud de editores de movimientos que dan como resultados este tipo de archivos pero realmente no tienes porqué enfrentare al código.

Bueno lo dicho, aquí expongo a modo de documentación lo que he descubierto sobre el formato BVH.



Esto es lo que contiene un archivo BVH:

HIERARCHY
ROOT hip
{
	OFFSET	0.00  0.00  0.00
	CHANNELS 6 Xposition Yposition Zposition Xrotation Zrotation Yrotation
	JOINT abdomen
	{
		OFFSET	0.000000 3.422050 0.000000
		CHANNELS 3 Xrotation Zrotation Yrotation
		JOINT chest
		{
			OFFSET	0.000000 8.486693 -0.684411
			CHANNELS 3 Xrotation Zrotation Yrotation
			JOINT neck
			{
				OFFSET	0.000000 10.266162 -0.273764
				CHANNELS 3 Xrotation Zrotation Yrotation
				JOINT head
				{
					OFFSET	0.000000 3.148285 0.000000
					CHANNELS 3 Xrotation Zrotation Yrotation
					End Site
					{
						OFFSET 0.000000 3.148289 0.000000
					}
				}
			}
			JOINT lCollar
			{
				OFFSET	3.422053 6.707223 -0.821293
				CHANNELS 3 Yrotation Zrotation Xrotation
				JOINT lShldr
				{
					OFFSET	3.285171 0.000000 0.000000
					CHANNELS 3 Zrotation Yrotation Xrotation
					JOINT lForeArm
					{
						OFFSET	10.129278 0.000000 0.000000
						CHANNELS 3 Yrotation Zrotation Xrotation
						JOINT lHand
						{
							OFFSET	8.486692 0.000000 0.000000
							CHANNELS 3 Zrotation Yrotation Xrotation
							End Site
							{
								OFFSET 4.106464 0.000000 0.000000
							}
						}
					}
				}
			}
			JOINT rCollar
			{
				OFFSET	-3.558935 6.707223 -0.821293
				CHANNELS 3 Yrotation Zrotation Xrotation
				JOINT rShldr
				{
					OFFSET	-3.148289 0.000000 0.000000
					CHANNELS 3 Zrotation Yrotation Xrotation
					JOINT rForeArm
					{
						OFFSET	-10.266159 0.000000 0.000000
						CHANNELS 3 Yrotation Zrotation Xrotation
						JOINT rHand
						{
							OFFSET	-8.349810 0.000000 0.000000
							CHANNELS 3 Zrotation Yrotation Xrotation
							End Site
							{
								OFFSET -4.106464 0.000000 0.000000
							}
						}
					}
				}
			}
		}
	}
	JOINT lThigh
	{
		OFFSET	5.338403 -1.642589 1.368821
		CHANNELS 3 Xrotation Zrotation Yrotation
		JOINT lShin
		{
			OFFSET	-2.053232 -20.121670 0.000000
			CHANNELS 3 Xrotation Zrotation Yrotation
			JOINT lFoot
			{
				OFFSET	0.000000 -19.300380 -1.231939
				CHANNELS 3 Xrotation Yrotation Zrotation
				End Site
				{
					OFFSET 0.000000 -2.463878 4.653993
				}
			}
		}
	}
	JOINT rThigh
	{
		OFFSET	-5.338403 -1.642589 1.368821
		CHANNELS 3 Xrotation Zrotation Yrotation
		JOINT rShin
		{
			OFFSET	2.053232 -20.121670 0.000000
			CHANNELS 3 Xrotation Zrotation Yrotation
			JOINT rFoot
			{
				OFFSET	0.000000 -19.300380 -1.231939
				CHANNELS 3 Xrotation Yrotation Zrotation
				End Site
				{
					OFFSET 0.000000 -2.463878 4.653993
				}
			}
		}
	}
}
MOTION
Frames:     1
Frame Time: 0.033333
0.000000 43.528519 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

Se pueden distinguir dos partes bien diferenciadas, HIERARCHY y MOTION.

HIERARCHY
En la primera se representa la estructura del esqueleto describiendo los huesos o partes del cuerpo en una jerarquía, de este modo por ejemplo en este ejemplo podemos ver como la raíz de todas las partes del cuerpo es la cadera, y tiene como uniones hijas al abdomen y las 2 piernas, a su vez el abdomen tiene como hijo al pecho, y así sucesivamente hasta completar las partes del cuerpo que se quieran simular.

Cada una de estos huesos o partes del cuerpo vienen caracterizadas por unos parámetros.

OFFSET indica las coordenadas x, z e y donde comienza.

CHANNELS indica el numero y nombre de las variables que pueden cambiar la posición y rotación del hueso. (Solo se indica posición en la raíz, en los demás solo se indicará la rotación.

JOINT indica los huesos hijos a los que está unido y cuyo OFFSET será su límite Nota: el valor de las variables de rotación de un hueso siempre se consideran con respecto al hueso padre.


MOTION
En la segunda parte se representa el movimiento del esqueleto.
Para ello primero se indica el numero de frames (numero de movimientos a realizar), después indicamos la velocidad de esos movimientos(Frames Time).

A partir de ahí cada línea (hasta un retorno de carro explicito “/n” no de los que ocurren con el auto-formateado para que no se salga de la pantalla) representa uno de estos frames con una serie de cifras que se corresponden con las variables declaradas en la estructura del esqueleto en cada canal en el orden en el que se han declarado. De esta manera cuanto más complicado es nuestro esqueleto más cifras habrá en cada línea de movimiento.

Ejemplo de frame (aunque aparezca formateado en varias líneas en realidad solo tiene un retorno de carro al final):

0.000000 43.528519 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 60.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

Este frame solo tiene valores distintos de 0 para un par de variables,

El valor 43.528519 se corresponde con Yposicion del elemento hip, esto se traduce en que el esqueleto tiene una posición absoluta elevada, (suponiendo que en 0 está el suelo se habrá elevado la cadera que es el origen de todas las demás partes para que al estar de pie el modelo virtual los pies estén en posición 0).

Y el valor 60.00000 se corresponde con Xrotation del elemento neck (cuello), lo cual significa que el modelo está mirando hacia arriba.





Movimiento de la cabeza

22 03 2010

SE MUEVE!!! SE MUEVE!!!

Casi grito eso cuando conseguí capturar el movimiento de la cabeza en un archivo bvh y después reproducirlo en un modelo virtual.

Después del  vídeo explico un poco el funcionamiento.

El de la izquierda soy yo, otra vez haciendo un poco el gamba con ese bonito sombrero que me he fabricado con una caja de zapatos al cual le he colocado diversas marcas de seguimiento.

Y el de la izquierda es un modelo virtual (tristemente para mí más guapo que yo)  que nos proporciona q-avimator para visualizar archivos con formato “bvh” en este caso el archivo “bvh” que reproduce es el que simocap ha generado automáticamente a partir del video de la izquierda.

Va un poco lento pero es porque al hacer la composición de los dos vídeos mi portátil no daba para más. Los vídeos por separado se ven de forma fluida, también están en youtube por si alguien tiene curiosidad.

Lo que hago es medir los ángulos que hay entre las marcas de mi sombrero y la marca del pecho que uso como marca base.

El motivo de que en la cabeza tenga varias marcas es que al girar es posible que se deje de ver la marca frontal, de este modo las marcas laterales son las que dan la posición.  Así cuando solo se visualiza una marca uso esta pero si se visualizan dos hago la media.

Una vez tengo el angulo de la cabeza lo voy trasladando al archivo de formato “bvh” para guardarlo.

Además una vez este proceso ha terminado para todo el vídeo de captura,  recorro el archivo modificando los ángulos para suavizar los movimientos ya que debido a pequeños fallos en la captura se producen movimientos bruscos no reales.

Este archivo con formato “bvh” se puede visualizar en múltiples programas como blender, pose , o incluso en Second Life, yo he usado QAVIMATOR por ser código de fuentes abiertas, y consumir pocos recursos .

Mi siguiente paso es capturar el movimiento de los brazos. Me las tengo que ingeniar para colocarme las marcas sin que se me caigan y tal :P .

Saludos.





Obteniendo los ángulos de Euler

28 02 2010

Solución para salvar el problema del Gimbal Lock al obtener los ángulos de Euler a partir de la matriz que se usa en ArToolkit.

Para obtener los ángulos de euler a partir de la matriz de rotación he programado el siguiente código:


int getAngulos(double rot[3][3],  double *rfXAng, double *rfYAng, double *rfZAng) {

// Matriz de Rotacion

// +-           -+   +-                                      -+

// | r00 r01 r02 |   |  cy*cz  cz*sx*sy-cx*sz  cx*cz*sy+sx*sz |

// | r10 r11 r12 | = |  cy*sz  cx*cz+sx*sy*sz -cz*sx+cx*sy*sz |

// | r20 r21 r22 |   | -sy     cy*sx           cx*cy          |

// +-           -+   +-                                      -+

// gimbalLock == 0 , no se produce gimbal Lock

// gimbalLock == 1 , se ha producido gimbal Lock por y angulo = pi/2

// gimbalLock == 2 , se ha producido gimbal Lock por y angulo = -pi/2

int gimbalLock = 0;

if (rot[2][0] < 0.995) {

if (rot[2][0] > -0.995) {

// y_angulo = asin(-r20)

// z_angulo = atan2(r10,r00)

// x_angulo = atan2(r21,r22)

*rfYAng = asin(-rot[2][0]);

*rfZAng = atan2(rot[1][0],rot[0][0]);

*rfXAng = atan2(rot[2][1],rot[2][2]);

}

else {

// y_angulo = +pi/2

// x_angulo + z_angulo = atan2(r01,r02)

// NOTA.  La solución no es unica.  Tomamos x_angulo = 0.

*rfYAng = PI/2;

*rfZAng = -atan2(rot[0][1],rot[0][2]);

*rfXAng = 0.0;

gimbalLock = 1;

}

}

else {

// y_angulo = -pi/2

// x_angulo + z_angulo = atan2(-r01,-r02)

// NOTA.  La solución no es unica.  Tomamos x_angulo = 0.

*rfYAng = -PI/2;

*rfZAng = atan2(-rot[0][1],-rot[0][2]);

*rfXAng = 0.0;

gimbalLock = 2;

}

printf(“Radianes: %3.1f %3.1f %3.1f \n”,*rfXAng,*rfYAng,*rfZAng);

printf(“Centigrados: %3.1f %3.1f %3.1f \n”,(*rfXAng*180)/PI, (*rfYAng*180)/PI, (*rfZAng*180)/PI);

return gimbalLock;

}
Esta función nos indica los ángulos de Euler y además devuelve un valor 1 u 2 cuando se produce Gimbal Lock por angulo con respecto al eje “Y” de 90 o -90 grados respectivamente, de este modo estaré advertido de la situación en un futuro.

En breve voy a empezar a construir mis propios archivos bvh, espero no tener demasiados problemas.





Interpretación de la matriz de coordenadas

19 02 2010

Ahora que tengo la matriz de coordenadas de una marca con respecto a otra lo que necesito es obtener los ángulos de rotación con respecto a cada uno de los ejes. El problema es que en la escasa documentación que ofrece Artoolkit lo que dice es que la última columna de la matriz indica la distancia en los distintos ejes X, Y, y Z. Y efectivamente al acercar o alejar las marcas se puede apreciar.

Pero no dice nada acerca de las otras 3 columnas que después descubrí que indican la rotación que yo buscaba.

Matriz de rotación

r [0,0] r [0,1] r [0,2]

r [1,0] r [1,1] r [1,2]

r [2,0] r [2,1] r [2,2]

Así que empiezo a hacer pruebas primero coloco una marca base y debajo de ella coloco otra. Como se puede apreciar están sobre la mesa sin giro alguno

Sin figura 3D

Con figura 3D

La tetera roja está colocada en la marca base.

Y la matriz resultado es la siguiente:

[R] =
0,9988 0,0060 -0,0496 0,1213
-0,0064 0,9999 -0,0091 -130,7769
0,0495 0,0094 0,9987 5,0256
Cuya matriz de rotación se parece bastante a:

1 0 0
0 1 0
0 0 1

Efectivamente la última columna cumple su cometido de indicar la distancia, ya que para dx y dz su valor es cercano a 0 pero para dy nos da un valor d -130 es decir la marca secundaria está por debajo de la marca base. Y el resto de la matriz (la matriz de rotación) se parece a la matriz identidad.

Después hice pruebas con distintas marcas colocándolas en ángulos reconocibles de 90 grados con respecto a una marca base (la de la tetera rosa) que será respecto a la que calcule las matrices de coordenadas.

Como se puede observar cada una de las marcas 1, 2, y 3 están giradas 90 grados en un sentido u otro con respecto a uno delos ejes de la marca 0.

La marca 1 está girada con respecto al eje X.

La marca 2 está girada con respecto al eje Y.

La marca 3 está girada con respecto al eje Z.

Y las matrices de coordenadas respecto a la marca base 0 (tetera rosa) obtenidas para cada un una de las otras marcas son las siguientes:

Matriz de la marca 1.

[R] =
0,9984 0,0036 0,0557 -3,8267
0,0556 -0,1288 -0,990 53,1803
0,0036 0,9917 -0,1288 67,2298
Cuya matriz de rotación se parece bastante a:

1 0 0
0 0 -1
0 1 0

Matriz de la marca 2.

[R] =
0,0168 -0,0193 -0,9997 74,2620
-0,0366 0,9991 -0,0199 10,7033
0,9992 0,0370 0,0161 57,7545
Cuya matriz de rotación se parece bastante a:

0 0 -1
0 1 0
1 0 0

Matriz de la marca 3.

[R] =
-0,0356 0,9993 -0,0067 8,1143
-0,9970 -0,0351 0,0685 -115,7258
0,0682 0,0092 0,9976 -11,3858
Cuya matriz de rotación se parece bastante a:

0 1 0
-1 0 0
0 0 1

Estos valores tan poco aleatorios tienen su explicación, la cual encontré en los apuntes de la asignatura SIO, Síntesis de imágenes por Ordenador (José Cortés Parejo).

Seno de 90º es 1 y de -90º es -1 y el coseno 90 es 0. Así que lo que nos dicen las matrices es que la marca 1 está girada 90 grados alrededor del eje X, y las marcas 2 y 3 -90 grados alrededor de los ejes Y y Z respectivamente.

Así que la conclusión es que la matriz de rotación general es la multiplicación de las matrices de rotación con respecto a cada eje. Si consideramos α, β y γ los ángulos de giro alrededor de los ejes X, Y y Z respectivamente tenemos que multiplicando las matrices de rotación obtenemos lo siguiente.

[R] = Rotación en eje Z

cos γ -sen β 0
sen γ cos γ 0
0 0 1
* ( Rotación en eje Y

cos β 0 senβ
0 1 0
-sen β 0 cos β
* Rotación en eje X

1 0 0
0 cos α -senα
0 senα cos α
)

[R] =

cos β * cos γ sen α * sen β * cos γ – cos α * sen γ cos α * sen β * cos γ + sen α * sen γ
cos β * sen γ sen α * sen β * sen γ + cos α * cos γ cos α * sen β * sen γ – sen α * cos γ
-sen β sen α * cos β cos α * cos β

Se corresponde con:

Matriz de rotación

r [0,0] r [0,1] r [0,2]

r [1,0] r [1,1] r [1,2]

r [2,0] r [2,1] r [2,2]

Esta sería entonces la matriz de rotación compacta para los 3 ejes que obtenemos como resultado de la función arGetTransMat junto con el último vector que ya comentamos que era el de la distancia.

Para obtener entonces los ángulos α , β y γ simplemente tenemos que despejar operando sobre los componentes apropiados de la matriz.

(sen α * cos β)/(cos α * cos β) = sen α /cos α = tan α → α = atan (tan α)

Sustituyendo por los componentes de la matriz : α = atan ( r [2,1] / r [2,2])

β = asen -(-sen β) = asen -(r [2,0])

(cos β * sen γ)/(cos β * cos γ) = sen γ /cos γ = tan γ → γ = atan (tan γ)

Sustituyendo por los componentes de la matriz : γ = atan ( r [1,0] / r [0,0])

Estos ángulos estarán expresados en radianes. Para expresarlos en grados sistema más reconocible por nosotros solo tenemos que multiplicar por 180 y dividir por Pi.

El código podría ser algo así:

#define PI 3.14159265358979323846

Ángulo de giro en X → α = (atan (matriz[2][1] / matriz[2][2]) * 180) / PI;

Ángulo de giro en Y → β = (asin (-matriz[2][0]) * 180) / PI;

Ángulo de giro en Z → γ = (atan (matriz[1][0] / matriz[0][0]) * 180) / PI;


Que bonito sería el mundo si esto fuera tan fácil, pero no lo es, y este código después de probarlo un poco se aprecia un error en la estimación de los ángulos con respecto a X y Z esto es debido a que produce Gimball lock. Este error se produce cuando hay giros de 90 con respecto al eje Y (cos 90º = 0) segundo en la multiplicación de matrices y es un error intrínseco a este tipo de uso de los ángulos de euler.

Estoy estudiando distintas opciones para solucionarlo, parece que una buena opción es el uso de quaternion para la representación de la rotación, aunque después para el paso a archivos de movimiento de esqueleto formato bvh necesitaría los ángulos de euler, lo que supondría una nueva conversión.

En principio voy a seguir estudiando opciones, y empezando a tocar archivos bvh, para su mejor compresión de este modo espero encontrar la solución más adecuada al desarrollo de la siguiente fase, la escritura automática de un archivo bvh a partir de las coordenadas obtenidas por las marcas.

Saludos.

0,9999




Coordenadas de una marca respecto a otra

12 02 2010

En cualquier caso para mi proyecto principalmente necesito la posición de las marcas con respecto a otras marcas, las coordenadas con respecto a la cámara solo me servirá para la marca base, que determinará el movimiento de traslación del esqueleto 3d. El resto de marcas me servirán para medir sus ángulos relativos y determinar los movimientos de rotación de las articulaciones.

Para determinar las coordenadas de unas marcas con respecto a otras necesitamos la matriz de transformación entre ellas. Para ello una vez tenemos las matrices de coordenadas con respecto al sistema de referencia de la cámara de las dos marcas implicadas realizamos las siguientes operaciones:

Pasándole a la función arUtilMatInv la matriz de coordenadas de la marca base con respecto a la cámara obtendremos la matriz de coordenadas de la cámara con respecto a la marca.

Esta función lo que ha hecho es invertir los sistemas de referencias. (Todo esto tiene una base teórica que explicaré en la memoria del proyecto).

Una vez tengo esta matriz la multiplicamos por la matriz de la marca de la cual queríamos obtener sus coordenadas respecto a la primera. Podemos usar la función arUtilMatMul.

El código podría ser algo así:

arUtilMatInv(m1C, m1Inv);

arUtilMatMul(m1Inv, m2C, m2M);

- m1C y m2C son las matrices de coordenadas de las marcas con respecto a la cámara

- m1Inv es la matriz de coordenadas de la cámara respecto a la marca 1

- m2M es la matriz de coordenadas de la marca 2 con respecto a la marca 1.

El siguiente post será un mega post donde explico como interpretar la matriz de coordenadas.





Sistemas de coordenadas

9 02 2010

A continuación pongo el enlace a un vídeo que muestra un boceto del sistema de marcas que pretendo usar para capturar los movimientos del cuerpo. He puesto figuras virtuales sobre las marcas para hacer ver que el seguimiento de las marcas está prácticamente resuelto.

(Sí, ese soy yo haciendo un poco el gamba, todo sea por la ciencia).

(http://www.youtube.com/watch?v=1dELJbOOixQ)

Como han podido ver lo que hago es colocar marcas en las distintas extremidades, cabeza, y torso de modo que pueda hacer seguimiento (tracking) de las marcas.

Para este caso de cinemática inversa saber las coordenadas “x” “y” en la pantalla de las marcas no es suficiente para capturar un movimiento 3D.

Necesitamos un sistema de referencia en 3 dimensiones y obtener las coordenadas de la marca en ese sistema.

De este modo a posteriori podremos medir la posición de las extremidades o cabeza con respecto la posición del torso, el cual nos dará las coordenadas de traslación del esqueleto 3D.

Para que no dependan las mediciones de la longitud de las extremidades lo que se debe medir es el angulo con respecto a la marca base (la del torso) para cada uno de los ejes del sistema de referencia situado en esta marca base.

Por eso las marcas de las cuales se obtienen las coordenadas son especiales. Tienen una forma cuadrada con unas medidas proporcionales rígidas y un dibujo en el interior. De este modo gracias a funciones de la librería libre ArToolkit (arDetectMarker) conseguimos capturar la posición de los vértices, aristas de la cuadricula negra y el dibujo interior. Esta información la guarda en una estructura de tipo ARMarkerInfo (en realidad primero ARMarkerInfo2 y esta es tratada para convertirla en ARMarkerInfo) (http://artoolkit.sourceforge.net/apidoc/structARMarkerInfo.html )

De este modo al saber que la marca debe ser cuadrada, si en pantalla no se visualiza cuadrada y sus datos guardados en la estructura así lo reflejan será debido a la perspectiva en la que se está visualizando. Así que tratando dicha estructura de datos mediante la función arGetTransMat obtenemos la matriz de transformación entre el sistema de referencia de la marca y el de la cámara, es decir la posición y orientación relativa de la marca con respecto a sistema de referencia de la cámara. Esta matriz es una matriz 3 x 4 que explicaremos a más adelante.

Dibujos de sistemas de referencia de la marca y de la camara .

En el siguiente post explicaré como obtener las coordenadas de unas marcas con respecto a otras.





Compilando mi propio código ArToolkit

27 01 2010

Por fin después de un par de meses de investigación intensa sobre como desarrollar mi proyecto empiezo a ver en acción mi propio código.

Me refiero a codigo usando  las librerías de  ArToolkit , y aunque empecé con pequeñas modificaciones de los casos de ejemplo la cosa no era tan obvia como parecía.

Lo primero que me apareció fue un FALLO DE SEGMENTANCION y me lo decía así, literal. El error parecía que venía desde la fase de linkado ya que el codigo.o parecía normal.  Solución vino al configurar de nuevo todo el artoolkit como se hace al instalarlo, y el problema supongo que viene de que hace tanto tiempo que instalé ArToolkit en mi máquina, que habré cambiado librerías de las que dependía desde entonces, por lo cual al construir nuevos ejecutables con la configuración antigua no encontraba las librerias apropiadas. (Solución: reinstalar ArToolkit con configuración nueva)

Una vez solucinado esto pues estoy tocando código y archivos auxiliares (muchos) para que me detecte en una misma imagen varias marcas y las distinga dandome las coordenadas de todas ellas (las cuales trataré a posteriori).

Archivos auxiliares:

- por cada patrón que queramos detectar necesitamos sus características morfologicas recogidas en un archivo.

- necesitamos otro archivo en el que se hagan referencia al numero de patrones y ruta de los archivo que lo caracterizan.

- necesitamos el código que lee este último archivo, un parser que da la información de estos al codigo principal.

- también necesitamos los archivos donde guardamos los módelos 3d a superponer en la imagen (menos importante en mi caso actual).

- finalmente el código principal que hace uso de los anteriores y de la librería de artoolkit para encontrar e identificar las marcas y superponerlas con imagenes 3d

Bueno y nada más , la buena noticia es que sigo aquí luchando por el proyecto y que intentaré escribir más a menudo.

Saludoss

pd: en primicia decir que para el proximo post espero poner un video en youtube, para intentar que se entienda mi proyecto en imagenes.





Motion and gesture file formats

26 12 2009

Para la traslación de movimientos a un modelo virtual hay que pasarle la información de esos movimientos, para ello existen una serie de formatos de archivo que representan el movimiento y los gestos.

En el siguiente enlace se describe un poco cada uno de esos formatos.
http://en.wikipedia.org/wiki/List_of_motion_and_gesture_file_formats

La mayoría del software de animación 3d puede leer e interpretar varios de estos formatos.

De este modo un solo archivo se pueden usar en varias plataformas y con multitud de modelos 3D.
Por ejemplo para animar modelos en blender, o incluso en second life.

Mi proyecto por lo tanto a evolucionado a la captura de movientos en uno o varios de estos formatos,
posteriormente se podría conectar a un software de visualización de movimientos con el de creación de estos archivos para simultanear la captura de movimientos con la representación de estos en el modelo 3D.

En principio he elegido .bvh (Biovision Hierarchical Data) como formato para la captura de movimiento por ser uno de los más populares. Aunque la falta de documentación real sobre su funcionamiento está dificultandome su codificación. Así que no descarto otros formatos, ya que existe software de traducción entre algunos formatos y otros.

Siguientes pasos:
- Instalar editor y visualizador de formato .bvh para su estudio
- Desarrollar código que transforme las coordenadas obtenidas con ARtoolKit a coordenadas de movimiento en .BVH








Seguir

Get every new post delivered to your Inbox.