• No se han encontrado resultados

Diseño e implementación de aplicaciones interactivas para exposiciones y paseos

N/A
N/A
Protected

Academic year: 2020

Share "Diseño e implementación de aplicaciones interactivas para exposiciones y paseos"

Copied!
89
0
0

Texto completo

(1)

UNIVERSIDAD NACIONAL DEL CENTRO DE LA PROVINCIA DE BUENOS AIRES

Diseño e implementación

de aplicaciones interactivas

para exposiciones y paseos

Proyecto de tesis de grado de la carrera Ingeniería en Sistemas

Alumna: Solange Marquez Figueroa

[email protected]

Director: Dr. Cristian García Bauza

(2)

1

Tabla de contenido

Tabla de contenido ... 1

Índice de figuras ... 2

Índice de diagramas... 4

Índice de code snippets ... 5

Agradecimientos ... 6

Resumen... 7

Capítulo 1 Introducción ... 8

1.1 Motivación ... 9

1.2 Solución propuesta ... 9

1.3 Organización del informe ... 10

Capítulo 2 Interactividad ... 12

2.1 Evolución de la Interfaz de usuario ... 12

2.1.1 Kinect... 15

2.2 Interactividad en paseos y museos ... 19

2.3 Tecnologías utilizadas ... 24

Capítulo 3 Diseño e Implementación ... 25

3.1 Arquitectura propuesta ... 25

3.1.1 Controlador... 25

3.1.2 Modelo ... 35

3.1.3 Vista... 38

3.2 Diseño de cada aplicación ... 41

3.2.1 Reproductor de video ... 41

3.2.1.1 Reproducción normal y hacia atrás ... 43

3.2.1.1 Reproducción cámara lenta y acelerada ... 49

3.2.1.3 Unificación de estados de reproducción ... 50

3.2.2 Hinchada ... 55

3.2.2.1 Reproducción de un sonido ... 57

3.2.2.2 Reproducción múltiple ... 58

3.2.2.3 Reproducción dinámica ... 61

3.2.2.4 Carga de sonidos ... 64

3.2.2.5 Interfaz gráfica ... 64

3.2.3 Descubrir la imagen ... 69

3.2.3.1 Descubrimiento sin memoria... 70

(3)

2

3.2.3.3 Recubrimiento de la imagen ... 74

Capítulo 4 Pruebas ... 76

4.1 Contexto ... 76

4.2 Aplicaciones ... 77

4.2.1 Reproductor de video ... 77

4.2.2 Hinchada ... 79

4.2.3 Descubrir la imagen ... 80

Capítulo 5 Conclusiones ... 83

5.1 Resultados obtenidos ... 83

5.2 Trabajos futuros ... 84

Referencias ... 86

Índice de figuras

Figura 2.1 - Evolución de las interfaces de usuario. ... 12

Figura 2.2 - Interfaces de usuario (CLI, GUI y NUI respectivamente) ... 13

Figura 2.3 - Dispositivo WiiMote ... 14

Figura 2.4 - Dispositivo Leap Motion ... 14

Figura 2.5 - Dispositivo Kinect ... 15

Figura 2.6 - Componentes del dispositivo Kinect ... 15

Figura 2.7 - Rango de inclinación ... 16

Figura 2.8 - Arreglo de micrófonos del dispositivo Kinect marcados en violeta. ... 17

Figura 2.9 - Frames de profundidad. ... 17

Figura 2.10 - Frames de esqueletos. ... 18

Figura 2.11 - Veinte articulaciones rastreadas en un esqueleto. ... 18

Figura 2.12 - Interacción en el Museo de Louvre con el uso de Nintendo 3DS y códigos QR. . 20 Figura 2.13 - Juego en Museon con la utilización de PuppyIR. ... 20

Figura 2.14 - Live Projection Mapping - EVA 2013 ... 21

Figura 2.15 - Pisos interactivos en eventos. ... 21

Figura 2.16 - „Play Work Build‟ en el National Building Museum. ... 22

Figura 2.17 - „Strike a pose‟ en Cleveland Museum of Art. ... 22

Figura 2.18 - Juego interactivo relacionado al Básquet en Chicago Sports Museum. ... 23

Figura 2.19 - Avatares en Sedena. ... 23

Figura 3.1 - Interacción del dispositivo Kinect con la aplicación a través del Kinect SDK ... 26

Figura 3.2 - Secuencia de llamados para la inicialización ... 30

(4)

3

Figura 3.4 - Secuencia de llamados para la actualización del modelo. ... 31

Figura 3.5 - Comunicación necesaria entre el controlador y gestor de Kinect... 31

Figura 3.6 - Transformación de los datos por el método getTotalSkeletons. ... 32

Figura 3.7 - Diferentes estados de rastreo: PositionOnly (izquierda) y Tracked (derecha)... 32

Figura 3.8 - Transformación de los datos por el método isSkeletonAvailable. ... 33

Figura 3.9 - Transformación de los datos por el método getFirstSkeletonPosition. ... 33

Figura 3.10 - Espacio del esqueleto (izquierda) comparado con los valores de profundidad (derecha). ... 33

Figura 3.11 - Transformación de los datos por el método getSkeletonPositions. ... 34

Figura 3.12 - Transformación de los datos por el método getPlayersId. ... 34

Figura 3.13 - Transformación de los datos por el método isPlayerOnPixel. ... 34

Figura 3.14 - Comunicación entre los componentes del sistema. ... 36

Figura 3.15 - Posibles usos de los datos por el modelo ... 37

Figura 3.16 - Comunicación necesaria entre la vista y el modelo. ... 38

Figura 3.17 - Secuencia de llamados para la inicialización ... 39

Figura 3.18 - Secuencia de llamados para la actualización de la vista. ... 39

Figura 3.19 - Secuencia de llamados para terminar la aplicación. ... 40

Figura 3.20 - Idea básica sobre el funcionamiento del Reproductor de Video ... 42

Figura 3.21 - Acción de los movimientos ... 42

Figura 3.22 - Etapa 0 - Modos de reproducción de video de normal a hacia atrás. ... 43

Figura 3.23 - Modo de reproducción normal. ... 44

Figura 3.24 - Flujo de actividad para la reproducción del video con control de movimiento. .... 47

Figura 3.25 - Modo de reproducción hacia atrás ... 48

Figura 3.26 - Etapa 1 - Modos de reproducción de video. ... 49

Figura 3.27 - Modo de reproducción acelerado. ... 50

Figura 3.28 - Intensidad de sonidos de acuerdo a la cantidad de personas y sus movimientos. ... 56

Figura 3.29 - Parte visual de la aplicación Hinchada. ... 56

Figura 3.30 - Reproducción sin fin de un audio. ... 57

Figura 3.31 - Reproducción sin fin de múltiples audios. ... 58

Figura 3.32 - Secuencia de llamados para gestionar audios. ... 60

Figura 3.33 - Representación de sonidos reproducidos en verde, y no reproducidos en rojo. Variación en crecimiento de sonidos a reproducir... 63

Figura 3.34 - Representación de sonidos reproducidos en verde, y no reproducidos en rojo. Variación en disminución de sonidos a reproducir. ... 63

(5)

4

Figura 3.36 - Establecimiento de colores con respecto a los identificadores de los jugadores. 67

Figura 3.37 - Idea básica sobre el funcionamiento de „Descubrir la imagen‟ ... 69

Figura 3.38 - Establecimiento de transparencias con respecto a la existencia de los jugadores. ... 73

Figura 3.39 - Establecimiento de niveles transparencias con respecto a la existencia de los jugadores. ... 74

Figura 4.1 - Contexto de las pruebas realizadas. ... 76

Figura 4.2 - Prueba del reproductor del video con una sola persona moviéndose hacia la derecha. ... 77

