Prácticas

Prácticas

Práctica 1: Avatar Virtual

Uno de los usos más directos que se puede encontrar para las tecnologías de captura de movimientos es precisamente el renderizado de un avatar virtual que siga los movimientos del usuario. En esta práctica, vamos a realizar la implementación de un avatar muy, muy básico a partir de la información extraída de la captura de movimientos. Más concretamente, en esta práctica el alumno modificará un programa para renderizar por pantalla una versión muy básica de un avatar virtual que utilice figuras geométricas simples para representar los nodos o articulaciones del esqueleto generado por OpenNI

  • Para ello, al igual que en prácticas anteriores, el alumno partirá del programa localizado en ./OpenNI/Samples/NiUserTracker
  • Una vez se ha entendido el programa, el alumno creará una copia de la carpeta ../OpenNI/Samples/NiUserTracker en ../OpenNI/Samples/NiUserTracker_OCW_Avatar, y modificará el fichero Makefile de la nueva carpeta para que al compilar se cree un ejecutable con nombre Sample_NiUserTracker_OCW_Avatar en la carpeta ../OpenNI/Samples/Bin. Durante toda la práctica, sólo se modificará el contenido de ../OpenNI/Samples/NiUserTracker_OCW_Avatar.

 

El alumno deberá aplicar lo aprendido en las anteriores unidades didácticas para modificar el programa conforme a los siguientes criterios:

  • No debe mostrarse por pantalla la imagen normalmente generada por la aplicación que se está modificando.
  • Debe accederse a cada coordenada del esqueleto del usuario detectado.
  • Deberá dibujarse un cubo en la posición que corresponda a cada coordenada del esqueleto generado por OpenNI.

Dibujar un cubo

¿Cómo dibujo un cubo?

Atención

Antes de comenzar a realizar la práctica, es recomendable intentar dibujar un único cubo y visualizarlo adecuadamente. Puede ocurrir que estemos dibujando el cubo bien, pero no se nos muestre por pantalla porque la "cámara" del mundo virtual que representa nuestro punto de vista en el mundo virtual (lo que se muestra por pantalla) no esté apuntando en la dirección del cubo. Una función de GLUT que permite modificar el punto de vista de esta cámara y su posición es:

void gluLookAt(GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ,

                GLdouble centerX, GLdouble centerY , GLdouble centerZ,

                GLdouble upX, GLdouble upY, GLdouble upZ);

 

Esta función coloca la cámara en la posición (eyeX,eyeY,eyeZ), mirando hacia la posición (centerX,centerY,centerZ). El vector (upX,upY,upZ) representaría hacia donde está apuntando la parte superior de la cabeza de la cámara (normalmente, tendrá el valor (0,1,0), ya que la cámara se entenderá que está erguida).

 

También es interesante destacar que se puede dibujar un cubo de forma que cada cara se asocie a un color distinto. Para ello, bastaría con modificar TrazarCubo y llamar a la función glColor4f justo antes de dibujar cada cara. Incluso es posible hacerlo antes de dibujar cada vértice de cada cara, creando efectos más psicodélicos al mezclarse los colores de un vértice a otro.

Práctica 2: Cubo Giratorio

En esta práctica el alumno diseñará una aplicación en la que se detecten ciertos gestos periódicos, que se traducirán en el aumento o disminución de la velocidad de giro de un cubo renderizado en el mundo virtual.

Para ello, al igual que en prácticas anteriores, el alumno partirá del programa localizado en ./OpenNI/Samples/NiUserTracker.

Una vez se ha entendido el programa, el alumno creará una copia de la carpeta ../OpenNI/Samples/NiUserTracker en ../OpenNI/Samples/NiUserTracker_OCW_CuboGira, y modificará el fichero Makefile de la nueva carpeta para que al compilar se cree un ejecutable con nombre Sample_NiUserTracker_OCW_CuboGira en la carpeta ../OpenNI/Samples/Bin. Durante toda la práctica, sólo se modificará el contenido de ../OpenNI/Samples/NiUserTracker_OCW_CuboGira.

El alumno deberá aplicar lo aprendido en las anteriores unidades didácticas para modificar el programa conforme a los siguientes criterios:

  • No debe mostrarse por pantalla la imagen normalmente generada por la aplicación que se está modificando. En lugar de ello, únicamente se mostrará un cubo por pantalla, al cual se le aplicarán diferentes animaciones en función de los gestos que el usuario realice.
  • Al realizar gestos de subir y bajar con el brazo derecho, el cubo empezará a girar en un sentido, incrementando su velocidad en dicho sentido con cada gesto nuevo que se detecte de este tipo.
  • Al realizar gestos de subir y bajar con el brazo izquierdo, el cubo empezará a girar en el sentido opuesto al caso anterior, e igualmente incrementando su velocidad en dicho sentido con cada gesto nuevo que se detecte de este tipo.
  • Un gesto de subir y bajar se considerará como tal si al menos la posición de la mano correspondiente sube por encima de la posición del cuello del usuario y baja por debajo de la posición de su cadera

Hacer girar un cubo

¿Y cómo hago que el cubo gire?

Práctica 3: Nube de puntos 3D

En esta práctica , el alumno deberá implementar una aplicación que genera una "nube de puntos" en el espacio. La idea es trasladar aproximadamente el mapa de profundidad generado por OpenNI a una geometría tridimensional.

Para ello, al igual que en prácticas anteriores, el alumno partirá del programa localizado en ./OpenNI/Samples/NiUserTracker.

Una vez se ha entendido el programa, el alumno creará una copia de la carpeta ../OpenNI/Samples/NiUserTracker en ../OpenNI/Samples/NiUserTracker_OCW_Nube, y modificará el fichero Makefile de la nueva carpeta para que al compilar se cree un ejecutable con nombre Sample_NiUserTracker_OCW_Nube en la carpeta ../OpenNI/Samples/Bin. Durante toda la práctica, sólo se modificará el contenido de ../OpenNI/Samples/NiUserTracker_OCW_Nube.