Figura 4.3 - Prueba del reproductor del video con varias personas en fila hacia la izquierda. . 78 Figura 4.4 - Pruebas realizadas sobre la „Hinchada‟ con todas las personas a la vez. ... 79

Figura 4.5 - Dos personas detectadas como una sola cuando sus esqueletos se tocan. ... 80

Figura 4.6 - Proceso inicial de „Descubrir la imagen‟ con una sola persona. ... 81

Figura 4.7 - Descubriendo la imagen con muchas personas. ... 81

Figura 4.8 - Personas jugando con sus poses y eligiendo qué partes de la imagen descubrir. 82

Índice de diagramas

Diagrama 3.1 - Clase KinectDevice en la etapa de inicialización ... 26

Diagrama 3.2 - Clase KinectDevice luego de la etapa de comunicación con el dispositivo físico. ... 29

Diagrama 3.3 - Estructura de los controladores. ... 35

Diagrama 3.4 - Interfaz IModel con dos modelos de ejemplo. ... 36

Diagrama 3.5 - Incorporación de la vista al controlador y modelo. ... 40

Diagrama 3.6 - Incorporación del video a la vista ... 44

Diagrama 3.7 - Clase VideoModel - Incorporación de atributos y métodos. ... 45

Diagrama 3.8 - Comunicación del controlador con el Singleton Configuration. ... 46

Diagrama 3.9 - Incorporación de nuevos atributos a Configuration y nueva comunicación con la vista. ... 49

Diagrama 3.10 - Etapa 2 - Interacción entre los modos de reproducción. ... 51

Diagrama 3.11 - Diagrama de clases de la aplicación del reproductor de video. ... 55

Diagrama 3.12 - Relación entre PlayersModel y AudioManager. ... 59

Diagrama 3.13 - Clase AudioManager incorporando atributos específicos a la biblioteca FMOD ... 59

Diagrama 3.14 - Clase PlayersModel que mantiene el último contador con el que fue actualizado. ... 63

Diagrama 3.15 - Clase PlayersModel - Incorporación de atributos y métodos. ... 66

(6)

5

Diagrama 3.17 - Clase DiscoveryModel con sus atributos iniciales. ... 71

Diagrama 3.18 - Clase ColorManager actualizado para retornar color sin controlar su uso. .... 72

Índice de code snippets

Code snippet 3.1 - Incorporación de métodos para atrapar los eventos de flujos de datos. ...27

Code snippet 3.2 - Captura de evento de nuevo frame de esqueletos. ...28

Code snippet 3.3 - Captura de evento de nuevo frame de profundidad. ...28

Code snippet 3.4 - Interfaz IController ...29

Code snippet 3.5 - Métodos de VideoController load y unload. ...43

Code snippet 3.6 - Código correspondiente al método update de VideoController. ...46

Code snippet 3.7 - Cuerpo del método draw de la vista. ...47

Code snippet 3.8 - Implementación de update como una máquina de estados. ...51

Code snippet 3.9 - Implementación del método updateActualFrame() utilizado por update(). ...52

Code snippet 3.10 - Método updateState(). ...53

Code snippet 3.11 - Versión final del archivo configuration.xml ...54

Code snippet 3.12 - Cuerpo del método play utilizando la biblioteca FMOD. ...61

Code snippet 3.13 - Cuerpo del método stop utilizando la biblioteca FMOD. ...61

Code snippet 3.14 - Cuerpo del método update de PlayersController junto al transformador privado getAudioCounter. ...62

Code snippet 3.15 - Ruta de los archivos de audio dentro de Audios.xml ...64

Code snippet 3.16 - Porción del cuerpo del método load de la vista relacionado a la reproducción de video de fondo. ...65

Code snippet 3.17 - Cuerpo del método draw al dibujar siluetas sobre el video. ...65

Code snippet 3.18 - Cuerpo del método load del controlador. ...68

Code snippet 3.19 - Cuerpo del método update del controlador actualizado. ...68

Code snippet 3.20 - Cuerpo del método draw de la vista al dibujar textura sobre imagen de fondo. ...70

Code snippet 3.21 - Cuerpo método update del modelo. ...71

Code snippet 3.22 - Cuerpo del método load del controlador. ...72

(7)

6

Agradecimientos

A mis papás principalmente, por apoyarme cada día a lo largo de toda mi

carrera incondicionalmente. Por darme todas las posibilidades de llegar a este

punto, y aguantarme en esos días más complicados.

A mi hermanita Antonia, por levantarme el ánimo y darme una sonrisa cada

minuto compartido.

Al resto de mi familia, abuelos, tías y primos, por preocuparse y preguntar

siempre con buena onda.

A Giuli, Marian, Franco, Santi, Jorge, y amigos de la facultad, todos, que se

bancaron mis explicaciones de la tesis, y gracias a ellos realicé las pruebas

(8)

7

Resumen

La aparición de nueva tecnología capaz de reconocer los movimientos del cuerpo,

revolucionó las interfaces de usuario. Se encuentra en pleno crecimiento la creación

de aplicaciones interactivas que explotan estas tecnologías para ser usadas, luego, en

diversos ambientes como la medicina, el deporte y exposiciones, entre otros.

Si bien existen herramientas que facilitan el acceso a los datos brindados por los

dispositivos, no se logra simplificar su uso. Para la creación de aplicaciones es

necesario tener un conocimiento previo para lograr la manipulación de los datos, y

luego realizar acciones que respondan a los mismos.

En este trabajo se presenta una plataforma para facilitar la creación de diversas

aplicaciones interactivas que responden a movimientos del cuerpo. El desarrollo se

basó particularmente en el dispositivo Kinect. Esto permite que una persona con

conocimiento limitado en lo que respecta a la detección de los cuerpos, pueda crear su

propia aplicación.

Para la creación de esta plataforma, se investigaron diferentes paseos turísticos

alrededor del mundo que incorporan interactividad. Se consideraron algunas

posibilidades para luego desarrollarlas en la forma de tres aplicaciones interactivas

relacionadas al tenis. El interés demostrado hacia este deporte y en focalizar parte de

la interacción en él, se basó en la impronta que tiene esta disciplina en la ciudad de

Tandil, cuna de tenistas, y la posibilidad de brindar soporte virtual en la posible

creación de un museo interactivo. El desarrollo finalizó con las pruebas

(9)

8

Capítulo

1

Capítulo 1

Introducción

El avance tecnológico en estos últimos años, hizo que la interacción entre el humano y

cualquier dispositivo sea mucho más intuitiva. Las pantallas táctiles hicieron posible

este acercamiento, eliminando la necesidad de un teclado y mouse, haciendo posible

la dominación de un dispositivo sólo con el tacto. Pero eso no es todo, la incorporación

de reconocimiento de movimientos del cuerpo, revolucionó la manera de interactuar

con una máquina.

Wii Remote[1], Leap Motion[2] y Kinect[3] son una serie de controladores de juegos y

entretenimiento capaces de reconocer los movimientos del cuerpo, para luego realizar

acciones con su análisis. El dispositivo Kinect se destaca por la utilización de

diferentes sensores para la detección completa del cuerpo humano. Fue desarrollado

por Microsoft para la videoconsola Xbox 360 y es capaz de reconocer gestos,

comandos de voz, objetos e imágenes.

La aparición en el mercado de estas innovaciones provocó una revolución en la

creación de aplicaciones altamente interactivas. Se pueden apreciar en diferentes

disciplinas, por ejemplo en la medicina[4], con el uso del dispositivo Kinect, para el

desarrollo de habilidades en personas con necesidades especiales derivadas de la

discapacidad así como también en diferentes tipos de rehabilitación; en campo del

deporte[5] hay sistemas para mejorar distintas técnicas de juego; y en el

entretenimiento[6], se puede ver la utilización de Video Mapping[7] en diversos eventos

como recitales y desfiles.

Más aún, su alcance no termina ahí: la interactividad se puede ver en crecimiento en

muchos aspectos de la vida cotidiana, abriendo una cantidad infinita de posibilidades

(10)

9

1.1 Motivación

Si bien existen varias herramientas[8], para el desarrollo de aplicaciones interactivas,

como el SDK para Kinect, se necesita de un conocimiento previo para la manipulación

de los datos y las diferentes acciones que se quieran realizar. Así, se presentó el

desafío de desarrollar una serie de aplicaciones que utilicen el dispositivo Kinect y

manipulen los datos de diversas maneras probándolo en un escenario específico.

Hoy en día existe en el mundo un crecimiento de museos interactivos. Se llaman así a

aquellos museos que rompen la barrera del „No tocar‟ y en donde lo prohibido es

quedarse quieto. Con el objetivo de transformar un simple paseo por el museo, en un

paso más allá, con rasgos aún más interesantes y atrapantes. De esta forma un

recorrido silencioso y cauteloso puede transformarse en una experiencia divertida e

innovadora.

Con la incorporación de nuevas tecnologías, los museos permiten aprender jugando.

La unión del arte y la tecnología abre un gran camino de posibilidades. La

interactividad se lleva a cabo a través de dispositivos como los celulares y tabletas,

como así también el Kinect previamente mencionado.

En la ciudad de Tandil, Buenos Aires, se encuentra el proyecto de inaugurar un museo

de tenis. Pero este museo no pretende ser uno más: será el primer museo interactivo

de la ciudad, en donde las personas que lo visiten puedan participar de diferentes

actividades divertidas y atrapantes, donde adultos y niños puedan disfrutarlo de una

manera diferente. Esto generaría un encanto superior a la ciudad, atrayendo así a una

mayor cantidad de turistas.

La principal motivación en desarrollar una serie de aplicaciones que puedan ser

utilizadas en este museo, es la de evaluar qué tan reutilizables pueden ser, para qué

público son adaptables y la facilidad de que en un futuro una persona ajena al

proyecto pueda crear una aplicación.

1.2 Solución propuesta

El objetivo de este trabajo, es el de incorporar la parte interactiva a dicho museo de

tenis a través de la implementación de una serie de aplicaciones que utilizan Kinect.

Estas aplicaciones tendrán su foco en el museo, pero su alcance no será limitado. Se

(11)

10

Se pretende propiciar un ambiente en el que los adultos puedan divertirse como niños,

y que los niños disfruten del recorrido por un museo sin las limitaciones que

usualmente se deben tener. Considerando este objetivo, se desarrollarán algunas

aplicaciones que involucren la manipulación de video, audio y también imágenes.

Las aplicaciones van a tener el fin de mantener al público en continuo movimiento. En

todo momento, se mantendrá el enfoque en el objetivo principal que es la de no tener

limitaciones en el alcance del uso de las aplicaciones y la facilidad de la creación de

una nueva.

1.3 Organización del informe

El presente informe se divide en 5 capítulos. El Capítulo 1 es el actual, donde se

encuentra una introducción general al proyecto.

El Capítulo 2 llamado Interactividad, contiene el contexto actual y antecedentes

relacionados al trabajo. Se introducen conceptos de interactividad con el usuario y se

muestra la evolución de las tecnologías relacionadas. Se hace especial hincapié en el

dispositivo Kinect el cual se utiliza a lo largo de todo el proyecto. También se muestra

un relevamiento de algunos museos y paseos existentes que utilizan algún tipo de

tecnología para incluir interactividad. Por último, se proporciona un panorama general

de las tecnologías usadas para la creación de las aplicaciones.

El Capítulo 3, Diseño e Implementación, es específico y central al proyecto. Se

encuentra dividido en dos secciones: en primer lugar se expone la arquitectura

propuesta en donde se explican todos sus componentes y luego, se detalla la

instanciación de la arquitectura en tres diferentes aplicaciones.

El Capítulo 4 se basa en los resultados de las pruebas realizadas sobre las

aplicaciones que fueron explicadas en el Capítulo 3. Comienza detallando el contexto

de las pruebas, los elementos utilizados y la cantidad de personas que asistieron.

Luego se pasa a describir los resultados de las pruebas, aplicación por aplicación,

indicando aquellos aspectos positivos, y también aquellos que deben corregirse.

El Capítulo 5, engloba las conclusiones del trabajo en dos secciones: en primer lugar

se detallan los resultados obtenidos con respecto a los objetivos propuestos; luego se

proponen posibles trabajos futuros sobre la plataforma y las aplicaciones

(12)

11

Al finalizar se encuentra la sección de Bibliografía, en donde se listan todas aquellas

(13)

12

Capítulo

2

Capítulo 2

Interactividad

En este capítulo se introducen los conceptos de interactividad con el usuario. Se hará

un recorrido sobre la evolución de la tecnología. Como la plataforma creada en este

proyecto se basa en el dispositivo Kinect, se incluirán las especificaciones necesarias

relacionadas a su uso. Luego se mostrará la forma en que se utiliza la interactividad

específicamente en el contexto de paseos y museos. Por último, se dará un panorama

general de las tecnologías usadas para la creación de las aplicaciones.

2.1 Evolución de la Interfaz de usuario

La interfaz de usuario es el medio con que el usuario puede comunicarse con una

máquina. Éstas fueron evolucionando a través del tiempo, siendo cada vez más

intuitivas. Se pueden clasificar según la forma de interacción con el usuario, CLI, GUI o

NUI (Figura 2.1).

Figura 2.1 - Evolución de las interfaces de usuario.

Las CLI[9], command-line interface o también interfaz de líneas de comando, permiten

a los usuarios dar instrucciones a algún programa informático por medio de una línea

de texto simple. Como se basa únicamente en la entrada y salida de texto, toda la

(14)

13

realiza generalmente en su totalidad con un teclado. Esta interfaz existe casi desde los

comienzos de la computación.

Las GUI[10], graphical user interface, en español interfaz gráfica de usuario, surgen

como evolución de las interfaces de línea de comandos. Éstas cuentan con el uso de

imágenes gráficas, incluyendo ventanas, íconos y menús. Estos objetos son

manipulados por un mouse y por lo general se pueden operar de forma limitada por un

teclado también. Su principal uso, consiste en proporcionar un entorno visual sencillo

que permita la comunicación con el sistema operativo de una máquina.

Las NUI[11], natural user interface, es el tipo de interfaz de usuario en las que se

interactúa con un sistema sin utilizar dispositivos de entrada. La idea general es que

en lugar de tener medios artificiales de entrada, el usuario interactúa con la máquina

de una manera más similar a la que utiliza para interactuar con las personas y objetos

en el mundo real, y de una manera más directa. Esto quiere decir, interactuar a través

del tacto, los gestos del cuerpo, las expresiones faciales, y el lenguaje.

Figura 2.2 - Interfaces de usuario (CLI, GUI y NUI respectivamente)

Hoy nos encontramos en el inicio de la próxima revolución, pasando de interfaces

gráficas de usuario (GUI) a interfaces naturales de usuario. La sociedad está en

constante movimiento, llena de información y muy comunicativa. Es por esto que la

computadora de escritorio ya no cumple con las necesidades y demandas requeridas

por una sociedad en continua evolución. En la actualidad, se usan los teléfonos

móviles, tabletas y pantallas táctiles de variados tamaños, incluso hasta del tamaño de

una mesa de conferencia para permanecer conectados, satisfacer necesidades y

lograr objetivos. Sin embargo, NUI es más que tocar algo con el dedo en lugar de

hacer clic con un mouse. Wii Remote (WiiMote)[1], Leap Motion[2] y Kinect[3] son

ejemplos de una serie de controladores de juegos y entretenimiento que son capaces

de reconocer los movimientos del cuerpo (o partes de ellos), y realizar acciones con su

(15)

14

Figura 2.3 - Dispositivo WiiMote