El alumno deberá aplicar lo aprendido en las anteriores unidades didácticas para modificar el programa conforme a los siguientes criterios:

  • No debe mostrarse por pantalla la imagen normalmente generada por la aplicación que se está modificando. Únicamente deberá visualizarse la nube de puntos en cuestión.
  • El objetivo de esta práctica es "proyectar" el mapa de profundidad que normalmente se dibuja en el programa NiUserTracker sobre una nube de "puntos". Para representar los puntos, se pueden usar cubos o cuadrados (para dibujar un cuadrado, bastaría modificar la función TrazaCubo() para que únicamente se dibuje una cara, por ejemplo, la cara frontal).
  • El alumno deberá dibujar una serie de cubos o cuadrados de colores que aproximadamente recreen la misma imagen que se observa al ejecutar el programa el programa NiUserTracker, ayudándose para ello del mapa de profundidad y el mapa de etiquetas vistos en anteriores unidades didácticas.
  • No es necesario utilizar la generación del esqueleto en esta práctica, ni tampoco es necesario representar el esqueleto ni los mensajes de ayuda que la función NIUserTracker muestra por pantalla normalmente. Tampoco es necesario que cada píxel de la escena se represente por un cubo o cuadrado, entre otras razones porque puede resultar demasiado "pesado" a nivel de computación si el PC que se utiliza no es lo suficientemente potente.

Práctica 4: Reconocedor de gestos

En esta práctica se utilizarán la información sobre el esqueleto de la persona para distinguir una serie de gestos básicos. En concreto, para distinguir los gestos que usan los controladores de tierra para guiar a los aviones en pista.

Estos gestos se describen en un documento que puede accederse pinchando aquí. La figura siguiente muestra un resumen de dichos gestos que en principio es más que suficiente para el desarrollo de la práctica:

©AvStop Online Magazine

Como puede comprobarse, en estos gestos influye, sobre todo, la posición de las manos y su movimiento. Para ayudar en el desarrollo de la práctica, se propone seguir los siguientes pasos:

  •  Generar una nueva carpeta, ../OpenNI/Samples/NiUserTracker_OCW_Gestos, donde se copiará el contenido de ../OpenNI/Samples/NiUserTracker.
  • Modificar el fichero Makefile de la nueva carpeta para que al compilar se cree un ejecutable con nombre NiUserTracker_OCW_Gestos en la carpeta ../OpenNI/Samples/Bin. Durante toda la práctica, sólo se modificará el contenido de ../OpenNI/Samples/NiUserTracker_OCW_Gestos.
Tras estos dos pasos (semejantes a los que se han seguido en otras prácticas), se propone que el alumno siga el siguiente orden para la realización de la práctica:
  • Incluir información sobre la posición 3D de las manos en el código. Se puede hacer siguiendo el programa que se utilizó en la Unidad Didáctica B1_UD5 (Extracción del esqueleto de la persona).
  • Incluir información sobre la posición 3D de los codos, los hombros y la cabeza en el código. De nuevo, el programa desarrollado en la Unidad Didáctica B1_UD5 puede servir de guía.
  • Identificar poses estáticas a partir de:
  • La posición relativa de las manos izquierda y derecha respecto a la cabeza (por encima, por debajo, más o menos a la altura, por delante). Puede ser interesante saber medir las distancias mano-cabeza, para lo que se usará la distancia euclídea entre dos puntos 3D, que se puede calcular con la siguiente fórmula, teniendo en cuenta que OpenNI da las coordenadas 3D de los puntos en milímetros:
  • El ángulo del codo de cada brazo. Este ángulo se puede calcular como el ángulo que forman los vectores mano-codo y codo-hombro. El ángulo entre dos vectores se puede calcular a partir de la fórmula del producto escalar:
  • Con ésto ya es posible codificar un par de gestos de la figura: 
    • Stop sería un gesto con ambas manos por encima de la cabeza y los codos en ángulo de 90 grados (más o menos: aquí siempre hay que trabajar con umbrales para tener una cierta tolerancia. Una buena aproximación sería considerar ángulos entre 80 y 100 grados,
    • All Clear (OK) es un gesto en que la mano derecha se coloca por encima de la cabeza, y su codo en ángulo de 90 grados (más o menos), y la mano izquierda se coloca por debajo de la cabeza, con un ángulo aproximado de codo de 0 grados (recordad la NOTA anterior).
¡Al trabajar con ángulos, hay que recordar que un ángulo de 0 grados y un de 360 grados son equivalentes!
  • Para gestos con movimiento (la mayoría) se puede plantear su codificación como una máquina de estados, en donde un gesto es una secuencia de poses estáticas por las que el usuario va pasando ordenadamente. Por ejemplo:
    • En el gesto Emergency Stop, hay dos posiciones: la primera, ambas manos por encima de la cabeza y cerca de la cabeza. La segunda, ambas manos por encima de la cabeza y lejos de la cabeza. La distancia umbral entre cerca y lejos debe definirla el alumno.
  • Cuando un gesto sea identificado, debe mostrarse el nombre del gesto en pantalla (igual que se mostraban la cantidad de cuadrados recolectados en la práctica de la Unidad B1_UD5). Puede ser de gran ayuda mostrar las poses estáticas intermedias por las que el gesto va pasando de cara a comprender cómo está actuando el código.
En esta práctica, codificar todos los gestos adecuadamente se plantea como un reto para el alumno. Lo mínimo exigible se limita a la codificación de gestos estáticos.

Obra publicada con Licencia Creative Commons Reconocimiento 3.0