WiiMote[1] (Figura 2.3) es un dispositivo que tiene la capacidad de detección de

movimiento. Permite al usuario manipular e interactuar con elementos en pantalla a

través de reconocimiento de gestos y señalando a través del uso de tecnología de

acelerómetro ADXL330 y sensor óptico PixArt. Es el controlador principal para

Nintendo Wii, que gracias al sensor óptico, le permite determinar el lugar al que el

Wiimote está apuntando, independientemente del tipo o tamaño de la televisión.

Figura 2.4 - Dispositivo Leap Motion

Leap Motion[2] (Figura 2.4) es un dispositivo sensor que soporta movimientos de la

mano y de los dedos como entrada, análogo a un mouse, pero no requiere contacto

con las manos. El corazón del dispositivo consta de dos cámaras y tres LEDs

infrarrojos. Cuenta con un gran espacio de interacción que toma la forma de una

pirámide invertida. Anteriormente, el rango de visión se limitaba a 60 cm, luego de

(16)

15

Figura 2.5 - Dispositivo Kinect

Kinect[3] (Figura 2.5) es una línea de sensores de movimiento de entrada para

Microsoft Xbox 360 y Xbox One como también para PCs. El uso de cámaras y otros

complementos periféricos, permite a los usuarios controlar e interactuar con su

consola/computadora sin la necesidad de un controlador de juego, a través de una

interfaz natural de usuario usando gestos y comandos de voz. Como el proyecto

desarrollado se basa exclusivamente en el dispositivo Kinect, a continuación se

incluyen detalles del dispositivo:

2.1.1 Kinect

Figura 2.6 - Componentes del dispositivo Kinect

El dispositivo Kinect tiene una serie de componentes que hacen a su funcionamiento[12]

que se muestran en la Figura 2.6. Una cámara RGB con una resolución de 1280x960

permite la captura de imágenes de colores. Un emitidor infrarrojo (IR) se encarga de

(17)

16

rayos que vuelven reflejados. Estos rayos luego son convertidos en información de

profundidad midiendo la distancia entre un objeto y el sensor.

Un arreglo de cuatro micrófonos captura sonidos. Por la cantidad de micrófonos es

posible grabar audio, como así también encontrar la ubicación de la fuente de sonido y

la dirección de la onda de audio. Por último, un acelerómetro de 3 dimensiones con un

rango de 2G, donde G es la aceleración correspondiente a la gravedad, permite

determinar la orientación del Kinect.

Figura 2.7 - Rango de inclinación

El ángulo de visibilidad del dispositivo Kinect es de 43° en el espacio vertical, y de 57°

en horizontal. Debido a la inclinación motorizada, el espacio vertical puede moverse

27° hacia arriba o hacia abajo como se puede ver en la Figura 2.7.

Si están habilitados, el Kinect puede capturar audio, color y datos de profundidad, y

procesar los datos de profundidad para generar datos de esqueletos. Estos datos son

presentados en la forma de flujos de datos que se pueden controlar y acceder desde

las aplicaciones a través del SDK del dispositivo Kinect. Las aplicaciones

desarrolladas para este proyecto en particular, sólo utilizan los flujos de datos de

profundidad y de esqueletos.

El arreglo de micrófonos captura datos de audio a una resolución de 24 bits. Se

pueden ver en color lila en la Figura 2.8. Esto permite una precisión en un rango

dinámico de datos de voz, desde un habla normal a tres o más metros de distancia,

hasta una persona gritando. Además de capturar audio en alta definición, permite

focalizar en un audio proveniente de un lugar en particular, identificar la dirección del

(18)

17

Figura 2.8 - Arreglo de micrófonos del dispositivo Kinect marcados en violeta.

El flujo de datos de color es simplemente la imagen obtenida como si fuera a través de

una cámara web. Está disponible en diferentes resoluciones y formatos. El formato

determina si el flujo está codificado como RGB, YUV o Bayer. Sólo se pueden utilizar

una resolución y un formato a la vez. El sensor utiliza una conexión a través del puerto

USB lo que provee un determinado ancho de banda. La elección de la resolución

determina cómo es usado ese ancho de banda. Las imágenes en alta definición

utilizan más datos, pero se actualizan menos frecuentemente. Al bajar la resolución, se

actualizan más frecuentemente pero se pierde la calidad de la imagen debido a la

compresión.

Figura 2.9 - Frames de profundidad.

Cada frame del flujo de profundidad está formado por píxeles que contienen la

distancia en milímetros desde la cámara hasta el objeto más cercano. Este flujo une

dos tipos de datos distintos. Por un lado se encuentra la distancia, pero también se

toma en cuenta los datos de los jugadores segmentados. Cada dato es un entero

indicando el índice de un único jugador detectado (Figura 2.9).

El dispositivo Kinect procesa el flujo de profundidad para identificar hasta seis figuras

humanas. Los datos de la segmentación de jugadores sólo están disponibles si está

habilitado el rastreo de esqueletos. El valor „0‟ indica que no se encontró ninguna

(19)

18

jugadores. Un uso muy común de esta segmentación es para separar un usuario

específico de una imagen de color o de profundidad.

Figura 2.10 - Frames de esqueletos.

El rastreo de esqueletos permite al dispositivo Kinect reconocer personas y seguir sus

movimientos. Utilizando la cámara infrarroja, Kinect puede reconocer hasta 6 personas

en el área de visibilidad del sensor. De estos, sólo dos son rastreados en detalle, esto

es, se pueden detectar sus articulaciones en el espacio y rastrearlas en el tiempo

(Figura 2.10).

Los esqueletos en un frame pueden tener un estado de seguimiento de „rastreado‟ o „sólo posición‟. Aquellos „rastreados‟ proveen información detallada sobre la posición

de veinte articulaciones del cuerpo del usuario (Figura 2.11). En cambio, cuando un

esqueleto tiene un estado de „sólo posición‟, se tiene la información sobre la posición

del usuario, pero ningún detalle con respecto a las articulaciones.

(20)

19

Las aplicaciones pueden utilizar cada articulación para realizar acciones. Por ejemplo,

se puede utilizar la mano para guiar un cursor o simplemente dibujar la posición de las

articulaciones en pantalla. Una articulación también se puede clasificar en tres

estados: „rastreada‟ para una articulación claramente visible, „inferida‟ cuando no está claramente visible y se infiere su posición, o „no rastreada‟.

En octubre de 2014, surgió una nueva versión del SDK del dispositivo Kinect[13]. Se

amplió el campo de visión horizontal y vertical para la captura de profundidad y de

color. La captura de color es HD, los infrarrojos son independientes de la luz y hubo

mejoras con los micrófonos. La cantidad de esqueletos rastreados en detalle aumenta

de 2 a 6, y la cantidad de articulaciones rastreadas pasan de 20 a 25 cada uno,

incluyendo los pulgares. También es posible utilizar el dispositivo desde múltiples

aplicaciones.

2.2 Interactividad en paseos y museos

En la actualidad existe en el mundo un crecimiento de museos interactivos. Se llaman

así a aquellos museos que rompen la barrera del „No tocar‟ y en donde lo prohibido es

quedarse quieto. Con el objetivo de transformar un simple paseo por el museo, en un

paso más allá, con rasgos aún más interesantes y atrapantes. De esta forma un

recorrido silencioso y cauteloso puede transformarse en una experiencia divertida e

innovadora.

Con la incorporación de nuevas tecnologías, los museos nos permiten aprender

jugando. La unión del arte y la ciencia abre un gran camino de posibilidades. La

interactividad se lleva a cabo a través de dispositivos como los celulares y tabletas,

como así también el Kinect previamente mencionado.

El Museo del Louvre[14] incluyó la interactividad a sus recorridos utilizando códigos QR

y un dispositivo portátil Nintendo 3DS, ideal para descubrir el museo parisino (Figura

2.12). Este dispositivo pasó a ser el audio-guía oficial, sustituyendo a los modelos

tradicionales. Incluye mapas interactivos, recreaciones en 3D de obras e información

adicional sobre las mismas. La información brindada permite ser traducida a los

principales idiomas como el español, francés, alemán, japonés, coreano, italiano o

(21)

20

Figura 2.12 - Interacción en el Museo de Louvre con el uso de Nintendo 3DS y códigos QR.

Museon[15] es un museo de cultura y ciencia que incorpora interactividad en todas sus

exposiciones. Cree firmemente en la idea de que se aprende más rápido si se puede

poner en práctica la teoría que se aprendió. Repartidos por todo el museo se

encuentran unos terminales que permiten a las personas identificarse con un código

de barras y formula preguntas para comprobar la significatividad educativa de la visita.

Figura 2.13 - Juego en Museon con la utilización de PuppyIR.

A través de la tecnología del proyecto PuppyIR[16], el museo permite crear recorridos

interactivos en equipos, comenzando y terminando en terminales multi-táctiles (Figura

2.13). Durante el recorrido, el equipo debe recolectar elementos para luego llevarlos a

una terminal al finalizar. Aquí, el equipo deberá unir los elementos recolectados con

(22)

21

Figura 2.14 - Live Projection Mapping - EVA 2013

EVA[17] es la conferencia de desarrollo de videojuegos más importante de

Latinoamérica. Se realiza anualmente desde 2003 y cuenta con talleres y conferencias

especialmente pensadas para presentar las últimas novedades en áreas como

Programación, Arte, Publishing y Game Design. En la edición 2013 se realizó una

proyección en vivo sobre un grupo de bailarines utilizando Kinect[18]. Se debió ajustar

manualmente su posición para que su punto de vista coincida con el punto de vista del

proyector (Figura 2.14).

Figura 2.15 - Pisos interactivos en eventos.

La empresa Piso Interactivo[19] está ubicada en Guadalajara, México. Son creadores

de software e instalaciones interactivas para museos, diseño de interiores,

ambientación, eventos sociales y exposiciones. La Figura 2.15 muestra el uso de una

(23)

22

Figura 2.16 - ‘Play Work Build’ en el National Building Museum.

National Building Museum[20], de Washington DC, es un museo de arquitectura, diseño,

ingeniería, construcción y planeamiento urbano. Incorporó a sus visitas una aplicación

interactiva para los niños llamada „Play Work Build‟[21] que usa el cuerpo para construir

paredes virtuales al mantenerse quietos y destruirlas con los movimientos. Esto se

desarrolló gracias a la utilización del dispositivo Kinect (Figura 2.16).

Figura 2.17 - ‘Strike a pose’ en Cleveland Museum of Art.

Cleveland Museum of Art[22] [23], ubicado en Ohio, se especializa en arte Asiático y

Egipcio. Su recorrido ofrece al espectador una serie de aplicaciones que permiten

interactuar con el arte, como „Strike a pose‟ que reta a imitar las poses de diferentes esculturas. Como se puede ver en la Figura 2.17, al igual que „Play Work Build‟, utiliza

(24)

23

Figura 2.18 - Juego interactivo relacionado al Básquet en Chicago Sports Museum.

Chicago Sports Museum[24] es un museo que fue diseñado con un foco en la

interactividad y entretenimiento. Una de las actividades más interesantes que este

museo brinda, es la de imitar alguna jugada específica de Básquet, Fútbol, Baseball, o

Jockey. En la imagen se puede ver un juego de Básquet en un contexto similar al real,

que gracias al Kinect, un avatar de un jugador profesional sigue los movimientos de la

persona que lo juega (Figura 2.18).

Figura 2.19 - Avatares en Sedena.

En el museo creado en honor a las Fuerzas Armadas de México[25] se incluyó una

exhibición digital multi sensorial. Para ello, se realizaron instalaciones electrónicas que

(25)

24

logró incorporar modelos en 3D que al detectar la presencia de una persona cobran

vida y simulan los movimientos que realizan los visitantes (Figura 2.19).

2.3 Tecnologías utilizadas

El próximo capítulo se centra en el diseño e implementación de una serie de

aplicaciones interactivas. Estas aplicaciones utilizan video y audio para su

comunicación con el usuario. Existen diversas tecnologías que permiten la

manipulación de estos elementos.

Con respecto a la reproducción de video, se utilizó una biblioteca que permite

manipular los videos frame a frame. Emgu CV[26] es un wrapper para la biblioteca de

procesamiento de imágenes OpenCV. De esta manera se permite acceder a las

funciones de OpenCV[27] desde cualquier lenguaje .NET.

Luego, para la reproducción de audio se utilizó la biblioteca FMOD[28] que puede

manejar a los sonidos en un alto nivel, incorporando diferentes efectos. El uso de esta

biblioteca permite una mayor extensibilidad a la hora de incorporar nuevas

aplicaciones de audio. Reproduce y mezcla archivos de sonido de diversos formatos

en muchos sistemas operativos.

Para manipular la vista a nivel de píxel, o simplemente mostrar imágenes o videos sin

la necesidad de dinámicamente manipularlos, la vista XNA[29] es ideal. Brinda en un

alto nivel la interacción de la aplicación con la vista. Permite mostrar imágenes y

videos en diferentes capas superpuestas, y la creación de una nueva textura a mostrar

es muy sencilla.

A continuación se muestra el diseño de una plataforma para la creación de

aplicaciones interactivas. Luego, junto al uso de las tecnologías, se realiza la

(26)

25

Capítulo

3

Capítulo 3

Diseño e Implementación

El capítulo de implementación está dividido en dos partes. En primer lugar se describe

la arquitectura de software de la plataforma desarrollada. En esta sección se

presentan los componentes (y relaciones entre ellos) de las aplicaciones realizadas a

modo de ejemplo de utilización de la plataforma, como el funcionamiento de cada

aplicación. En segundo lugar se muestran también diagramas y partes de código

necesarios para ayudar a describir el funcionamiento de la plataforma descripta.

3.1 Arquitectura propuesta

Tal como se describió en el Capítulo 2, el desarrollo se centra en poder capturar y

distribuir información brindada por el Kinect, de una forma estandarizada y eficiente.

La plataforma está inclinada hacia la creación de aplicaciones para el entretenimiento,

interactuando con el público a través de la vista y el oído.

En las siguientes secciones se explicarán los componentes que forman parte de la

plataforma, para llevar a cabo cualquier aplicación deseada. El patrón de la

arquitectura está basado en Model-View-Controller[30]. Cada sección detallará en

manera progresiva la creación del modelo, del controlador y de la vista, para llegar por

último a sus versiones finales.

3.1.1 Controlador

Al inicio del proyecto, se tenía en claro que se iban a desarrollar una serie de

aplicaciones las cuales serían controladas por las personas, a través del dispositivo de

Kinect. Para este fin, se debía crear un gestor que sea el encargado de la

comunicación con el aparato físico. Toda comunicación entre el gestor y el dispositivo

físico se realiza a través del Kinect SDK, que brinda diversas posibilidades para el

(27)

26

Figura 3.1 - Interacción del dispositivo Kinect con la aplicación a través del Kinect SDK

El gestor, llamado KinectDevice, se fue implementando progresivamente. A lo largo de

los siguientes párrafos se explicará el camino tomado para su desarrollo, hasta llegar a

la versión final con todos sus métodos y atributos. Sus datos son crudos, y el

controlador es el encargado de tomar estos datos, transformarlos y actualizar el

modelo de datos.

La funcionalidad indispensable para comenzar a utilizar el gestor, es la inicialización.

Dentro de initializeKinect se conecta al dispositivo físico, y devuelve un dato para

indicar si la conexión fue exitosa o no. Internamente, busca el primer sensor conectado

y lo guarda como un atributo de la clase para ser usado en cualquier momento. Por

último, ejecuta la acción Start sobre el sensor.

Una vez inicializado, es fundamental la liberación del recurso físico. Por tal motivo, se

incorporó stopKinect. Aquí, a través del sensor guardado, le indica al Kinect que frene

el flujo de datos.

En el curso de esta primera etapa, se incluyeron sólo aquellos métodos primitivos. En

el Diagrama 3.1 se pueden ver aquellos que permiten la inicialización y la liberación

del dispositivo. También se incluye el método privado que es utilizado internamente

para obtener el primer sensor conectado, y el atributo privado que es fijado por el

mismo.

(28)

27

Como se mencionó en el capítulo anterior, para poder utilizar los datos brindados por

el dispositivo Kinect, se deben habilitar los diferentes flujos que se vayan a utilizar.

Cada flujo de datos dispara un evento indicando un nuevo frame. Se debe tener un

método asociado a cada uno de ellos para poder atraparlos y así guardar los datos

necesarios. Para el propósito actual sólo se van a utilizar dos: Skeleton Stream y

Depth Stream. Como fue descripto anteriormente, el Skeleton Stream brinda

información sobre los esqueletos encontrados, y el Depth Stream sobre la profundidad

de estos esqueletos, identificando a cada jugador. Su necesidad se verá especificada

en las próximas secciones.

Se debió modificar initializeKinect para incorporar los eventos de Kinect. En el caso

de que se encuentre un sensor disponible, se establecen aquellos métodos

encargados de atrapar el evento (Code snippet 3.1). Entonces, si el flujo de datos está

habilitado, en cada momento en el que kinect tiene un nuevo frame disponible, activa

el evento y KinectDevice puede tomar los datos deseados y los mantiene actualizados

para tenerlos disponibles cuando sean solicitados por algún controlador. En el caso en

que en el futuro se quiera incorporar un nuevo flujo de datos, es aquí donde se debe

incluir el nuevo evento especificando la funcionalidad determinada.

if (null != sensor) {

// Agrega controlador de evento para cuando haya nuevo frame de esqueleto

sensor.SkeletonFrameReady += skeletonFrameReady;

// Agrega controlador de evento para cuando haya nuevo frame de profundidad

sensor.DepthFrameReady += depthFrameReady; }

Code snippet 3.1 - Incorporación de métodos para atrapar los eventos de flujos de datos.

El evento disparado cuando un frame de esqueleto está listo, emite sus argumentos

del tipo SkeletonFrameReadyEventArgs. Dentro de los argumentos se encuentra un

SkeletonFrame el cual el gestor utiliza para tomar los datos de los esqueletos en forma

(29)

28

private void skeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)

{

using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())

{

if (skeletonFrame != null) {

if (skeletons == null)

skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];

skeletonFrame.CopySkeletonDataTo(skeletons); }

} }

Code snippet 3.2 - Captura de evento de nuevo frame de esqueletos.

El evento disparado cuando un frame de profundidad está listo, es similar al anterior.

Sus argumentos contienen un DepthImageFrame dentro de

DepthImageFrameReadyEventArgs. El DepthImageFrame es utilizado para tomar los

datos de los píxeles de profundidad, y guardarlos en un arreglo de tipo

DepthImagePixel (Code snippet 3.3).

private void depthFrameReady(object sender, DepthImageFrameReadyEventArgs e)

{

using (DepthImageFrame depthImageFrame = e.OpenDepthImageFrame())

{

if (depthImageFrame != null) {

if (depthPixels == null)

depthPixels = new Skeleton[depthImageFrame.PixelDataLength];

depthImageFrame.CopyDepthImagePixelDataTo(depthPixels); }

} }

Code snippet 3.3 - Captura de evento de nuevo frame de profundidad.

Se debe permitir a cada aplicación habilitar el o los flujos de datos que se utilicen, para

no estar recibiendo frames que son totalmente innecesarios. Se provee este servicio a

través de enableSkeletonStrem e enableDepthStream para habilitar cada uno de los

flujos previamente mencionados.

Durante el desarrollo de la primera aplicación se vio necesario borrar aquellos

esqueletos obtenidos del SkeletonFrame. En efecto, también se incorporó esta nueva

posibilidad implementando resetSkeletons, el cual tiene como única funcionalidad

eliminar el arreglo de esqueletos.

Resumiendo, en esta etapa se agregó funcionalidad relacionada a los flujos de datos.

(30)

29

como métodos privados, aquellos que se encargan de atrapar los eventos y mantener

actualizados los datos: depthPixels y skeletons. Los getters son indispensables para

obtener aquellos datos actualizados. Por último, se permite borrar datos. En el

Diagrama 3.2 se pueden ver resaltadas aquellas actualizaciones de la clase.

Diagrama 3.2 - Clase KinectDevice luego de la etapa de comunicación con el dispositivo físico.

El próximo paso es crear un controlador que utilice el gestor de Kinect como un

recurso. Tal como se mencionó anteriormente, el controlador se encarga de inicializar

el dispositivo Kinect, y luego tomará los datos crudos de KinectDevice, los

transformará y actualizará al modelo. Para mejorar la abstracción, y permitir así en un

futuro la incorporación de cualquier tipo de controlador de una manera sencilla, se

formalizó una estructura.

Es así que se llegó al diseño de los controladores. Cada controlador creado debe

implementar una interfaz IController. Sus métodos se pueden dividir fácilmente en tres:

load, update y unload, estandarizando la división de funcionalidad (Code snippet 3.4).

interface IController

{

//Inicialización de cualquier recurso necesario

bool load();

//Transformación de datos //Actualización del modelo

void update();

//Liberación de los recursos

void unload(); }

Code snippet 3.4 - Interfaz IController

Dentro del load, el controlador debe inicializar cualquier recurso que vaya a ser

(31)

30

específicas de este proyecto, es el KinectDevice. Otros recursos utilizados también en

esta ocasión pueden ser un gestor de colores y/o un gestor de audio. Estos se verán

explicados a lo largo de las secciones 3.2.2 y 3.2.3, junto con las últimas dos

aplicaciones que los utilizan.

Si se produjo algún problema dentro de la inicialización, el método se encarga de

indicar la situación a través de un booleano de retorno (Figura 3.2). De esta manera, la

vista es capaz de reaccionar. Sus acciones se verán en la sección correspondiente al

explicar el componente de la vista.

Figura 3.2 - Secuencia de llamados para la inicialización

El método unload debe contener la funcionalidad para liberar los recursos. Cada

controlador tendrá que liberar dentro de este método, todos sus recursos utilizados

(Figura 3.3). En este proyecto en particular, todos los controladores utilizan Kinect, por

lo tanto deberán liberarlo a través de kinectDevice.stopKinect().

Figura 3.3 - Secuencia de llamados para terminar la aplicación.

El update se ejecuta constantemente. En su cuerpo, el controlador debe realizar un

análisis de los datos y actualizar el modelo con los datos necesarios (Figura 3.4). Esta

(32)

31

Figura 3.4 - Secuencia de llamados para la actualización del modelo.

En este proyecto en particular, dentro del método update se debe encontrar la

comunicación con el gestor de Kinect. Previo a la actualización del modelo, se deben

transformar los datos. La transformación de los datos es la misma para cualquier

controlador que utilice la clase KinectDevice.

Por este motivo, se decidió crear una clase abstracta, KinectController, que sea un tipo

de IController. En ella se encontrarán todos los métodos necesarios para evitar la

repetición de código, y así facilitar la creación de un nuevo controlador dependiente de

Kinect. En la Figura 3.5 se puede ver su comunicación con KinectDevice.

Figura 3.5 - Comunicación necesaria entre el controlador y gestor de Kinect.

En las siguientes secciones se verá la forma en que cada aplicación desarrollada

permitió incorporar nuevos métodos y modificar la estructura básica de la plataforma

planteada, explicando también el uso de cada uno. A continuación se pasará a

mencionar aquellos que fueron agregados a KinectController a lo largo de todo el

desarrollo.

Como se nombró anteriormente, a través del SkeletonFrame, se mantiene un arreglo

de tipo Skeleton. Esta información brinda al controlador un conjunto amplio de datos y

en diversas formas. En este caso se puede determinar si hay algún esqueleto

traqueado, acceder a la cantidad de esqueletos encontrados, o también a sus

(33)

32

Figura 3.6 - Transformación de los datos por el método getTotalSkeletons.

La cantidad de esqueletos encontrados se obtiene a través de getTotalSkeletons()

(Figura 3.6). Como se mencionó en las especificaciones del Kinect dentro del capítulo

2, cada esqueleto tiene la propiedad TrackingState. Sus posibles valores son

PositionOnly, Tracked, o NotTracked. El estado Tracked indica que el esqueleto tiene

sus articulaciones rastreadas. Un esqueleto con PositionOnly sólo contiene su posición

general. NotTracked significa que no se rastreó el esqueleto. Este método en particular

cuenta aquellos esqueletos que como TrackingState tengan PositionOnly o Tracked

(Figura 3.7).

Figura 3.7 - Diferentes estados de rastreo: PositionOnly (izquierda) y Tracked (derecha)

Para consultar si un hay un esqueleto disponible, se puede utilizar el método

isSkeletonAvailable(). Se encarga de devolver un boolean indicando si existe en aquel

arreglo de esqueletos, algún esqueleto con TrackingState igual a Tracked (Figura 3.8).

(34)

33

Figura 3.8 - Transformación de los datos por el método isSkeletonAvailable.

A través del método getFirstSkeletonPosition(), se obtiene la posición del primer

esqueleto rastreado, es decir, con TrackingState igual a Tracked (Figura 3.9).

Nuevamente, este método consulta internamente por el primer esqueleto rastreado. La

posición de retorno es de tipo Point, pero la posición del esqueleto es de tipo

SkeletonPoint. Por lo tanto fue necesaria la incorporación de la funcionalidad para

solucionar la diferencia. Se incorporó un nuevo método a KinectDevice.

Figura 3.9 - Transformación de los datos por el método getFirstSkeletonPosition.

El método skeletonPointToScreen se encarga de mapear un SkeletonPoint a un

punto de pantalla. Los puntos de esqueletos están expresados en metros mapeados a

la habitación (Figura 3.10). El sensor del Kinect tiene un CoordinateMapper que tiene

la capacidad de traducir estos puntos a un DepthPoint a través del método

MapSkeletonPointToDepthPoint y la resolución de pantalla. Un DepthPoint se mide

en milímetros, y por lo contrario al punto de esqueleto, representa la posición dentro

del frame. Entonces, puede devolver un Point inicializado con los valores X e Y del

DepthPoint obtenido.

Más adelante se verá que también fue necesario consultar por todas las posiciones de

todos los esqueletos. Para ello existe también la transformación de Figura 3.10 - Espacio del esqueleto (izquierda) comparado con los valores de

(35)

34

getSkeletonPositions(), que devuelve un arreglo de Point de la longitud del arreglo de

esqueletos (Figura 3.11). En cada elemento guarda la posición mapeada a pantalla de

cada Skeleton.Position que se encuentra con un TrackingState de PositionOnly o

Tracked. En el caso de que el esqueleto no está traqueado, se inicializa un Point con

valores negativos indicando la situación.

Figura 3.11 - Transformación de los datos por el método getSkeletonPositions.

Volviendo a los diferentes tipos de frames, a través del DepthFrame se mantiene un

arreglo de tipo DepthImagePixel. El gestor de Kinect sólo brinda un método,

getDepthPixels(), para que cualquier controlador lo pueda acceder. KinectController se

encarga de recorrer este arreglo para quedarse sólo son los datos necesarios. Así se

forma un arreglo de enteros indicando el id de cada jugador en cada píxel (Figura

3.12). El método encargado de la transformación es getPlayersId().

Figura 3.12 - Transformación de los datos por el método getPlayersId.

También es posible convertirlo en un arreglo de booleanos. De esta manera, en cada

posición del arreglo se indica si hay o no algún jugador (Figura 3.13).

Figura 3.13 - Transformación de los datos por el método isPlayerOnPixel.

Entonces, a lo largo de esta etapa, se obtuvo una interfaz que debe implementar todo

controlador. Esta interfaz incluye métodos para la inicialización, actualización y

finalización. Como todo controlador dependiente de Kinect debe transformar los datos

de KinectDevice, se pensó en una clase abstracta que contenga a los

transformadores. Luego, cada controlador específico para cada aplicación deberá

extenderlo. A continuación se muestra la relación entre la interfaz IController, la clase

abstracta KinectController y el gestor KinectDevice (Diagrama 3.3). El método

(36)

35

Diagrama 3.3 - Estructura de los controladores.

El gestor de Kinect no tiene ningún conocimiento de su entorno. Éste es simplemente

un proveedor de servicios a los controladores que lo necesiten. En una mirada

general, se puede decir que los controladores son los encargados de inicializar el

gestor, transformar los datos, y, una vez finalizada la ejecución, liberarlo.

Cada método de los controladores, heredados de IController, son en algún momento

llamados desde alguna vista. Previo a actualizar la interfaz de usuario, se recuperarán

los datos del modelo. La vista será desarrollada más adelante. A continuación se

procederá a explicar el modelo de datos.

3.1.2 Modelo

El modelo es el encargado de generar un objeto basado en las actualizaciones del

controlador que luego la vista pueda utilizar para actualizarse. En la Figura 3.14 se

muestra la comunicación necesaria entre los distintos componentes del sistema. En

esta sección se procederá a explicar sólo las relaciones que se encuentran resaltadas,

esto es, la relación con el controlador explicado en la sección anterior y la

(37)

36

Figura 3.14 - Comunicación entre los componentes del sistema.

Cualquier modelo creado deberá brindar a la vista un método que le devuelva un

objeto específico. Como el tipo de datos que necesita la vista depende de cada vista

específica y del contexto de la aplicación, el tipo devuelto por el modelo debe ser

genérico.

Para abstraer todo tipo de modelo, se creó la interfaz IModel que sólo contiene dos

métodos, update y getData. El primero se encarga de crear un objeto a partir de los

atributos actualizados por el controlador, para que luego pueda ser devuelto en el

segundo. getData devuelve un objeto de tipo object, que luego la vista sabrá entender.

Entonces, cada modelo creado deberá implementar a esta interfaz, e instanciar un

objeto específico a una vista y a un determinado contexto (Diagrama 3.4).

Diagrama 3.4 - Interfaz IModel con dos modelos de ejemplo.

Cada implementación de un modelo es específica a la funcionalidad deseada de cada

aplicación. Previo a poder crear el objeto de devolución, el modelo deberá tener todos

sus atributos actualizados por el controlador. Dependiendo del objetivo del modelo, se

(38)

37

contenga un entero que indique la cantidad de personas, un punto indicando la

posición de una persona en específico, o también puede necesitar un arreglo de

posiciones. Las implementaciones de tres modelos diferentes se verán en la sección

3.2.

Por último, el controlador ejecuta el método update, en donde se crea el objeto

específico a la vista, o se realiza alguna otra acción según los datos previamente

establecidos. Este objeto será creado de diferentes maneras dependiendo del objetivo

final de cada aplicación.

El método getData se ejecuta constantemente por una vista. Cuando es llamado,

significa que el controlador ya actualizó el modelo. Es aquí donde se devuelve el

objeto específicoque fue creado previamente en la actualización.

Los modelos tienen infinitas posibilidades sobre lo que se puede mostrar utilizando los

datos disponibles. En las siguientes secciones se mostrará cómo funcionan algunos

modelos, y los resultados obtenidos en el desarrollo de aplicaciones. La creación de

nuevos modelos para ser actualizados por un controlador de tipo KinectController es

muy sencilla.

En las imágenes que se muestran en la Figura 3.15, se ven 3 posibles

representaciones de los objetos que crean los modelos. En la primera imagen se ve el

uso de la posición general de cada esqueleto para mostrar una calavera por cada

jugador. Esto se puede lograr obteniendo las posiciones de todos los esqueletos.

También se puede generar un contador, por ejemplo, jugando con la cantidad de

esqueletos rastreados. Utilizando las posiciones de un esqueleto, se pueden mostrar

todas sus articulaciones. Y de esta manera, con el uso de la imaginación, se pueden

crear una cantidad infinita de aplicaciones.

Figura 3.15 - Posibles usos de los datos por el modelo

Como es el caso de los controladores y los modelos, las vistas también deben seguir

(39)

38

3.1.3 Vista

La vista es la encargada de mostrar a través de la interfaz gráfica lo que el usuario

debe ver, creando una representación del modelo con el que se interactúa mediante

un controlador. Su funcionalidad principal es la de recibir un objeto, como por ejemplo

un arreglo de colores, o simplemente un valor entero, crear un frame de acuerdo a

estos datos, y mostrarlo por pantalla (Figura 3.16). Pero eso no es todo. Para llegar a

ello, es necesaria cierta configuración y comunicación con los demás componentes.

Previo a obtener los datos del modelo, la vista debe indicar al controlador que lo

actualice. Por ende, es indispensable que contenga un atributo de tipo IController y

otro de tipo IModel.

Figura 3.16 - Comunicación necesaria entre la vista y el modelo.

Al iniciarse la aplicación, es necesario inicializar todos aquellos componentes de la

vista. Es posible establecer una imagen o un video de fondo, la resolución de la

pantalla, si se quiere o no en pantalla completa, o si se quiere mostrar o no el mouse,

entre otras opciones. Todas estas aplicaciones, en particular, son pantalla completa y

el mouse no está visible.

Una vez que se inicializó a ella misma, debe instanciar el controlador y el modelo con

tipos no abstractos de cada uno de ellos. Y ahora sí, debe inicializar el controlador a

través del load. Este método devuelve a la vista un boolean indicando si la carga se

realizó correctamente. Es posible que se intente inicializar y por ejemplo el dispositivo

Kinect no esté conectado. En estos casos, la vista se encarga de avisarle al usuario de

(40)

39

Figura 3.17 - Secuencia de llamados para la inicialización

Hasta esta instancia se tiene una vista recientemente inicializada, que contiene un

controlador inicializado y un modelo de datos. Los recursos necesarios se encuentran

inicializados por el controlador. Queda un paso importante a realizar por la vista para

comenzar con la visualización.

El siguiente paso es dar comienzo a un evento que se produce constantemente en el

tiempo, un timer que su función es actualizar la vista. Dentro de este método disparado

en cada momento del tiempo, draw, la vista debe llamar al update del controlador.

Este método, como se mencionó en la sección anterior, transforma los datos crudos

para seguidamente actualizar al modelo. Luego, la vista debe llamar al método

getData del modelo. Dependiendo de la vista, la manera de crear el frame a mostrar y

la manera en dibujar sobre la pantalla varía (Figura 3.18).

Figura 3.18 - Secuencia de llamados para la actualización de la vista.

El método getData del modelo, devuelve un objeto genérico que la vista utilizará para

crear el objeto a mostrar. Como se verá en la sección de la instanciación de la

(41)

40

Estas vistas difieren en el tipo del objeto que muestran. Las vistas de XNA, por

ejemplo, utilizan una Texture2D que dibujan sobre pantalla. Windows Forms, con el

uso de la biblioteca Emgu CV, necesita de un Image<Bgr,byte>. Los datos recibidos

por el modelo pueden variar, por ejemplo entre un arreglo de colores para inicializar

una Texture2D, o un entero indicando la posición de un video para obtener un

Image<Bgr,byte>.

En algún momento, después de haber utilizado la aplicación el tiempo necesario, se va

a querer detenerla. La vista debe atrapar un evento que le permita identificar cuándo el

usuario desea cerrarla. En este caso en particular se usa la tecla escape. El método

llamado cuando se produce ese evento, es el que llama al último método del

controlador, unload. Recordando, el unload se encarga de liberar todos los recursos

utilizados (Figura 3.19).

Figura 3.19 - Secuencia de llamados para terminar la aplicación.

Concluyendo con el diseño de la vista, se puede poner un nombre formal a sus

métodos, dividiendo así correctamente su funcionalidad. El método de inicialización es

un load, que además de inicializar la vista, inicializa el controlador. A partir de ese

momento se dispara un evento constantemente, que llama al método draw de la vista,

dentro del cual se encuentra el update del controlador, el getData del modelo y la

creación del objeto que actualiza la pantalla. Por último, el evento de una tecla ejecuta

el método close, y justo antes de cerrar la aplicación, ejecuta el unload del controlador

(Diagrama 3.5).

(42)

41

En la siguiente sección se procederá a explicar la creación de las aplicaciones. Desde

el pensamiento que llevó a implementarlas, se las recorrerá a través de los primeros

pasos, y luego cómo fueron evolucionando hacia las versiones finales. No se dejará de

lado las diferencias y similitudes que hay entre todas ellas.

3.2 Diseño de cada aplicación

Como se mencionó en el capítulo de introducción, la idea es generar una plataforma

para el desarrollo de aplicaciones en el entretenimiento, específicamente para su uso

en museos. Para poder cumplir con el objetivo se fueron pensando aplicaciones para

ser implementadas y así instanciar la arquitectura que se explicó en la sección

anterior.

La instanciación de las aplicaciones se realizó con un fin específico, éstas serían

usadas en un museo de tenis. Se realizó un relevamiento de aplicaciones interactivas

en el contexto de museos y paseos. También se hizo una investigación sobre el uso

de la interactividad en el deporte. Los resultados obtenidos se encuentran a lo largo de

los capítulos uno, „Introducción‟ y 2, „Interactividad‟. Luego de observar diferentes

aplicaciones y de diferentes contextos se comenzó a pensar en aplicaciones

concretas.

A continuación se explicará el proceso que tuvo el desarrollo de cada aplicación. Se

podrán observar desde los primeros pasos y cómo fueron evolucionando para llegar al

objetivo. Se mostrará cómo fueron instanciados cada uno de los componentes de la

arquitectura y los detalles técnicos específicos de cada aplicación.

3.2.1 Reproductor de video

Para comenzar, se quería realizar algo que atraiga al público, dando un efecto

sorpresa. Es así que se pensó en la reproducción de un video. Con la incorporación de

Kinect generaría ese efecto sorpresa que se buscaba. Una persona de lejos, ve la

reproducción de un video en cámara lenta. Al acercarse, es decir, al entrar en el área

(43)

42

Figura 3.20 - Idea básica sobre el funcionamiento del Reproductor de Video

El objetivo final es implementar un reproductor de video que reproduzca de manera

constante un video en cámara lenta, y al pasar una persona por el frente de la

instalación, (dependiendo de la dirección) avance a una velocidad mayor o retroceda.

En la Figura 3.21 se intenta mostrar la idea en una secuencia de salto cuando no hay

movimientos y cuando hay movimientos hacia derecha e izquierda respectivamente.

Figura 3.21 - Acción de los movimientos

(a) Cámara lenta (b) Movimiento hacia derecha (c) Movimiento hacia izquierda

Durante su desarrollo, se pasó por varias etapas antes de llegar a la versión final.

Cada etapa incorpora algo de funcionalidad nueva. A lo largo de esta sección se

explicarán cada una de ellas. Lo que es común a todas las versiones, es el uso de los

Referencias

Documento similar