UNIVERSIDAD DE CASTILLA-LA MANCHA ESCUELA SUPERIOR DE INFORMÁTICA GRADO EN INGENIERÍA INFORMÁTICA TRABAJO FIN DE GRADO KinBehR KINect for human BEHaviour Recognition Rubén Cantarero Navarro Julio, 2014 K IN B EH R KIN ECT FOR HUMAN BEH AVIOUR R ECOGNITION UNIVERSIDAD DE CASTILLA-LA MANCHA ESCUELA SUPERIOR DE INFORMÁTICA Tecnologías y Sistemas de Información TECNOLOGÍA ESPECÍFICA DE TECNOLOGÍAS DE LA INFORMACIÓN TRABAJO FIN DE GRADO KinBehR KINect for human BEHaviour Recognition Autor: Rubén Cantarero Navarro Director: Dra. María José Santofimia Romero Director: Dr. Juan Carlos López López Julio, 2014 Rubén Cantarero Navarro Ciudad Real – Spain E-mail: Rubén.Cantarero@alu.uclm.es Teléfono: 699 384 459 c 2014 Rubén Cantarero Navarro Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". Se permite la copia, distribución y/o modificación de este documento bajo los términos de la Licencia de Documentación Libre GNU, versión 1.3 o cualquier versión posterior publicada por la Free Software Foundation; sin secciones invariantes. Una copia de esta licencia esta incluida en el apéndice titulado «GNU Free Documentation License». Muchos de los nombres usados por las compañías para diferenciar sus productos y servicios son reclamados como marcas registradas. Allí donde estos nombres aparezcan en este documento, y cuando el autor haya sido informado de esas marcas registradas, los nombres estarán escritos en mayúsculas o como nombres propios. i TRIBUNAL: Presidente: Vocal: Secretario: FECHA DE DEFENSA: CALIFICACIÓN: PRESIDENTE Fdo.: VOCAL SECRETARIO Fdo.: Fdo.: iii Resumen Actualmente la sociedad está experimentado importantes cambios en los que, cada vez más, se confía en que la tecnología facilite el día a día de las personas. Es por eso que, de forma exponencial, están apareciendo continuamente sistemas y dispositivos enfocados a ayudar a las personas en su vida cotidiana. En este contexto, el reconocimiento de acciones humanas (Human Action Recognition) está comenzado a jugar un papel fundamental en importantes áreas cómo la vídeo-vigilancia, asistencia a personas mayores y discapacitados, la Interacción Persona-Ordenador, etc. El presente proyecto estudia cómo la utilización de cámaras de profundidad puede ayudar a mejorar las tasas de reconocimiento de acciones humanas en las que los movimientos corporales no han sido previamente preestablecidos. La metodología seguida está descompuesta en dos etapas. En la primera de ellas se ha estudiado cómo obtener e interpretar la información proporcionada por este tipo de cámaras y analizar qué puede aportar esta información al reconocimiento de acciones. En la segunda etapa se ha empleado un algoritmo de aprendizaje máquina, conocido como Bag of Words (B OW), que proporciona una estimación de la clasificación de acciones a partir de secuencias de vídeo mediante el análisis de las características de imágenes. Finalmente, mediante la utilización de diferentes conjunto de datos, se ha entrenado y evaluado el sistema propuesto de manera que se garantice la robustez del mismo ante la multimodalidad en la realización de acciones. Por esta razón también se ha llevado a cabo la elaboración de un dataset propio. Para concluir, los resultados obtenidos han sido comparados con otros estudios para verificar si este nuevo enfoque basado en el uso de cámara de profundidad supone una mejora en el reconocimiento de acciones humanas. V Abstract Society is currently experimenting major changes in which, everyday more, major responsibilities are being delegated to technology to simplify people daily lives. That is the reason why, exponentially, systems and devices are targeting their role as people helpers. In this context, recognising human actions (Human Action Recognition) is playing a key role in important areas such as video surveillance, assistance to elder and disabled people, the Human-Computer Interaction, etc. This project describes the implementation of a system for human action recognition, based on the novel use of in-depth cameras. This work therefore involves the evaluation of the use of in-depth cameras can help improving recognition rates obtained for human actions in which body movements have not been previously showed to the recognising system. The followed methodology is decomposed into two stages. During first stage we have studied how to obtain and interpret the information provided by these cameras as well as to identify the information brought into light by the recognised actions. During the second stage, a machine learning algorithm has been implemented, using B OW model. This model provides an estimate of the action classification from video sequences by analysing the image characteristics. Finally, the use of different datasets, one for training and a different one for testing, enriches the system with robustness and multimodality support. In order to enhance the system with these features, a new dataset has been designed and recorded, also made available for the scientific community. Finally, obtained results have been compared with state-of-the-art studies to verify whether the proposed approach improves existing approaches. VII Agradecimientos Estos últimos cuatro años han supuesto los mejores y peores años de mi vida, con momentos buenos y malos. Pero me gustaría quedarme con el recuerdo de todos aquellos buenos momentos que me han mejorado como profesional y, lo más importante, como persona. Sin embargo, es la hora de comenzar otra nueva etapa y, antes de ello, me gustaría aprovechar este breve espacio para agradecer a todas aquellas personas que de alguna u otra forma han hecho posible la finalización de estos estudios. En primer lugar, me gustaría dar las gracias a mis padres ya que sin ellos nada de esto hubiera sido posible. Ellos siempre me han dado su cariño incondicional y me han enseñado a valorar y a disfrutar de todas las cosas buenas que nos regala la vida. También me gustaría agradecerles que hayan creído en mí dándome la oportunidad de estudiar esta carrera, realizando el esfuerzo que sé que han tenido que hacer para que esto sea posible. También, agradecer al resto de mis familiares su preocupación constante y todos los consejos que en algún momento me han dado. A mis compañeros de la universidad Javi, David, Cristian, Cesár, Lalio, Jesús, ... y compañeros de piso, Dani y Juanma, por haber compartido conmigo todas estas alegrías, desvelos, inquietudes y entusiasmo en estos cuatro años. Por eso, quiero darles las gracias por haberse convertido en unos amigos maravillosos y que espero conservar durante mucho tiempo. También querría darles las gracias a mis directores de proyecto, María José y Juan Carlos, sin los cuáles este proyecto no hubiera llegado nunca a su fin. Querría agradecer en especial a María José todo el apoyo y confianza que ha depositado en mi estos últimos meses y a las oportunidades que me ha dado. Gracias a ella han aumentado mis ganas de aprender y enriquecer mis formación. Gracias a todos aquellos que me han ayudado a conseguir la beca de investigación/colaboración del Departamento de Tecnologías y Sistemas de la Información otorgada por el Ministerio de Educación durante la cual he desarrollado este proyecto, en especial a María José. También querría agradecerles que me permitieran disfrutarla junto a los compañeros del grupo ARCO, gracias a los cuales he aprendido mucho. No puedo olvidar dar las gracias a Luís Jimenez Linares por habernos prestado la Kinect con la que se ha realizado el proyecto ni a David Villa Alises por haber facilitado la plantilla LATEX de este documento. Por último, tampoco puedo olvidar dar las gracias a mis amigos de toda la vida, por su apoyo y preocupación hacia mí y por todos los buenos ratos que hemos compartido. Rubén Cantarero Navarro IX A mis padres, por su apoyo incondicional. xi Índice general Resumen V Abstract VII Agradecimientos IX Índice general XIII Índice de cuadros XIX Índice de figuras XXI Índice de listados XXV Listado de acrónimos XXVII 1. Introducción 1 1.1. Estructura del documento . . . . . . . . . . . . . . . . . . . . . . . . . . . 2. Objetivos 4 5 2.1. Objetivo general . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.1.1. Objetivos específicos . . . . . . . . . . . . . . . . . . . . . . . . . 5 3. Objectives 9 3.1. General objective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.1.1. Specific objectives . . . . . . . . . . . . . . . . . . . . . . . . . . 9 4. Antecedentes 13 4.1. Kinect para Xbox 360 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 4.1.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 4.1.2. La creación de Kinect . . . . . . . . . . . . . . . . . . . . . . . . 14 4.1.2.1. Precedentes . . . . . . . . . . . . . . . . . . . . . . . . XIII 15 4.1.2.2. Evolución . . . . . . . . . . . . . . . . . . . . . . . . . 17 4.1.2.3. Homebrew de Kinect . . . . . . . . . . . . . . . . . . . 21 4.1.3. Desarrollo de aplicaciones alternativas . . . . . . . . . . . . . . . . 24 4.1.3.1. Ocio . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4.1.3.2. Medicina . . . . . . . . . . . . . . . . . . . . . . . . . . 27 4.1.3.3. Educación . . . . . . . . . . . . . . . . . . . . . . . . . 27 4.1.3.4. Accesibilidad . . . . . . . . . . . . . . . . . . . . . . . 28 4.1.4. Características técnicas . . . . . . . . . . . . . . . . . . . . . . . . 30 4.1.4.1. Segunda generación de Kinect . . . . . . . . . . . . . . 32 4.1.5. Ventajas de Kinect frente a otros dispositivos . . . . . . . . . . . . 34 4.1.6. Funcionamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 4.1.6.1. Cámara RGB . . . . . . . . . . . . . . . . . . . . . . . 34 4.1.6.2. Cámara profundidad . . . . . . . . . . . . . . . . . . . . 35 4.1.6.3. Sistema de micrófonos . . . . . . . . . . . . . . . . . . 37 4.1.6.4. Motor de inclinación . . . . . . . . . . . . . . . . . . . . 37 4.1.7. ¿Por qué Kinect? . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 4.1.8. Librerías Kinect . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 4.1.8.1. SDK Windows . . . . . . . . . . . . . . . . . . . . . . . 4.1.8.1.1. Descripción del SDK . . . . . . . . . . . . . . . . . . . . . . . . . 40 Evolución del framework . . . . . . . . . . . . . . . . . . . . . . . . . 45 Ventajas y desventajas . . . . . . . . . . . . . . . . . . . . . . . . . 46 OpenNI . . . . . . . . . . . . . . . . . . . . . . . . . . 47 4.1.8.1.2. 4.1.8.1.3. 4.1.8.2. 4.1.8.2.1. Descripción del framework . . . . . . . . . . . . . . . . . . . . . . . . . 48 Evolución del framework . . . . . . . . . . . . . . . . . . . . . . . . . 53 Ventajas y desventajas . . . . . . . . . . . . . . . . . . . . . . . . . 55 OpenKinect . . . . . . . . . . . . . . . . . . . . . . . . 56 4.1.8.2.2. 4.1.8.2.3. 4.1.8.3. 40 4.1.8.3.1. Descripción del framework . . . . . . . . . . . . . . . . . . . . . . . . . 56 Ventajas y desventajas . . . . . . . . . . . . . . . . . . . . . . . . . 57 4.2. Visión por computador . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 4.1.8.3.2. xiv 4.2.1. Perspectiva de visión por computador . . . . . . . . . . . . . . . . 59 4.2.2. Algoritmos de reconocimiento de acciones basados en vídeo . . . . 60 5. Método de trabajo 65 5.1. Metodología de trabajo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 5.1.1. Acerca de Scrum . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 5.1.1.1. Fases de Scrum . . . . . . . . . . . . . . . . . . . . . . 67 5.1.1.2. Roles y responsabilidades . . . . . . . . . . . . . . . . . 68 5.1.1.3. Prácticas y conceptos relevantes . . . . . . . . . . . . . . 69 5.1.2. Descripción de la planificación . . . . . . . . . . . . . . . . . . . . 71 5.1.2.1. Fase 1: Pre-game . . . . . . . . . . . . . . . . . . . . . 72 5.1.2.2. Fase 2: Development . . . . . . . . . . . . . . . . . . . 73 5.1.2.2.1. Iteración 0 . . . . . . . . . . . . . . . . . . . . . . . . . 73 Iteración 1 . . . . . . . . . . . . . . . . . . . . . . . . . 74 Iteración 2 . . . . . . . . . . . . . . . . . . . . . . . . . 75 Iteración 3 . . . . . . . . . . . . . . . . . . . . . . . . . 75 Iteración 4 . . . . . . . . . . . . . . . . . . . . . . . . . 76 Iteración 5 . . . . . . . . . . . . . . . . . . . . . . . . . 77 Fase 3: Post-game . . . . . . . . . . . . . . . . . . . . . 78 5.2. Herramientas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 5.2.1. Aplicaciones de desarrollo . . . . . . . . . . . . . . . . . . . . . . 78 5.2.2. Lenguajes de programación . . . . . . . . . . . . . . . . . . . . . 80 5.2.3. Documentación y gráficos . . . . . . . . . . . . . . . . . . . . . . 80 5.2.4. Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 5.2.5. Sistemas operativos . . . . . . . . . . . . . . . . . . . . . . . . . . 81 5.1.2.2.2. 5.1.2.2.3. 5.1.2.2.4. 5.1.2.2.5. 5.1.2.2.6. 5.1.2.3. 6. Desarrollo del proyecto 83 6.1. Iteración 1: Primeros pasos con Kinect . . . . . . . . . . . . . . . . . . . . 84 6.1.1. Primer programa con Kinect . . . . . . . . . . . . . . . . . . . . . 85 6.1.1.1. La reflexión . . . . . . . . . . . . . . . . . . . . . . . . 86 6.1.1.2. La oclusión . . . . . . . . . . . . . . . . . . . . . . . . 87 6.1.1.3. Desalineamiento entre cámaras . . . . . . . . . . . . . . 88 xv 6.1.2. Apreciaciones a nivel de píxel . . . . . . . . . . . . . . . . . . . . 88 6.1.2.1. Píxeles RGB . . . . . . . . . . . . . . . . . . . . . . . . 89 6.1.2.2. Píxeles de profundidad . . . . . . . . . . . . . . . . . . 90 6.1.3. Conversión a distancias reales . . . . . . . . . . . . . . . . . . . . 92 6.1.4. Trabajando en tres dimensiones . . . . . . . . . . . . . . . . . . . 94 6.1.4.1. Nube de puntos . . . . . . . . . . . . . . . . . . . . . . 96 6.1.5. Afianzando los conceptos adquiridos . . . . . . . . . . . . . . . . . 101 6.1.5.1. Dibujando con Kinect . . . . . . . . . . . . . . . . . . . 101 6.1.5.2. Álbum de fotos . . . . . . . . . . . . . . . . . . . . . . 102 6.1.5.3. Batería virtual . . . . . . . . . . . . . . . . . . . . . . . 103 6.2. Iteración 2: Comprendiendo el funcionamiento de O PEN NI . . . . . . . . . 105 6.2.1. Aspectos básicos sobre la librería . . . . . . . . . . . . . . . . . . 106 6.2.1.1. openni::OpenNI . . . . . . . . . . . . . . . . . . . . . . 6.2.1.1.1. 107 Acceso al dispositivo . . . . . . . . . . . . . . . . . . . . . . . . . 107 Acceso a los flujos de vídeo . . . . . . . . . . . . . . . . . . . . . . . . . 108 Acceso a los dispositivos a través de eventos . . . . . . . . . . . . . . . . . . . . . . . . . 108 Información de errores . . . . . . . . . . . . . . . . . . . . . . . . . 108 6.2.1.2. openni::Device . . . . . . . . . . . . . . . . . . . . . . . 109 6.2.1.3. openni::VideoStream . . . . . . . . . . . . . . . . . . . 110 6.2.1.4. openni::VideoFrameRef . . . . . . . . . . . . . . . . . . 110 6.2.2. GLUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 6.2.3. Primera versión del módulo de captura de imágenes . . . . . . . . . 113 6.3. Iteración 3: Incorporación de NiTE . . . . . . . . . . . . . . . . . . . . . . 114 6.3.1. Toma de contacto con NiTE . . . . . . . . . . . . . . . . . . . . . 116 6.2.1.1.2. 6.2.1.1.3. 6.2.1.1.4. 6.3.1.1. Seguimiento de manos y detección de gestos . . . . . . . 116 6.3.1.2. Seguimiento del cuerpo . . . . . . . . . . . . . . . . . . 118 6.3.1.2.1. Funcionamiento . . . . . . . . . . . . . . . . . . . . . . . . . 118 Análisis e interpretación de la información proporcionada . . . . . . . . . . . . . . . . . . . . . . . . . 118 6.3.2. Evolución del módulo de captura de imágenes . . . . . . . . . . . . 120 6.3.1.2.2. 6.3.2.1. Segunda versión . . . . . . . . . . . . . . . . . . . . . . xvi 121 6.3.2.2. Tercera versión . . . . . . . . . . . . . . . . . . . . . . 126 6.3.2.3. Cuarta versión . . . . . . . . . . . . . . . . . . . . . . . 129 6.4. Iteración 4: Módulo de reconocimiento de acciones . . . . . . . . . . . . . 133 6.4.1. Modelo Bag of Words . . . . . . . . . . . . . . . . . . . . . . . . 134 6.4.2. Implementación de la solución propuesta . . . . . . . . . . . . . . 138 6.4.2.1. Fase 1: Configuración inicial . . . . . . . . . . . . . . . 143 6.4.2.2. Fase 2: Segmentación de vídeos . . . . . . . . . . . . . . 144 6.4.2.3. Procesamiento . . . . . . . . . . . . . . . . . . . . . . . 147 6.4.2.3.1. Fase 3: Extracción de características . . . . . . . . . . . . . . . . . . . . . . . . . 148 Fase 4: Clustering . . . . . . . . . . . . . . . . . . . . . . . . . 152 Fase 5: Proceso de reconocimiento . . . . . . . . . . . . . . . . . . . . . . . . . 154 6.5. Iteración 5: Interfaz gráfica . . . . . . . . . . . . . . . . . . . . . . . . . . 159 6.4.2.3.2. 6.4.2.3.3. 7. Resultados 167 7.1. Dataset de entrenamiento empleado . . . . . . . . . . . . . . . . . . . . . 167 7.2. Recogida de datos de prueba . . . . . . . . . . . . . . . . . . . . . . . . . 168 7.3. Análisis de los resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 8. Conclusiones y trabajo futuro 181 8.1. Objetivos alcanzados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 8.2. Trabajo futuro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 9. Conclusions and future work 187 9.1. Achieved objectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 9.2. Future work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 A. Listados de los ejemplos con Processing 195 A.1. Ejemplo 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 A.2. Ejemplo 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 A.3. Primer ejemplo de nube de puntos . . . . . . . . . . . . . . . . . . . . . . 197 A.4. Primer ejemplo de nube de puntos con movimiento . . . . . . . . . . . . . 198 A.5. Primer ejemplo de nube de puntos a color . . . . . . . . . . . . . . . . . . 199 A.6. Dibujando con Kinect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 A.7. Álbum de fotos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 A.8. Batería musical . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 xvii B. Módulo de captura de imágenes 209 B.1. Diseño definitivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 B.1.1. Modelo de clases definitivo . . . . . . . . . . . . . . . . . . . . . . 209 B.1.2. Estructura de directorio definitivo . . . . . . . . . . . . . . . . . . 210 B.1.3. Modelo de flujo de la ejecución . . . . . . . . . . . . . . . . . . . 211 C. Formulario de consentimiento 213 D. Conclusión personal 219 Referencias 221 xviii Índice de cuadros 4.1. Especificación técnica Kinect. . . . . . . . . . . . . . . . . . . . . . . . . 31 4.2. Conjuntos de datos existentes, el número de categorías y el número de clips por categoría ordenados por año . . . . . . . . . . . . . . . . . . . . . . . 62 6.1. Resultados del tercer ejemplo con Processing. . . . . . . . . . . . . . . . . 95 6.2. Resultados obtenidos con ficheros PPM. . . . . . . . . . . . . . . . . . . . 130 6.3. Resultados obtenidos con ficheros JPEG. . . . . . . . . . . . . . . . . . . . 131 7.1. Información y número de acciones realizado por cada actor. . . . . . . . . . 170 7.2. Porcentaje de acierto de cada actor (sin guiar) en cada tipo de acción según el tipo de imagen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 7.3. Porcentaje de acierto de cada actor (guiado) en cada tipo de acción según el tipo de imagen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 7.4. Porcentaje de acierto de cada acción según el tipo de imagen (entorno guiado y sin guiar). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 7.5. Matriz de confusión de los vídeos RGB (entorno guiado y sin guiar). . . . . 176 7.6. Matriz de confusión de los vídeos de profundidad (entorno guiado y sin guiar).176 7.7. Matriz de confusión de los vídeos de los esqueletos (entorno guiado y sin guiar). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 7.8. Comparación de resultados con [MDRSN13]. . . . . . . . . . . . . . . . . 178 7.9. Comparación de resultados con [MDRSN13]. . . . . . . . . . . . . . . . . 178 XIX Índice de figuras 4.1. Kinect para Xbox 360 [web14n]. . . . . . . . . . . . . . . . . . . . . . . . 14 4.2. Wiimote para Wii [web14t]. . . . . . . . . . . . . . . . . . . . . . . . . . 15 4.3. PlayStation Move para PlayStation 3 [web14p]. . . . . . . . . . . . . . . . 15 4.4. Escena de “Minority Report” [web14s]. . . . . . . . . . . . . . . . . . . . 17 4.5. Disposición del dispositivo Wiimote [web14c]. . . . . . . . . . . . . . . . 18 4.6. Player blob [WA12]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.7. Player blob dividido en partes [WA12]. . . . . . . . . . . . . . . . . . . . 20 4.8. Johnny Lee mostrando las modificaciones al Wii Remote [web14f]. . . . . 22 4.9. Analizador de USB Beagle 480 [web14e]. . . . . . . . . . . . . . . . . . . 23 4.10. Kinect for Cooler Videoconferencing [web14q]. . . . . . . . . . . . . . . 24 4.11. Real-Time Princess Leia Holography Via Kinect Hack [web14x]. . . . . . 25 4.12. Ubi Interactive [wbU14]. . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4.13. Fitnect [web14b]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4.14. TedCas [wbT14a]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 4.15. VirtualRehab [wbV14]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 4.16. Juego River Corssing [web14i]. . . . . . . . . . . . . . . . . . . . . . . . 28 4.17. Kinect Math [web14l]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 4.18. Actividad “Baskets” integrada en la plataforma Jumpido [web14g]. . . . . 29 4.19. NAVI (Navigational Aids fot the Visually Impaired) [web14w]. . . . . . . 30 4.20. Kinect Sign Language Translator [web14r]. . . . . . . . . . . . . . . . . . 30 4.21. Distribución de los componentes en Kinect [web14k]. . . . . . . . . . . . 32 4.22. Distancia para el reconocimiento del esqueleto en Kinect [web14k]. . . . . 32 4.23. Segunda generación de Kinect [web14k]. . . . . . . . . . . . . . . . . . . 33 4.24. Componentes de un píxel. . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 4.25. Estructura del vector de bytes de la imagen. . . . . . . . . . . . . . . . . . 35 4.26. Fase de calibración del sistema de mapas de profundidad de la Kinect. . . . 36 4.27. Imagen de los puntos infrarrojos proyectados en una pared [Bor12]. . . . . 37 4.28. Fase de funcionamiento del sistema de mapas de profundidad de la Kinect. . 38 XXI 4.29. Disposición de los micrófonos en Kinect [web14k]. . . . . . . . . . . . . . 38 4.30. Arquitectura del SDK [web14j]. . . . . . . . . . . . . . . . . . . . . . . . 41 4.31. Interacción del hardware y software con una aplicación [web14j]. . . . . . 42 4.32. Articulaciones reconocidas por el SDK de Kinect [web14j]. . . . . . . . . . 43 4.33. Puntos del rostro humano reconocidos por el SDK de Microsoft [web14j]. . 43 4.34. Arquitectura de KinectInteraction [web14j]. . . . . . . . . . . . . . . . . . 44 4.35. Resultado obtenido a través de Kinect Fusion [web14j]. . . . . . . . . . . 44 4.36. Evolución del SDK de Kinect [WA12]. . . . . . . . . . . . . . . . . . . . . 46 4.37. AXUS Xtion [web14d]. . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 4.38. Arquitectura del framework O PEN NI 2 [web14u]. . . . . . . . . . . . . . . 49 4.39. Solución propuesta por Tomoto S. Washio [web14m]. . . . . . . . . . . . 51 4.40. 3D Hand [web14h]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 4.41. Resultado obtenido con KScan3D [web14a]. . . . . . . . . . . . . . . . . 53 4.42. Ejemplo de gesto reconocido con SigmaNIL [web14y]. . . . . . . . . . . . 54 4.43. Evolución de la arquitectura O PEN NI [web14u]. . . . . . . . . . . . . . . . 54 5.1. Fases de Scrum [web14z]. . . . . . . . . . . . . . . . . . . . . . . . . . . 68 5.2. Iteración de la metodología Scrum [web14z]. . . . . . . . . . . . . . . . . 70 6.1. Proyecto “MAY THE FORCE BE WITH YOU” de TeoPatk [wbT14b]. . . . 85 6.2. Captura del primer ejemplo con Processing. . . . . . . . . . . . . . . . . . 87 6.3. Scanner 3D con Kinect por Kyle McDonald [Bor12]. . . . . . . . . . . . . 87 6.4. Captura del segundo ejemplo con Processing. . . . . . . . . . . . . . . . . 88 6.5. Comparación entre los píxeles en una matriz bidimensional y una unidimensional [Bor12]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 6.6. Captura del tercer ejemplo con Processing. . . . . . . . . . . . . . . . . . . 95 6.7. Origen de coordenadas bidimensional en Processing [web14v]. . . . . . . 96 6.8. Origen de coordenadas tridimensional en Processing [web14v]. . . . . . . 97 6.9. Captura del primer ejemplo de “Nube de puntos”. . . . . . . . . . . . . . . 98 6.10. Captura del primer ejemplo de “Nube de puntos” donde sólo se representa uno de cada diez puntos capturados. . . . . . . . . . . . . . . . . . . . . . 98 6.11. Captura del primer ejemplo de “Nube de puntos” desde otro punto de vista. 99 6.12. Captura del primer ejemplo de “Nube de puntos” a color. . . . . . . . . . . 100 6.13. Captura de la aplicación “Dibujando con Kinect”. . . . . . . . . . . . . . . 102 6.14. Captura de la aplicación “Álbum de fotos”. . . . . . . . . . . . . . . . . . 103 6.15. Distribución de un cubo en Processing [Bor12]. . . . . . . . . . . . . . . . 105 6.16. Captura de la aplicación “Batería virtual”. . . . . . . . . . . . . . . . . . . 106 xxii 6.17. Diagrama de clases del módulo de captura de imágenes (versión 1). . . . . 114 6.18. Módulo de captura de imágenes en modo RGB. . . . . . . . . . . . . . . . 115 6.19. Módulo de captura de imágenes en modo profundidad. . . . . . . . . . . . 115 6.20. Funcionamiento del seguimiento de usuarios con NiTE [web14u]. . . . . . 119 6.21. Sistema de coordenadas de NiTE. . . . . . . . . . . . . . . . . . . . . . . 119 6.22. Articulaciones detectadas por NiTE [web14u]. . . . . . . . . . . . . . . . 121 6.23. Diagrama de clases del módulo de captura de imágenes (versión 2). . . . . 123 6.24. Resultado de la combinación de las técnicas de procesamiento. . . . . . . . 123 6.25. Resultado de la eliminación del fondo. . . . . . . . . . . . . . . . . . . . . 124 6.26. Dibujado del esqueleto sobre la imagen de profundidad. . . . . . . . . . . . 124 6.27. Dibujado del esqueleto eliminando el fondo. . . . . . . . . . . . . . . . . . 125 6.28. Imagen correspondiente al ejemplo 6.4. . . . . . . . . . . . . . . . . . . . 125 6.29. Estructura de directorios. . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 6.30. Modelo de flujo de la ejecución secuencial. . . . . . . . . . . . . . . . . . 128 6.31. Modelo de flujo de la ejecución concurrente. . . . . . . . . . . . . . . . . . 129 6.32. Gráfico comparativo del no de ficheros entre el formato PPM y JPEG. . . . . 131 6.33. Gráfico comparativo del tamaño total en megabytes entre el formato PPM y JPEG. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 6.34. Funcionalidad introducida en el módulo (versión 4). . . . . . . . . . . . . . 135 6.35. Imágenes originales. Extraídas de “Bag-of-words models” (S. Lazebnik, A. Torralba, L. Fei-Fei, D. Lowe, C. Szurka) y adaptadas por Rubén Cantarero Navarro. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 6.36. Extracción de características. Extraídas de “Bag-of-words models” (S. Lazebnik, A. Torralba, L. Fei-Fei, D. Lowe, C. Szurka) y adaptadas por Rubén Cantarero Navarro. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 6.37. Generación del diccionario (clustering). Extraídas de “Bag-of-words models” (S. Lazebnik, A. Torralba, L. Fei-Fei, D. Lowe, C. Szurka) y adaptadas por Rubén Cantarero Navarro. . . . . . . . . . . . . . . . . . . . . . . . . 137 6.38. Cuantificación de características. Extraídas de “Bag-of-words models” (S. Lazebnik, A. Torralba, L. Fei-Fei, D. Lowe, C. Szurka) y adaptadas por Rubén Cantarero Navarro. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 6.39. Clasificador SVM. Extraídas de “Bag-of-words models” (S. Lazebnik, A. Torralba, L. Fei-Fei, D. Lowe, C. Szurka) y adaptadas por Rubén Cantarero Navarro. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 6.40. Diagrama de flujo de la solución propuesta. . . . . . . . . . . . . . . . . . 140 6.41. Diagrama de flujo de según las etapas. . . . . . . . . . . . . . . . . . . . . 142 6.42. Módulos del sistema. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 6.43. Estructura de directorios de la solución propuesta. . . . . . . . . . . . . . . 145 xxiii 6.44. Diagrama de flujo de build_segmented_videos. . . . . . . . . . . . . . . . . 146 6.45. Fases de procesamiento. . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 6.46. Diagrama de la fase de extracción de características. . . . . . . . . . . . . . 150 6.47. Captura de stipdet de una imagen de profundidad capturada con Kinect. . . 151 6.48. Diagrama de new_sequence_cluster_choice_k . . . . . . . . . . . . . . . . 154 6.49. Diagrama de la fase de proceso de reconocimiento. . . . . . . . . . . . . . 163 6.50. Funcionalidad de Grabación. . . . . . . . . . . . . . . . . . . . . . . . . . 164 6.51. Funcionalidad de etiquetado. . . . . . . . . . . . . . . . . . . . . . . . . . 164 6.52. Sección de clasificación. . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 6.53. Sección de Resultados. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 7.1. Ejemplo de IXMAS. [wbI14] . . . . . . . . . . . . . . . . . . . . . . . . . 169 7.2. Escenario de grabación empleado. . . . . . . . . . . . . . . . . . . . . . . 170 7.3. Porcentaje de acierto de cada acción según el tipo de imagen (entorno guiado y sin guiar). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 7.4. Problema encontrado en vídeos de profundidad. . . . . . . . . . . . . . . . 179 7.5. Problema encontrado en vídeos de esqueletos. . . . . . . . . . . . . . . . . 179 B.1. Diagrama de clases. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 B.2. Estructura de directorios. . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 B.3. Modelo de flujo de la ejecución concurrente. . . . . . . . . . . . . . . . . . 211 xxiv Índice de listados 6.1. «Ejemplo 1» versión 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 6.2. «Dibujando con Kinect» . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 6.3. Detección de poses con NiTE . . . . . . . . . . . . . . . . . . . . . . . . . 117 6.4. Ejemplo del formato PPM. . . . . . . . . . . . . . . . . . . . . . . . . . . 126 6.5. Estructura fichero XML. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 6.6. Estructura fichero ACTOR_frame_segmented.txt. . . . . . . . . . . . . . . 145 6.7. Estructura fichero de datos del clasificador SVM. . . . . . . . . . . . . . . 156 6.8. Ejemplo de la estructura fichero de datos del clasificador SVM. . . . . . . . 157 A.1. «Ejemplo 1» [Bor12] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 A.2. «Ejemplo 2» [Bor12] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 A.3. «Primer ejemplo Nube de puntos» [Bor12] . . . . . . . . . . . . . . . . . 197 A.4. «Primer ejemplo Nube de puntos con movimiento» [Bor12] . . . . . . . . 198 A.5. «Primer ejemplo Nube de puntos a color» [Bor12] . . . . . . . . . . . . . 199 A.6. «Dibujando con Kinect» [Bor12] . . . . . . . . . . . . . . . . . . . . . . 200 A.7. «Álbum de fotos» [Bor12] . . . . . . . . . . . . . . . . . . . . . . . . . . 202 A.8. Clase Hotpoint de la aplicación «Batería musical» [Bor12] . . . . . . . . . 204 A.9. Clase principal de la aplicación «Batería musical» [Bor12] . . . . . . . . . 205 XXV Listado de acrónimos KinBehR KINect for human BEHaviour Recognition BSD Berkeley Software Distribution MSR Microsoft Research SDK Software Development Kit NAVI Navigational Aids fot the Visually Impaired TOF Time-Of-Flight TFG Trabajo Fin de Grado HMM Hidden Markov Models GMM Modelos de Mezclas Gaussianas IEEE Institute of Electrical and Electronics Engineers AVSS Advanced Video and Signal Based Surveillance MHI Motion History Images SOM Kohonen Self Organizing feature Map SIR Sampling Importance Resampling ML Maximum Likelihood SVM Support Vector Machines BoW Bag of Words CLG Combined Local-Global LPP Locality Preserving Projections TVTL Temporal-Vector Trajectory Learning LTM Locations’ Temporal motion of Mahalanobis distance DTM Difference’ Temporal motion of Mahalanobis distance TTM Trajectory Temporal motion of Mahalanobis distance IN Internación Natural API Application Programming Interface LGPL Lesser General Public License XXVII OpenNI Open Natural Interaction 3D Tres dimensiones IDE Integrated Development Environment CPU Central Processing Unit FORTH Foundation for Research and Technology-Hellas DMO DirectX Media Objec USB Universal Serial Bus NUI Natural User Interface RAM Random Access Memory HTML HyperText Markup Language GPL General Public License JNA Java Native Access JNI Java Native Interface GLUT OpenGL Utility Toolkit ANSI American National Standards Institute FORTRAN Formula Translating System PPM Portable PixMap format PGM Portable Gray Map ASCII American Standard Code for Information Interchange POSIX Portable Operating System Interface JPEG Joint Photographic Experts Group XML eXtensible Markup Language IXMAS INRIA Xmas Motion Acquisition Sequences PERL Practical Extraction and Report Language GUI Graphical User Interface INRIA Institut National de Recherche en Informatique et en Automatique STIP Space-time Interest Points HOF Histograms of Optical Flow HOG Histograms of Oriented Gradients LUT Look Up Table KDE K Desktop Environment GCC GNU Compiler Collection GNU GNU is Not Unix xxviii Capítulo 1 Introducción La búsqueda de espacios cada vez más inteligentes en los que el propio entorno dé soporte a personas de la tercera edad (Ambient Assited Living), personas en su vida cotidiana (Ambient Intelligence) o ciudadanos (Smart Cities) plantea, como primer reto, el desarrollo de tecnologías o sistemas capaces de identificar las acciones que estas personas están llevando a cabo en ese entorno. El reconocimiento de acciones humanas es, sin embargo, uno de los principales retos de la comunidad científica y muy especialmente en el área de la visión por computador. En este sentido, la aproximación más común consiste en extraer imágenes características de vídeos y caracterizar y etiquetar estas imágenes con la correspondiente acción que se está realizando en ellas. Para ello se suele recurrir a un algoritmo de clasificación previamente entrenado con las acciones a reconocer. Sin embargo, el enfoque basado en vídeo no es el único. Así, en el estado del arte podemos identificar diferentes propuestas que van desde las más intrusivas, como las basadas en sensores desplegados a lo largo del cuerpo [XZSS12] hasta otras como las basadas en el análisis de los valores obtenidos por los sensores de los teléfonos móviles [AGO+ 12]. Pero, independientemente del enfoque aplicado, la realidad es que el reconocimiento de acciones humanas es una tarea tremendamente compleja. Esa complejidad, en el caso particular del reconocimiento de acciones humanas basadas en el análisis de vídeo, se deriva de los diferentes retos que esta tarea debe abordar. En primer lugar hay que hacer frente a la importante variabilidad en el rendimiento obtenido en el reconocimiento de distintas acciones. Un ejemplo de ello podría ser como en los movimientos que implica el caminar, las zancadas de cada persona pueden diferir en gran medida. Esto se debe a que los movimientos corporales implicados en una determinada acción no son únicos y no están perfectamente delimitados, variando de unas personas a otras e incluso dentro de la misma persona. Esto supone un gran desafío ya que una buena aproximación para el reconocimiento de acciones debería ser capaz de generalizar sobre las variaciones dentro de una clase y distinguir entre las acciones de diferentes clases. De este modo, cuando exista un gran número de las clases de acción, esto será aún más complicado ya que el solapamiento entre las clases será mayor. 1 Otro reto que debe ser tenido en cuenta es la naturaleza cambiante del entorno donde se producen las acciones. Esto implica serias dificultades en diferentes aspectos que deben ser considerados. Ejemplos de ellos podrían ser cómo partes de una persona pueden ser ocluidas en las grabaciones o la influencia que pueden tener las condiciones de luminosidad en la apariencia de una persona. No obstante, esta tarea también se encuentra con el reto que suponen las variaciones temporales. Por consiguiente, la velocidad a la que se registra la acción tiene un efecto importante en la extensión temporal de una acción, especialmente cuando se utilizan funciones de movimiento. Un algoritmo de reconocimiento robusto de acciones humanas debería ser invariante a diferentes ritmos de ejecución. Recientemente, algunos investigadores han utilizado cámaras RGBD, como Microsoft Kinect, para intentar abordar los retos mencionados arriba. Estas cámaras de profundidad añaden una dimensión extra que las cámaras 2D normales no proporcionan. De este modo, la información sensorial proporcionada por este tipo de cámaras se han empleado para generar modelos del esqueleto humano en tiempo real que permiten considerar las diferentes posiciones del cuerpo. Estos modelos del esqueleto proporciona información significativa que los investigadores han usado para modelar las actividades humanas que han sido usadas en el entrenamiento del algoritmo de clasificación y que posteriormente serán empleadas para el reconocimiento de actividades desconocidas. Este trabajo está motivado por la necesidad de abordar el problema de cómo las posturas corporales inciden en la tarea de reconocimiento de acciones humanas basadas en el análisis de vídeo. De este modo se parte de la hipótesis de trabajo de que el uso de cámaras de profundidad puede ayudar a mejorar las tasas de reconocimiento de acciones humanas en las que los movimientos corporales no han sido predefinidos, sino que dependerán de la persona que los realice. Este trabajo está inspirado en el trabajo de [NLT+ 11] en el que se presenta un análisis entre diferentes técnicas para abordar la tarea del reconocimiento de acciones, demostrando que la técnica que ofrece el mayor equilibrio tiempo/rendimiento es la técnica de Bag of Words (B OW) con una precisión del 63.9 %. El modelo B OW surgió como una aproximación motivada en métodos de categorización de texto [Joa98b] [TK02] [LSST+ 02] [CSTL02]. No obstante, se han publicado estudios [ZRZ02] en los que la idea de adaptar la categorización de texto a la categorización de vídeo puede resultar verdaderamente interesante. Es por ello por lo que en los últimos años se ha demostrado que B OW [KB10] [LAS08] [LP07] es uno de los métodos más precisos para el reconocimiento de acciones, capaz de actuar en una gran variedad de escenarios con un coste computacional realmente bajo. Al contrario de lo que sucede con otras técnicas de clasificación de acciones humanas [WBR07] [YKS08], B OW no requiere ningún algoritmo adicional de segmentación, lo que simplifica la tarea de visión por computador haciendo, por lo tanto, posible trabajar directamente con datos de vídeo. Utilizando la metodología propuesta en [MDRSN13], en la que también se abordaba el 2 problema del reconocimiento de acciones humanas realizadas de manera multimodal, este proyecto trabajará con un sistema entrenado con un conjunto de datos (dataset) distinto del utilizado en la clasificación, comprobando de esta manera la robustez del sistema ante la multimodalidad en la realización de acciones. Aunque el citado trabajo presentaba un sistema combinado de BoW y un algoritmo de razonamiento, en él se proporcionan resultados del rendimiento obtenido por el algoritmo BoW, entrenado con un conjunto de datos diferente al utilizado en la clasificación. Este trabajo utilizará esos datos para compararlos con los obtenidos en un experimento similar, utilizando cámaras de profundidad en lugar de cámaras 2D. Dado que no hay vídeos estándar adecuados para la descripción de la complejidad de las acciones de la vida real con un conjunto de actividades complejas que sean lo suficientemente representativas, se procederá a la creación de un nuevo dataset, “KinbehrDataset”. “KinbehrDataset” estará compuesto por acciones realizadas por diversos individuos en un entorno no controlado. Para la creación de dicho dataset se empleará un método científico de recogida de datos que asegure la validez de las muestras recogidas. Además, es importante mencionar que será puesto a disposición del resto de la comunidad científica con el fin de que lo resultados obtenidos en el presente estudio puedan ser comparados con futuros proyectos. De este modo, se emplearán dataset distintos para el entrenamiento y evaluación del sistema propuesto. Esto permitirá mostrar la generalidad de la solución, sus capacidades en las diversas aplicaciones de la vida real y su rendimiento en situaciones complejas. Por tratarse éste de un proyecto con alto contenido de investigación, la elaboración de este trabajo seguirá la siguiente metodología. En primer lugar se realizará un análisis de las diferentes cámaras de profundidad que se encuentran disponibles en el mercado, teniendo en cuenta diferentes aspectos como el precio, disponibilidad, prestaciones, soporte, etc. Es importante destacar que debido a limitaciones presupuestarias y al bajo precio que ofrece, este análisis estará limitado a los diferentes modelos del dispositivo Kinect de Microsoft. Seguidamente se trataran los conceptos más relevantes a tener en cuenta en el tratamiento, procesamiento e interpretación de las diferentes imágenes proporcionadas por el dispositivo elegido. El siguiente paso a abordar será el desarrollo de un módulo que permita capturar los diferentes flujos de información proporcionados por los sensores del dispositivo. Para ello, será necesario seguir una serie de pasos bien definidos, entre los cuales destacan la realización de un estudio de los frameworks disponibles para el dispositivo elegido, analizar las peculiaridades que presenta, etc. Seguidamente se procederá a adaptar la solución propuesta al modelo B OW. Para ello, se dividirá este proceso en dos etapas bien diferenciadas. La primera consistirá en el entrenamiento del sistema con un dataset público que se adapte a los objetivos perseguidos. De este modo, se realizará un estudio sobre los diferentes dataset disponibles. Posteriormente, se llevará a cabo la segunda etapa que consistirá en la evaluación del sistema mediante el dataset 3 “KinbehrDataset”, constituido a partir de grabaciones con diferentes flujos de información (imagen a color, profundidad, etc.) de cada individuo. Finalmente, se procederá a la validación e interpretación de los resultados obtenidos pudiendo comprobar si la hipótesis de trabajo con la que se comenzó se cumple. 1.1 Estructura del documento El presente documento se estructura en siete capítulos bien diferenciados. El primero de ellos, donde el lector se encuentra en este momento, se ha mostrado una visión general sobre la hipótesis de trabajo desde la que se parte y así como la forma en la que se pretende abordar. En el capítulo de “Objetivos” se presenta el objetivo general y los distintos objetivos específicos que se persiguen con la realización del TFG. En el capítulo de “Antecedentes” se pretende ofrecer al lector una visión detallada sobre el dispositivo Kinect y el estado del arte de la visión por computador. El siguiente capítulo, “Método de trabajo”, versa sobre la metodología de desarrollo empleada, la planificación del proyecto y las diferentes herramientas empleadas para su realización. Seguidamente, en el capítulo “Desarrollo del proyecto”, que constituye el núcleo del documento, se expone el trabajo realizado en las diferentes iteraciones en las que se ha dividido el proyecto. En los dos últimos capítulos, “Resultados” y “Conclusiones y trabajo futuro”, finalmente se exponen los resultados obtenidos en base a la hipótesis de trabajo de la que se partió y se analiza en que grado han sido logrados los objetivos, respectivamente. 4 Capítulo 2 Objetivos E este capítulo se detallan los objetivos del proyecto, tanto generales como específicos. De esta manera, se pretende dar a conocer al lector el alcance al que se pretende llegar con la realización del mismo. N 2.1 Objetivo general En este proyecto se ha desarrollado un algoritmo de “aprendizaje máquina” (machine learning) que combina el análisis de imágenes de intensidad y profundidad con una base de conocimiento donde se contenga información de alto nivel sobre acciones humanas. El sistema de reconocimiento estará basado en un clasificador de máquina de vectores de soporte o Support Vector Machines (SVM) para lo cual será necesario disponer de una batería de casos de entrenamiento y otra de testeo. Se realizará una revisión del estado del arte para identificar la existencia de dataset públicos que puedan servir para entrenar al sistema. Sin embargo, el sistema a desarrollar no se basará en el reconocimiento de acciones aisladas, sino que buscará interpretar y entender la actividad de más alto nivel que está siendo desarrollada por la persona para mitigar así los errores de reconocimiento de acciones que carecen de sentido en el contexto actual y que son reportadas por el sistema. Para ello, será necesario generar un dataset en el que se pueda asegurar que las personas están realizando las acciones con las que se ha entrenado el sistema pero de una manera racional, es decir, motivada por un objetivo concreto. Por lo tanto, también será objetivo de este proyecto la generación de dicho dataset a partir de la grabación y etiquetado de escenarios concretos, donde se realice al menos un número relevante de las acciones con las que el sistema haya sido entrenado. Dichas acciones dependerán de las acciones disponibles en los datasets públicos ya que, utilizando un dataset para entrenar el sistema distinto del utilizado para su evaluación, se asegurará la validez del sistema propuesto. 2.1.1 Objetivos específicos En este apartado se mostrarán los distintos objetivos específicos que han sido marcados para el desarrollo de K IN B EH R. Evaluación de mercado: Realizar una análisis exhaustivo sobre los diversos dispositi5 vos Kinect disponibles (Kinect for Xbox 360, Kinect for Windows y Kinect de segunda generación) y estudiar qué dispositivo es el que mejor se adapta para el desarrollo de la actividad del proyecto. Así mismo también se pretende proporcionar una visión general sobre la evolución que han experimentado este tipo de dispositivos a lo largo de la historia, haciendo especial inca pie en los cambios más importantes de los últimos años. Análisis de librerías disponibles: Realizar un estudio sobre las diferentes plataformas y/o librerías disponibles que actualmente proporcionan soporte a Kinect, identificando y evaluando de esta manera qué funcionalidades ofrecen, lenguajes de programación soportados por cada uno/a, limitaciones, ventajas y desventajas, compatibilidad, etc. También se pretende ofrecer una visón general sobre la evolución que han experimentado en los últimos años prestando especial interés en las nuevas posibilidades que frece cada una. Identificación y análisis de los datos recogidos por el dispositivo: Identificar los flujos de información proporcionados por los diferentes sensores de Kinect (profundidad, sonido, acelerómetro, etc.) y analizar las diversas formas de interpretarlos, manipularlos y procesarlos para su posterior explotación. De esta forma será necesario familiarizarse y comprender los conceptos más importantes relacionados con las imágenes (especialmente con las imágenes de profundidad). Posteriormente, esto proporcionará la base sobre la que se desarrollará un módulo que permita la captura de imágenes mediante el dispositivo Kinect, intentando en todo momento exprimir al máximo las posibilidades que ofrece y que son de especial interés para el presente proyecto. Identificación y análisis del conjunto de acciones a reconocer: Una vez identificados los datos recogidos por el dispositivo es necesario identificar las diferentes acciones que se van a reconocer y monitorizarlos para, posteriormente, llevar a cabo un análisis de los patrones que caracterizan a cada uno. Esto proporcionará la base para el reconocimiento de dichos patrones por el sistema a desarrollar. Adaptación del modelo Bag of Words: Realizar un pequeño estudio para proporcionar una visión general acerca del estado del arte sobre las soluciones existentes. También será necesario analizar y comprender en profundidad los conceptos más importantes acerca del funcionamiento del modelo Bag of Words (B OW), así como la forma en la que se puede adaptar la solución proporcionada al presente proyecto. Por lo tanto, la consecución de este subobjetivo será clave para la implementación de un módulo que, junto a un clasificador, permita la identificación de acciones. Desarrollo de un clasificador (SVM): Para ello será necesario investigar, analizar y diseñar las diferentes técnicas de clasificación para el reconocimiento de patrones de gestos corporales que se pretenden monitorizar. Una vez realizado este primer paso, se procederá a la implementación del/de los clasificador/es, el entrenamiento y evaluación 6 del mismo. Organización del conjunto de sujetos del experimento: A través de un método científico de recogida de datos se pretende confeccionar un conjunto de datos (ejemplos de entrenamiento o muestras) de diferentes individuos. Esto servirá como base para el etiquetado de las clases y el entrenamiento del clasificador SVM, teniendo como objetivo final la construcción de un modelo que permita predecir la clase de una nueva muestra. Asociado a esta tarea, también será necesario la interpretación de la legislación vigente para la elaboración de acuerdos con los individuos de manera que todo el procedimiento sea conforme a la legislación vigente respecto de la protección de datos de carácter personal. Desarrollo de una interfaz gráfica: Mediante el desarrollo de una interfaz gráfica se pretende integrar los diferentes módulos desarrollados a lo largo del proyecto, así como facilitar a los futuros usuarios del sistema su utilización. 7 Capítulo 3 Objectives This chapter describes the project objectives, both from a general and more specific perspective, therefore stating the project scope and the expected results. 3.1 General objective In this project we have developed a machine learning system that combines intensity and in-depth image analysis with a knowledge base containing high level information about human actions. The recognition system will be based on a support vector machine classifier, so-called Support Vector Machines (SVM). This classifier will be trained with a specific dataset specifically recorded for human action recognition. A review of the state of the art will be performed to identify the existence of public dataset that can be used for the system training. However, the system to be developed will not be based on the recognition of isolated actions. On the contrary, it will seek the interpretation and understanding of higher abstraction level actions. Performing in-context human action recognition enables the recognition system to mitigate the impact of recognition errors, reported by the system but making no sense from the point of view of the context in which the actions are taking place. In order to take the context into account, it will be necessary to generate a dataset in which it can be assumed that people are performing the actions with which the system has been trained but in a rational way. The main implication of assuming the rationality of the actions being performed is that they are motivated by a concrete objective. In this sense, it is also among the project objectives to generate a dataset where actions are performed in a rational manner, rather than being based on commands. This requires recording and labelling specific scenarios where actors perform a significant number of actions with which the system has been trained. These actions will depend on the ones being provided by the available public datasets. However, it is important to highlight that the dataset used for training is different from the one being used for testing and validating the implemented system. 3.1.1 Specific objectives In this section the specific objectives stated for the development of K IN B EH R are displayed. Market analysis: to undertake a market analysis of the different Kinect devices avai9 lable in the market (Kinect for Xbox 360, Kinect and Kinect for Windows second generation) and, among existing ones, to consider which one better fits this project requirements. This market analysis is also intended to provide an overview of the evolution that have experienced such devices throughout history, making special emphasis in recent years changes. Analysis of available libraries: to conduct a study of the different platforms and/or available libraries currently providing support for Kinect, by identifying and evaluating offered features, programming languages, limitations, advantages and disadvantages, compatibility, etc. It also aims to provide an overview of the evolution experienced in recent years with special attention to the new offered functionality. Identification and analysis of the device collected data: to identify the information flows provided by Kinect sensors (in-depth, sound, accelerometer, etc.) and to analyze the different ways of interpreting, manipulating and processing these values for later manipulations. This objective involve getting familiar and understanding the most important concepts related to images (especially in-depth images). Later, this will provide the basis on which a module that allows image capture using the Kinect device, trying to squeeze the most of of the possibilities offered and that are of special relevance to this project will be developed. Identification and analysis of the set of actions to be considered: once collected data has been identified by the device it is necessary to state the different actions that will be considered in the proposed system by performing an action characterisation. This will provide the basis for the recognition of these patterns by the system to be developed. Adapting the Bag of Words Model: to carry out a thorough analysis of the state of the art solutions for human action recognition. It will also be necessary to analyze and understand the most important concepts about the B OW model basis, and how this model has to be adapted in order to be implemented in the proposed system. Therefore, achieving this sub-goal will be key to the implementation of a module, along with a classifier, enabling action identification. An (SVM) classifier development: before selecting a specific approach a previous research and analysis have to be carried out in order to identify the different classification techniques for pattern recognition of body gestures. This goal also involve the implementation and training of the classifier as well as its performance validation. Selecting and organising the set of experimental subjects: since the system validation is going to be performed using a different dataset than the one used for training purposes, this objective requires the implementation of a scientific method for data collection. This objective will therefore result in a new dataset used for testing or validating purposes. This will serve as the basis for labelling classes and training the 10 classifier SVM, with the ultimate goal of building a model to predict the class of a new sample. Closely related to this task is the interpretation of existing legislation for consent agreements so that the whole procedure compliant with current legislation regarding personal data protection. Developing a graphical user interface: the development of a graphical user interface is intended to integrate the different modules developed during this project as well as to simplify the use of the system potential users. 11 Capítulo 4 Antecedentes E presente capítulo tiene como objetivo proporcionar una visión general sobre los conceptos más importantes tratados en este proyecto. Para ello, se ha comenzado hablando sobre Kinect, revisando cuestiones interesantes como su historia y evolución, aplicaciones de Kinect en el mundo real, las prestaciones técnicas que ofrece, las diferentes librerías que hay disponibles para desarrollar con Kinect; las diferentes versiones del dispositivo así como los conceptos más básicos sobre su funcionamiento y que más adelante serán necesarios para entender el resto del documento. L En la segunda parte del capítulo se ofrece una visión general sobre el estado actual de la cuestión de visión por computador, centrándose en los trabajos realizados en los últimos años, así como los algoritmos de reconocimiento de acciones más conocidos hasta el momento. 4.1 Kinect para Xbox 360 En la siguiente sección se proporcionarán algunos antecedentes acerca de dónde proviene Kinect Xbox 360 y cual ha sido su evolución a lo largo de los años, así como la forma en la que funciona el dispositivo y las ventajas y desventajas que ofrece para el diseño y desarrollo de sistemas de visión por computador. 4.1.1 Introducción Kinect para Xbox 360 (ver Figura 4.1), a partir de ahora Kinect, es «un controlador de juego libre y entretenimiento» creado por Alex Kipman y desarrollado por Microsoft para la videoconsola Xbox 360 y desde junio del 2011 para PC mediante Windows. Basado en una cámara web y pensado como un periférico para ambas plataformas, permite a los usuarios, por ejemplo, controlar e interactuar con la consola Xbox 360 sin necesidad de tener ningún contacto físico con un controlador de videojuegos tradicional, como pueden ser los mandos o joysticks. Todo ello se realiza a través de una interfaz de usuario natural usando gestos y comandos de voz. En un principio, el proyecto de Kinect estaba orientado a ampliar la audiencia de la Xbox 360 más allá de la base de un jugador típico. A continuación, se muestra uno de los comen13 Figura 4.1: Kinect para Xbox 360 [web14n]. tarios más destacados que fue realizado por Los Angeles Times el 1 de Junio de 2009 tras asistir al Electronic Entertainment Expo en Los Ángeles: “Microsoft wants people to start using their full bodies to play video games. The Redmond software giant showed off a sensor-based technology that recognizes faces, voices and body joints to affect the movements on screen. In a demo game called Ricochet, players can use their arms, legs, torso and head to block an onslaught of virtual projectiles. Another game called Paint Party lets users splash virtual paint onto an on-screen canvas. Players call out different colors to change the palette. The effort aims to attract a broader audience to Microsoft’s console. Most of the 30 million Xbox 360s sold since November 2005 has been snapped up by avid young males drawn to complex shooter or adventure games such as Halo and Gears of War”. No obstante, Kinect también fue lanzado al mercado con el objetivo de proporcionar una interfaz de usuario que de forma natural fuera capaz de reconocer gestos, comandos de voz, etc. para hacer frente a los sistemas de la competencia, como Wiimote con Wii MotionPlus (ver Figura 4.2) y PlayStation Move (ver Figura 4.3), que también permitían controlar el movimiento de las consolas Wii y PlayStation 3, respectivamente. 4.1.2 La creación de Kinect Los antecedentes de Kinect comienzan mucho antes de que el propio dispositivo fuera concebido. Kinect surge como el resultado de varias décadas de análisis e investigación sobre interfaces de usuario basadas en gestos y voz. Quizá el gran éxito que cosechó la película Minority Report en el año 2002, con su forma de interpretar una interfaz de usuario natural sin necesidad de emplear controladores, fue unos de los hechos que provocó la gran avalancha de avances que se sucederían en los años venideros. Posteriormente, como se comentó 14 Figura 4.2: Wiimote para Wii [web14t]. Figura 4.3: PlayStation Move para PlayStation 3 [web14p]. en el párrafo anterior, la rivalidad entre las consolas de videojuegos para diseñar controladores naturales de calidad fue lo que terminó provocando la llegada de este dispositivo a los salones de todo el mundo. No obstante, fue la filosofía de intentar desbloquear todo aquello que es ocultado lo que definitivamente permitió abrir las puertas a los desarrolladores. 4.1.2.1. Precedentes Una de las personas más influyentes en la interacción persona-computador, Bill Buxton, ha comentado en numerosas ocasiones durante los últimos años sobre lo que el llama “The Long Nose of Innovation”, en referencia al término acuñado por el director de la revista Wired, Chris Anderson: “The Long Nose”. Este término hace referencia a las décadas de trabajo necesario para desarrollar una tecnología “revolucionaria” que surge, de forma aparente, de 15 la nada. Uno de los ejemplos más destacables es la invención del ratón, que supuso una importante revolución en la interfaz gráfica de usuario tras largos años de perfeccionamiento. El primer ratón fue construido por Douglas Engelbart y Bill English en el Stanford Research Institute en 1963. No obstante, no fue hasta 1995 con el lanzamiento de la versión del sistema operativo Windows 95 cuando el ratón se convirtió en un periférico indispensable para todo el mundo. The Long Nose describe los 30 años necesarios para que dispositivos como el ratón pasen de ser una invención a ser omnipresentes en la industria Algo muy similar a este estudio de 30 años descrito por The Long Nose puede ser aplicado al proceso de invención y desarrollo de Kinect. Chris Schmandt en el Architectural Machine Group del MIT comenzó a finales de los años 70 un proyecto de investigación llamado “Put-That-Here”, basado en una idea de Richard Bolt de reconocimiento combinado de voz y gesto como vectores de entrada de un interfaz gráfica. Este proyecto estaba acoplado en una habitación con una gran pantalla de proyección, donde el usuario debía sentarse en una silla de vinilo a una distancia aproximada de ocho metros frente a la pantalla. Además disponía de un pequeño dispositivo magnético que se encontraba oculto en una muñeca que realizaba las labores de receptor del movimiento espacial que se produjera, además de un micrófono instalado en la cabeza. De este modo, gracias a estos “dispositivos” y mediante procesos de lógica elementales de reconocimiento de pronombres como “aquí” o “eso”, el usuario era capaz de crear y mover formas de manera muy básica en la pantalla. Versiones posteriores este proyecto permitían a los usuarios guiar a barcos a través del mar Caribe o colocar edificios coloniales en el mapa de Boston. En el año 1993, David Koonz, Thorrison Kristinn, y Carlton Sparrell llevaron a cabo en el MIT Media Labs otro proyecto de investigación dirigido por Bolt: “The Iconic System”. En dicho proyecto se continuo la idea del proyecto Put-That-Here realizado anteriormente con el objetivo de que en dicha ocasión fuera posible trabajar con gestos, palabras y el movimiento del ojo. Otra novedad fue que en esta ocasión los resultados eran proyectados en un espacio de tres dimensiones generada mediante un ordenador. Además, en lugar de los cubos magnéticos utilizados con Put-That-Here, The Iconic System utilizaba un sistema de guantes especiales para facilitar el seguimiento de los gestos de usuario. Marcos Lucente desarrolló a finales de los 90 una interfaz de usuario avanzada para IBM Research: “DreamSpace”. No obstante, esta interfaz llegó a estar operativa en una gran variedad de plataformas incluyendo Windows NT. Una de las principales características que la diferenciaban de sus predecesores era que DreamSpace no empleaba tubos ni guantes para llevar a cabo el reconocimiento de gestos, empleando por lo tanto un sistema de visión. Esta variante fue concebida para trabajar más allá de entornos especializados, suponiendo por lo tanto una alternativa viable al ratón y al teclado. 16 En 1999, John Underkoffler el cual era por aquel entonces miembro del MIT Media Labs participó en un nuevo proyecto de Stephen Spielberg: “Minority Report“ (ver Figura 4.4). De este modo, Jhon junto con Alex McDowell, Diseñador de Producción, diseñaron la interfaz de usuario que Tom Cruise utilizaría en la película. Algunos de los conceptos de diseño de la interfaz de usuario de Minority Report finalmente terminaron en otro proyecto de Underkoffler llamado ”G-Speak“. Figura 4.4: Escena de “Minority Report” [web14s]. 4.1.2.2. Evolución Nintendo fue la compañía que dio el primer paso hacía un nuevo paradigma de entender los videojuegos y de cómo el usuario puede interaccionar con la consola. En el Tokyo Game Show de 2005, la presentación de su nueva consola Wii fue acompañada por un nuevo dispositivo de juego llamado Wiimote (ver Figura 4.5). De manera similar en la que trabajaba el proyecto Put-That-There (véase § 4.1.2.1) con sus cubos magnéticos, el controlador de Wii era capaz de detectar el movimiento que se produjera a lo largo de los tres ejes, contando además con un sensor óptico que recogía el lugar donde apuntara el dispositivo, todo ello de forma inalámbrica. Peter Moore, el entonces jefe de la división Xbox de Microsoft, tras comprobar el éxito que cosechó Nintendo con Wiimote decidió comenzar a desarrollar una alternativa que fuera capaz de hacer frente a Nintendo. Para ello, Microsoft decidió crear dos equipos que compitieran para lograr desbancar a Nintendo: Uno trabajaría con la tecnología que PrimeSense tenía desarrollada ya para aquel entonces, mientras que el otro equipo partiría de la tecnología desarrollada por la compañía 3DV. A pesar de que el objetivo marcado inicialmente era el de presentar alguna novedad en el E3 de 2007, ninguno de los equipos que fueron compuestos había conseguido ningún resultado que mereciera la pena presentar en la convención. Tras la salida de Peter Moore de Microsoft, Don Matrick se hizo cargo de continuar en 17 Figura 4.5: Disposición del dispositivo Wiimote [web14c]. 2008 el proyecto, hasta ahora secreto, de reconocimiento de vídeo a partir de la tecnología de PrimeSense. A pesar de que la tecnología 3DV con la que trabajó uno de los equipos confeccionados inicialmente no obtuvo los resultados esperados, Microsoft decidió comprar la compañía en 2009 por 35 millones de dólares con el fin último de evitar futuros problemas de patentes en torno a Kinect. Posteriormente, Alex Kipman fue ascendido a director general de proyectos de incubación y puesto al cargo de desarrollar un nuevo dispositivo que incluyera un sensor de profundidad, control de movimiento, reconocimiento facial y reconocimiento de voz. Este proyecto fue nombrado con el nombre «Project Natal». Project Natal tomó como referencia el dispositivo desarrollado por PrimeSense, el cual incluía un sensor de infrarrojos y un receptor de infrarrojos. Para evitar futuros problemas, Microsoft decidió obtener la licencia del diseño de dicho dispositivo y del chip PS1080 que montaba. Este chip supuso un paso muy importante para los objetivos del proyecto ya que era capaz de procesar datos de profundidad a 30 frames por segundo de una manera muy innovadora. Este permitió además reducir el precio de reconocimiento de la profundidad en comparación con el método vigente en aquel momento conocido como “tiempo de vuelo”, que consistía en registrar el tiempo que tarda un rayo de en salir y volver al sensor. La solución propuesta por PrimeSense consistía en proyectar un patrón de puntos infrarrojos en las superficies y emplear la disposición de los puntos para confeccionar un mapa de profundidad con una resolución de 320 x 240 píxeles que posteriormente serían analizados por el chip PS1080. Por otra parte, el chip también se encargaba alinear automáticamente la información de la cámara RGB y la cámara de infrarrojos, proporcionando de esta manera datos RGBD. Por su parte, Microsoft equipó también al dispositivo con una matriz de micrófonos de cuatro piezas debido a que ya tenían experiencia con el reconocimiento de voz que incorporaban sus sistemas operativos desde Windows XP. De esta forma, el dispositivo contaría con la capacidad de reconocimiento de voz en grandes habitaciones mediante este 18 micrófono direccional. Si bien el reto del hardware parecía estar resuelto gracias a PrimeSense, sólo a falta de dar con una forma de diseñar un dispositivo más pequeño, los problemas de software que se les estaban presentando parecían insuperables: Debían desarrollar un sistema de reconocimiento de movimiento a partir de los flujos de datos proporcionados por la cámara RGB y el sensor de profundidad que montaba el dispositivo. Debían depurar la señal de audio que proporcionaba la matriz de micrófonos incorporada al dispositivo para hacer posible la implementación de un sistema de reconocimiento de voz. Para tratar de resolver estos problemas de software, el equipo de Project Natal se vio obligado a recurrir a Microsoft Research (MSR), una división de Microsoft que fue creada en 1991 para investigar los diversos temas de ciencia de equipo y problemas. A finales de 2008, el equipo Project Natal contrató a Jamie Shotton para que aportara nuevas ideas para el sistema de seguimiento de movimiento, ya que la solución propuesta hasta el momento contaba con varios problemas: Para conseguir que el sistema de captura de movimiento detectara al jugador era necesario que inicialmente se colocara en posición en forma de T. Cada vez que el jugador detectado era perdido por el sistema era necesario reiniciar el sistema y comenzar de nuevo con la posición en forma de T. El sistema de seguimiento sólo era capaz de funcionar con tipos muy específicos de estructura corporal. No obstante, algunos de los problemas presentados por el seguimiento del movimiento pudieron ser resueltos gracias a los datos de profundidad que eran proporcionados por el sensor de profundidad. Estos permitían hacer un filtrado de los píxeles que no pertenecían al jugador y obtener además información muy valiosa como el color y la textura de la ropa de los jugadores, así como la altura y la anchura del jugador. Como resultado de este primer proceso de filtrado, se obtenía una representación del jugador en posiciones de píxeles, también conocido como “player blob” (ver Figura 4.6). Sin embargo, esto tan sólo supuso la primera parte de la resolución del problema. Por ello, Jamie Shotton tuvo que enfrentarse al reto de de transformar este player blob en algo que pudiera ser seguido. La solución que Shotton propuso consistía en fragmentar el player blob obtenido en partes del cuerpo que fueran fácilmente reconocibles. De esta forma, una vez que estas partes del cuerpo fueran identificadas, sería también posible identificar también las articulaciones y por consiguiente el esqueleto del jugador. Por último, junto con Fitzgibbon y 19 Figura 4.6: Player blob [WA12]. Andrew Blake, Shotton desarrolló un algoritmo que llegaría a ser capaz de diferenciar hasta 31 partes del cuerpo (ver Figura 4.7). Figura 4.7: Player blob dividido en partes [WA12]. Anteriormente se expuso a otro problema muy serio: La necesidad de que el jugador adoptase una posición inicial en forma de T para que el sistema de seguimiento de movimiento fuera capaz de detectar al jugador. Para hacer frente a este problema, Shotton decidió emplear técnicas de aprendizaje por ordenador. De esta forma, mediante cantidades ingentes de datos, el sistema de reconocimiento de imagen podía ser entrenado para dividir el player blob en las partes del cuerpo, de forma que estas pudieran ser utilizadas posteriormente y 20 así evitar esta molesta posición inicial en forma de T. Para lograr este propósito, se colocaron dispositivos en hogares con el objetivo de realizar grabaciones de vídeo de personas realizando movimientos físicos básicos. Toda esta información recolectada, junto con datos adicionales obtenidos en un estudio de captura de movimiento en Hollywood que recogían secuencias de videos de personas corriendo, bailando, etc., fue procesada por un sistema de computación distribuida conocido como Dryad con el objetivo de de producir un clasificador por árbol de decisión. Con este árbol de decisión sería posible asignar cualquier píxel obtenido mediante el sensor de profundidad incorporado en Kinect a una de las partes del cuerpo. Además, este proceso fue realizado para 12 tipos diferentes de cuerpos, solucionando de esta manera otros de los problemas expuestos anteriormente en el que sólo era reconocido un tipo de estructura corporal, realizando además diversos ajustes que permitieran mejorar la capacidad de decisión para identificar una persona sin una pose inicial y sin interrupciones en el reconocimiento. Llegados a este punto, tan sólo les quedaba una tarea pendiente: El reconocimiento por voz. Para hacer frente al reto, Alex Kipman recurrió a Iván Tashev del grupo de investigación de Microsoft en Redmond, ya que previamente había trabajado en proyectos similares para el reconocimiento por voz en Windows Vista. Para abordar el problema del filtrado de ruido de fondo en una matriz de micrófonos que se encontraba situada más cerca de los altavoces del televisor que del propio jugador, debían seguir un planteamiento similar al empleado anteriormente para diferenciar entre los píxeles que pertenecían a un jugador de los que no. Como resultado obtuvieron unos algoritmos de cancelación de ruido y supresión de eco mediante la combinación de las tecnologías ya patentadas por Microsoft que mejoraron el procesamiento de audio situándolo muy por encima del estándar que estaba disponible en la fecha. Por último, se lanzó durante una semana un sistema de aprendizaje computacional distribuido compuesto por mil nodos con el objetivo de construir un modelo acústico para Kinect, finalizado el 26 de septiembre de 2010. Este estaba basado en varios acentos regionales de América y las peculiaridades acústicas de la matriz de micrófonos que poseía Kinect. Finalmente, el 4 de Noviembre de 2010 el sensor fue anunciado bajo el nombre de Kinect. 4.1.2.3. Homebrew de Kinect Este movimiento tuvo importantes repercusiones en el entorno de Kinect como se mostrará a lo largo de esta sección, ya que entre otras cosas dio lugar a la aparición de numerosas plataformas como O PEN NI o NiTE, las cuales son las principales herramientas de este proyecto. La historia “hacker” de Kinect comienza con Johnny Chung Lee. Johnny era ya conocido por aquel entonces por ser la persona que había hackeado el controlador remoto de Wii, 21 Wiimote (véase § 4.1.2.2), con el objetivo de implementar el seguimiento de dedos (ver Figura 4.8) y que posteriormente pasaría a formar parte de Project Natal para trabajar en el reconocimiento de gestos. A pesar de los intentos de Johnny por convencer a Microsoft para publicar un driver público para Kinect, no lo consiguió. Fue por este motivo por el que contactó con AdaFruit, un suministrador de código libre, para convocar un concurso con el fin de hackear Kinect. Figura 4.8: Johnny Lee mostrando las modificaciones al Wii Remote [web14f]. Este concurso, cuyo anuncio coincidió con el día en que se lanzó Kinect al mercado, ofrecía un premio de 1000 dólares (que posteriormente sería aumentado hasta 3000 dólares) al primer participante que logrará desarrollar con éxito un controlador para el dispositivo e implementar una aplicación que convirtiera los flujos de datos del sensor de vídeo y visión de profundidad de Kinect. Este concurso fue posible en gran medida al hecho de que Kinect se comunicaba mediante un USB estándar con la consola Xbox 360 y por tanto ese mismo conector podría ser conectado al puerto USB de cualquier ordenador. A pesar de los comunicados realizados por Microsoft para evitar los objetivos de dicho concurso, el 6 de Noviembre de 2010 Joshua Blake, Sandler Seth, y Machulis Kyle fundaron un grupo de trabajo denominado OpenKinect con el objetivo de coordinar los esfuerzos para ganar el concurso. Ellos consideraban que el primer reto propuesto por el concurso era relativamente sencillo de conseguir pero que, sin embargo, debían aunar todos los esfuerzos realizados con el fin de intercambiar la información que fueran obteniendo y las herramientas que se fueran desarrollando. Lo que comenzó siendo un grupo fundado para conseguir un premio terminó siendo una comunidad centrada en en mirar hacia lo que podría lograrse gracias a la tecnología que ofrecía este nuevo dispositivo. De manera simultanea a estos acontecimientos, AlexP mostró en la red cómo era capaz de controlar los motores que poseía Kinect y leer los datos provenientes de su acelerómetro. 22 Dos días después, publicó un vídeo en el que mostraba cómo obtenía el flujo de datos de la cámara RGB y de la cámara de profundidad. Sin embargo, y a pesar de que el premio de AdaFruit había ascendido ya a 3000 dólares, decidió no proclamarse campeón del mismo debido a sus reticencias de publicar el código. Microsoft siendo consciente de los avances que estaban realizando en la comunidad hacker en su lucha por liberar el dispositivo y ofrecer herramientas para que cualquiera pudiera desarrollar para Kinect, mostró públicamente su cambio de opinión respecto a este movimiento siempre y cuando no se denominara “hackeo”. Fue el analizador USB Beagle 480 (ver Figura 4.9) lo que permitió a AdaFruit comenzar con el volcado USB de los datos recibidos a través de Kinect. Héctor Martín, ingeniero informático de Bilbao, gracias a estos datos fue capaz de desarrollar en unas pocas horas un controlador (libfreenect) y una aplicación para mostrar los datos de la cámara RGB y de la cámara de profundidad. Figura 4.9: Analizador de USB Beagle 480 [web14e]. PrimeSense anunció el 10 de Diciembre el lanzamiento de sus propios controladores de código abierto para el dispositivo y todas las librerías (entre ellas O PEN NI) necesarias para procesar los datos obtenidos del mismo. Este hecho supuso un gran avance, ya que las herramientas que ofrecía PrimeSense mejoraban notablemente los resultados obtenidos con los algoritmos de seguimiento de libfreenect. No obstante, al igual que le ocurrió a Microsoft en un principio, el seguimiento de esqueleto mediante O PEN NI todavía necesitaba la incómoda postura en T para inicializar el reconocimiento de esqueleto. No fue hasta el 17 de junio de 2011 que Microsoft ofreciera oficialmente soporte para desarrollar con Kinect. Para ello lanzó una beta del Software Development Kit (SDK) bajo una licencia pública no comercial. En la actualidad, cualquier desarrollador que lo desee puede obtener acceso a las mismas herramientas que Microsoft utiliza para implementar aplicaciones para Kinect. 23 4.1.3 Desarrollo de aplicaciones alternativas Gracias a las características que serán explicadas en la siguientes subsecciónes (véase § 4.1.4 y § 4.1.6), Kinect ha conseguido desde que fue lanzada su primera versión en 2010 ser mucho más que un simple periférico para videojuegos. Los desarrolladores de todo el mundo han descubierto que posee un gran potencial, permitiéndoles experimentar con un hardware de visión, que generalmente hubiera estado al alcance de unos pocos debido a la complejidad y alto precio. Esto se debe en gran parte a que el controlador de Microsoft es uno de los dispositivos más versátiles del mercado, sobre todo, teniendo en cuenta que originalmente fue desarrollado para ofrecer una nueva forma de interacción a los jugadores de videoconsolas. De este modo, Kinect ha conseguido trascender el objetivo con el que fue creado para llegar a convertirse en una poderosa herramienta de visión por computador que es empleada en prestigiosos centros de investigación como el MIT Media Lab. En una entrevista Joi Ito, director del MIT Media Lab, comentaba que este dispositivo está comenzando a ser la piedra angular de muchos proyectos de investigación desarrollados por estudiantes en el MIT. Algunos de los más interesantes son: Kinect for Cooler Videoconferencing, que consiste en un sistema de videoconferencia que ofrece una forma diferente de interactuar en relación a las plataformas que se conocen hoy en día para tal fin (ver Figura 4.10). Entre los aspectos más destacables en este proyecto se encuentra la posibilidad de emplear realidad aumentada, la identificación de los individuos que se encuentran en escena o incluso el enfoque automático de la persona que se encuentre hablando en cada momento [web14q]. Figura 4.10: Kinect for Cooler Videoconferencing [web14q]. Real-Time Princess Leia Holography Via Kinect Hack (ver Figura 4.11), que consiste en un sistema que permite transmitir vídeo holográfico a quince frames por segundo a través de internet. Lo más llamativo de este proyecto es que para su funcio24 namiento tan sólo se requiere un dispositivo Kinect, un portátil con unas prestaciones estándar para el extremo final de la comunicación y un ordenador de sobremesa que disponga de tres chips de procesamiento gráfico. Para la proyección del holograma se requiere un dispositivo especial para tal propósito y que aún se encuentran en fase de desarrollo [web14x]. Figura 4.11: Real-Time Princess Leia Holography Via Kinect Hack [web14x]. No obstante, desde que se hicieron públicas las herramientas ofrecidas por las diferentes compañías, desarrolladores de todo el mundo comenzaron a crear sus propias aplicaciones y a exprimir las ventajas que ofrece Kinect más allá de los objetivos iniciales para la videoconsola Xbox 360. No obstante, esto supone una oportunidad que va mucho más allá del ocio y proyectos de investigación, convirtiendo a Kinect en la base de muchos productos comerciales. Según declaraciones de miembros de Microsoft: “We’ve seen a tremendous amount of interest in the Kinect for Windows commercial program, with more than 300 companies participating in our early adopter program. Although the commercial hardware and software were not released until February 1 st , we’re already seeing innovative examples of commercial uses from some of our early adopter participants. The possibilities are endless. In coming months, we will feature many of these examples of Kinect for Windows applications on this website as well as our blog.” 25 En las siguientes subseciones se presentan algunos de los start-ups más destacados hasta el momento ordenados por el campo en el que trabajan. 4.1.3.1. Ocio Ubi (ver Figura 4.12), sistema desarrollado por Ubi Interactive que permite convertir cualquier superficie en una pantalla táctil [wbU14]. Figura 4.12: Ubi Interactive [wbU14]. Fitnect (ver Figura 4.13), ofrece un probador en tres dimensiones basado en realidad aumentada. Esta innovadora aplicación permite a los compradores probarse de manera virtual diferentes prendas y accesorios, dándoles así la oportunidad de ver cómo les sentarían los productos sin necesidad de probárselos [web14b]. Figura 4.13: Fitnect [web14b]. 26 4.1.3.2. Medicina TedCas (ver Figura 4.14), sistema desarrollado por TedCas Medical Systems. Su principal objetivo es luchar contra las infecciones que se producen en un quirófano puesto que, gracias a Kinect, permite a los cirujanos navegar por el historial clínico de los pacientes sin necesidad de tocar su historia clínica o el teclado ya que todo será controlado mediante gestos [wbT14a]. Figura 4.14: TedCas [wbT14a]. VirtualRehab (ver Figura 4.15), sistema desarrollado por Virtualware Group el cual se centra en proporcionar un programa de rehabilitación a través del fortalecimiento muscular, la resistencia y la coordinación [wbV14]. Figura 4.15: VirtualRehab [wbV14]. 4.1.3.3. Educación KinectEducation [web14o] es un recurso de la comunidad educadora que tiene el objetivo de impulsar a los desarrolladores, profesores, estudiantes, aficionados y a cualquier otra persona interesada en la educación para promover en las aulas el uso 27 de aplicaciones basadas en Kinect. Ellos defienden que la integración de dispositivos como Kinect en las aulas ofrece innovadoras oportunidades de aprendizaje dentro de un entorno controlado de le educación pública. “River Crossing” es una de las aplicaciones que presentan en esta comunidad. Este juego educativo tiene como principal objetivo que el niño sea capaz de aprender la tarea de dirigir un barco a través de un río donde el niño debe emplear la lógica para trasladar un pato, un zorro y un saco de semillas a la otra orilla del río sin que se coman unos a otros (ver Figura 4.16). “Kinect Math” es otra de las aplicaciones promovidas por KinectEducation, con el objetivo de dar a los educadores la posibilidad de volver a interesar a los estudiantes de matemáticas, practicando físicamente con los conceptos matemáticos que pueden resultar más abstractos (ver Figura 4.17). Figura 4.16: Juego River Corssing [web14i]. Jumpido [web14g] es una plataforma de aprendizaje enfocada en dar soporte al plan educativo de niños entre 6 y 12 años. Para ello, incorpora una gran variedad de actividades que permiten a los niños progresar de manera interactiva y entretenida en diferentes campos como en biología, química, matemáticas, música, etc. “Baskets” es un ejemplo de sus muchas actividades cuyo fin es animar al niño a resolver problemas matemáticos que van apareciendo en las ramas de los árboles dándoles una retroalimentación muy estimulante para ellos sobre sus respuestas (ver Figura 4.18). 4.1.3.4. Accesibilidad Navigational Aids fot the Visually Impaired (NAVI) (ver Figura 4.19): Tiene como objetivo emplear el sensor de profundidad de Kinect para detectar paredes y obstácu28 Figura 4.17: Kinect Math [web14l]. Figura 4.18: Actividad “Baskets” integrada en la plataforma Jumpido [web14g]. los, sirviendo así como ayuda de movimiento para una persona con algún grado de discapacidad visual proporcionándoles feedback táctil sobre los obstáculos que se encuentran en su camino. Fue creada por dos estudiantes de la Universidad de Konstanz en Alemania. La aplicación emplea, además de un dispositivo Kinect, un ordenador portátil y un dispositivo Arduino LillyPad que están situados en una mochila. Por otro lado, el sensor está ubicado en un casco especial sobre la cabeza del usuario, manteniendo de esa forma el sensor Kinect apuntando hacia el frente [web14w]. Kinect Sign Language Translator (ver Figura 4.20): Es un prototipo de investigación desarrollado por la división MSR que es capaz de traducir ambos lenguajes, en ambos sentidos y en tiempo real. El sistema reconoce los gestos, traduciéndolos de forma escrita y oral, mientras que si una persona habla, sus frases se traducen a signos en un modelo en el ordenador. No obstante, el desarrollo aún tiene un largo recorrido por delante ya que se necesita que cinco personas hagan el mismo gesto por cada palabra de forma que luego ésta sea reconocida a posteriori. Por el momento se han incluido 29 Figura 4.19: NAVI (Navigational Aids fot the Visually Impaired) [web14w]. 300 palabras chinas de un total de 4.000 que los programadores chinos están utilizando para las pruebas iniciales. Figura 4.20: Kinect Sign Language Translator [web14r]. 4.1.4 Características técnicas Actualmente hay disponible en el mercado dos versiones diferentes: Kinect for Xbox 360 y Kinect for Windows. Ambos sensores comparten muchas capacidades (ver cuadro 4.2), siendo algunas de las más importantes: Una cámara RGB, la cual hace posible la captura de vídeo mediante el almacenamiento de datos desde tres canales a una resolución de 1280 x 960 a 30 frames por segundo, o a una resolución de 640 x 480 frames por segundo. Un sensor de infrarrojos (IR) y un sensor de profundidad IR. Ambos hacen posible la captura de profundidad: El emisor emite rayos de luz infrarroja y el sensor de profundidad lee los haces IR reflejados que vuelven a él. De esta manera, es posible convertir esta información en datos relativos a la profundidad midiendo la distancia entre el objeto y el sensor. 30 Un micrófono de múltiples matrices. Incorpora cuatro micrófonos para que sea posible grabar audio desde una dirección especifica, encontrar la ubicación del sonido y la dirección de la onda de audio. Dispone de un convertidor analógico-digital de 24 bits incluyendo de eco acústico y supresión de ruido. Un acelerómetro de tres ejes configurado para una gama 2G (donde G es la aceleración debida a la gravedad). De este modo, es posible utilizar el acelerómetro para determinar la orientación actual del sensor. Motor: Este motor es capaz de inclinar el dispositivo en un ángulo de 30◦ por arriba y por abajo del plano horizontal. Elemento Rango Ángulo de visión Rango de movimiento del cabezal (vertical) Velocidad de imagen (flujos de datos de color y profundidad) Resolución por defecto en cámara de profundidad Resolución por defecto en cámara de color RGB Formato de audio 43◦ vertical y 57◦ horizontal ±27◦ 30 frames per second (FPS) VGA (640 x 480) VGA (640 x 480) 16-kHz, 16-bit mono pulse code modulation (PCM) Un array de cuatro micrófonos que incluye conversos analógico a digital de 24 bits integrado con Acoustic Echo Cancellation y Noise Suppression Características de entrada de audio Cuadro 4.1: Especificación técnica Kinect. En la Figura 4.21 se muestra un gráfico que especifica como están distribuidos los diferentes componentes en el interior del dispositivo. No obstante, Kinect for Windows ofrece varias funcionalidades que no están presentes en su primera versión, Kinect for Xbox 360. A continuación se mencionan las más significativas: Near Mode: Permite a la cámara ver objetos que se encuentren delante de ella a una distancia de hasta 40 centímetros sin perder exactitud o precisión. Mientras que Kinect para Xbox 360 reconoce usuarios desde los 0’4 metros a los 4 metros de distancia reconociendo el esqueleto únicamente desde los 0’8 metros a los 4 metros, con este nuevo Near Mode es posible reconocer esqueletos desde los 0’4 metros de distancia 31 Figura 4.21: Distribución de los componentes en Kinect [web14k]. a los 3 metros de distancia del sensor. En la Figura 4.22 se muestra una comparativa entre ambos modos de reconocimiento. Figura 4.22: Distancia para el reconocimiento del esqueleto en Kinect [web14k]. Audio y reconocimiento de voz: Recibe una mejora substancial en su precisión y estabilidad. Cable USB: Asegura la fiabilidad en una amplia gama de ordenadores y mejora la convivencia con otros periféricos USB. Configuración de la cámara: Lo cual proporciona ajustes adicionales, tales como el brillo, exposición, etc. así como un mayor rango de resoluciones disponibles en la cámara RGB y en el sensor de profundidad para proporcionar una mayor precisión. Detección de manos: Permite implementar gestos con las manos como pellizcar para hacer zoom, agarrar, etc. 4.1.4.1. Segunda generación de Kinect Es importante destacar que Microsoft ha anunciado que con motivo del lanzamiento de su nueva videoconsola, Xbox One, Kinect experimentará una importante renovación con grandes mejoras. La gran diferencia del nuevo Kinect (ver Figura 4.23) respecto a su predecesor reside en la nueva cámara principal. La segunda generación del dispositivo de captura de 32 movimientos incorpora una cámara Time-Of-Flight (TOF) de alta resolución que permite al próximo Kinect de Xbox One capturar más detalles con gran precisión y mayor resolución. El nuevo modo de profundidad proporcionado por esta cámara TOF hace posible la captura y la reprodución de una escena con hasta tres veces más fidelidad que el primer Kinect. Figura 4.23: Segunda generación de Kinect [web14k]. No obstante, no es la única ventaja que se obtiene al emplear este tipo de cámara. Con ella además se logra un campo de visión hasta un 60 % más amplio, lo cual permite capturar un espacio mayor, posibilitando de esta manera que más personas puedan ser registradas concurrentemente e incluso a una menor distancia del dispositivo. En la nueva generación de la nueva videoconsola pueden aparecer hasta 6 personas en escena reconociendo y distinguiendo todos sus movimientos. Todos estos cambios suponen un importante avance respecto a su predecesora que tan sólo era capaz de registrar el movimiento de 2. El segundo gran cambio en la nueva generación de Kinect viene de la mano del nuevo sensor de infrarrojos. Este sensor logra reconocer objetos y personas en condiciones de luminosidad muy bajas, siendo ahora tan potente que permite identificar elementos en una habitación totalmente a oscuras. La precisión es tal que permite el reconocimiento de personas y el registro de cuerpos incluso sin ninguna luz visible para el ojo humano. Incluso bajo condiciones de luminosidad bajas permite reconocer la pose de la mano a una distancia de hasta cuatro metros de distancia, distinguiendo con precisión cada uno de los dedos. Mediante la combinación de todas estas novedades es posible registrar no sólo la silueta del usuario, sino también distinguir su esqueleto completo, la orientación de sus miembros, los músculos del cuerpo con la fuerza y distribución de pesos ejercida sobre ellos, y hasta el latido del corazón. El reconocimiento facial también se ve ampliamente mejorado, detectando hasta el más mínimo detalle y gesto, permitiendo de esta manera una identificación más precisa. Esta nueva tecnología cuenta además con una mejora en el procesador de Kinect, permitiéndole hacer frente a la ingente cantidad de información que obtienen todos los nuevos sensores. Hasta 2 gigabits de datos por segundo son recogidos por el dispositivo para leer el entorno. Toda esa información ha de ser procesada e interpretada rápidamente y para ello ha 33 sido necesario una evidente mejora en las especificaciones de la máquina. En resumen, se pueden destacar las siguientes mejoras: Mayor precisión con hasta el triple de fidelidad con respecto su predecesor. Capacidad de ver en la oscuridad gracias a su nuevo sensor IR. Campo de visión hasta un 60 % más amplio. Capacidad de rastrear hasta seis esqueletos a la vez. Detección de frecuencia cardíaca y mejora en la detección de la expresión facial. Veinticinco articulaciones individuales, incluidos los pulgares. A pesar de estas importantes mejoras, el mayor inconveniente para el desarrollo del presente TFG es que no será lanzada hasta hasta el año 2014. Por este motivo, se prevé que para el desarrollo del mismo se emplee la actual Kinect. 4.1.5 Ventajas de Kinect frente a otros dispositivos A continuación se exponen las principales ventajas que el dispositivo Kinect ofrece frente a los dispositivos tradicionales que pueden ser empleados en la visión por computador: Se requiere únicamente una cámara. No son necesarios cálculos manuales para obtener la profundidad. Adquisición de la geometría en tres dimensiones de las escenas en tiempo real. Dependencia de la iluminación reducida. Baja dependencia de la textura de las superficies. En la actualidad existen diversas plataformas muy potentes que ofrecen soporte para desarrollar software para Kinect. 4.1.6 Funcionamiento El propósito de esta sección es proporcionar una visión general sobre la forma en la que trabaja el dispositivo Kinect. Para ello, se ha dividido en diferentes apartados que versan sobre la cámara RGB, la cámara de profundidad y el proceso de mapeo de profundidad, el sistema de micrófonos y por último una breve reseña sobre el motor de inclinación. 4.1.6.1. Cámara RGB Como ya se exponía en la sección de características técnicas de Kinect (véase § 4.1.4), este dispositivo dispone de una cámara RGB que permite capturar vídeo a una resolución de 1280 x 960 frames por segundo o a una resolución de 640 x 480 frames por segundo. Mediante las diferentes plataformas que se encuentran disponibles actualmente (véase § 4.1.8), un desarrollador es capaz de obtener los datos de dicha cámara y emplearlos en 34 sus aplicaciones. Estos datos representan las imágenes que son obtenidas a través del sensor y se encuentran codificados como un vector de bytes. No obstante, para entender esta codificación es necesario conocer primero cómo se estructura una imagen. Cada píxel de una imagen tiene cuatro componentes que representan los valores de los colores rojo (R, red), verde (G, green) y azul (B, blue) más un componente adicional que se corresponde con el valor de transparencia (a, alfa) si se tratan de imágenes RGBa, o un color vacío si es del tipo RGB (ver Figura 4.24). Figura 4.24: Componentes de un píxel. Cada componente de un píxel, a su vez, representa un valor decimal comprendido entre 0 y 255 correspondiendo a un byte. Por lo tanto, el vector de bytes (ver Figura 4.25) que se obtiene del sensor es una representación de esos píxeles organizados de arriba abajo y de izquierda a derecha donde los 3 primeros elementos del vector serán los valores rojo, verde y azul del píxel situado en la esquina superior izquierda de la imagen, mientras que, por el contrario, los 3 últimos elementos corresponderán al píxel situado en la esquina inferior derecha. Figura 4.25: Estructura del vector de bytes de la imagen. 4.1.6.2. Cámara profundidad Como ya se exponía en la sección de características técnicas de Kinect (véase § 4.1.4), este dispositivo dispone de un sensor de infrarrojos (IR) y un sensor de profundidad IR, haciendo posible la captura de profundidad mediante la creación de mapas de profundidad. Este proceso de creación de mapas de profundidad se lleva a cabo mediante lo que se denomina “codificación de luz”. Esta codificación de luz consta de dos fases: Calibración (ver Figura 4.26): Esta fase consiste en la proyección de un patrón de puntos (ver Figura 4.27) sobre una superficie variando la distancia a la que se encuentra en 35 unas posiciones conocidas. Posteriormente, por cada posición se obtiene una imagen infrarroja que será almacenada en la memoria interna del dispositivo y que más tarde servirá como referencia. De esta manera, aplicando técnicas de triangulación y conociendo la distancia que separa el proyector de la cámara infrarroja (75 mm), la focal de ésta (750 mm) y la distancia de la cámara a los puntos proyectados, es posible conocer dónde se proyectaría cada punto en el proyector si este fuese en realidad una cámara infrarroja igual a la otra. Por lo tanto, de esta forma es posible conocer exactamente la posición en la que se proyecta cada punto si se conoce su patrón. Figura 4.26: Fase de calibración del sistema de mapas de profundidad de la Kinect. Funcionamiento(ver Figura 4.28): Esta fase se reduce a un problema de visión estéreo. Para resolver este problema, el chip de PrimeSense que incorpora el dispositivo busca los puntos en la imagen infrarroja para posteriormente comparar la posición de los puntos proyectados (a través de las imágenes de referencia) y la posición de los puntos en la proyección de la imagen que ha sido obtenida, calculando de este modo cuánto se ha desplazado cada punto. Para realizar este proceso, es necesario emplear una matriz de correlación de 9 x 9 píxeles que contiene la disparidad entre los puntos de ambas escenas. Mediante este método se crean unas sombras de 5 píxeles en todo el borde de la imagen debido a que para esos píxeles, parte de la máscara se encuentra fuera de la imagen y por lo tanto no hay información suficiente para realizar la correlación. Posteriormente, mediante un proceso llamado “triangulación activa” se calculan las distancias a las que se encuentran proyectados cada punto. Por último, con 36 Figura 4.27: Imagen de los puntos infrarrojos proyectados en una pared [Bor12]. la información que se ha obtenido de todos los puntos se construye la imagen. En la ecuación 4.1 se observa la ecuación empleada en el proceso de triangulación activa para calcular la profundidad (z), donde b es la distancia entre el proyector infrarrojo y la cámara IR (75 mm), f es la focal de la cámara IR (750 mm); kd es la disparidad entre los puntos de ambas imágenes y doff es la disparidad característica de la Kinect (1090). z= 4.1.6.3. 1 8 b∗f ∗ (dof f − kd) (4.1) Sistema de micrófonos De acuerdo con lo expuesto anteriormente (véase § 4.1.4), Kinect dispone de un sistema de micrófonos que está compuesto de cuatro micrófonos colocados en la parte inferior, uno en el lazo izquierdo y tres en lado derecho (ver Figura 4.29). Esta distribución tan especifica es el principal motivo por el que Kinect dispone de una anchura de 28 cm. Estos micrófonos son empleados tanto para el reconocimiento de voz como para identificar el origen y direccionalidad de la fuente de sonido. Esto último se debe a que el sonido llegará a los distintos micrófonos en instantes de tiempo diferentes, de forma que, a grosso modo, es posible calcular el lugar de dónde provienen las ondas sonoras teniendo en cuenta el desfase entre la señales y la velocidad del sonido en el entorno. 4.1.6.4. Motor de inclinación De acuerdo con lo expuesto anteriormente (véase § 4.1.4), Kinect dispone de un motor de inclinación que se encuentra en su base. El principal objetivo de este motor es permitir mover 37 Figura 4.28: Fase de funcionamiento del sistema de mapas de profundidad de la Kinect. Figura 4.29: Disposición de los micrófonos en Kinect [web14k]. el dispositivo arriba y abajo en un rango de 30 grados con la intención de calibrar el espacio de detección y el ángulo de visión de las cámaras. 38 4.1.7 ¿Por qué Kinect? Las cámaras que normalmente se ven en la vida cotidiana recogen la luz que rebota en los objetos que están delante de ellas y la convierten en una imagen como la que una persona vería con sus propios ojos. Sin embargo, las cámaras de profundidad como la que ofrece Kinect trabaja de una manera muy distinta: Recogen la distancia de los objetos que están situados frente a ellas. Para ello, emplean luz infrarroja para crear una imagen (imagen de profundidad) que no captura la apariencia de los objetos, sino donde se encuentran en el espacio. Una imagen de profundidad es mucho más sencilla de entender por un ordenador que una imagen a color convencional. De este modo, cualquier sistema que intente entender una imagen comenzará analizando los píxeles tratando de encontrar y reconocer las personas y objetos que estos representan. No obstante, esta es una tarea bastante compleja ya que, en una imagen a color, los píxeles están sujetos a varios factores como la luz de la habitación de cuando la imagen fue tomada o la abertura de la cámara. Por el contrario, en una imagen de profundidad el color de cada píxel proporciona la distancia de cada parte de la imagen con respecto la cámara. Puesto que estos valores se corresponden directamente con donde se encuentran ubicados los objetos en el espacio, este tipo de imágenes resultan mucho más útiles y eficientes a la hora de determinar conceptos bastante complejos como por ejemplo dónde comienza un objeto y termina otro o si hay gente alrededor. Además, debido a la forma en la que Kinect captura este tipo de imágenes, los resultados obtenidos no se ven sujetos a las condiciones de luz de la habitación de cuando fue capturada la imagen. De este modo, Kinect capturará la misma imagen de profundidad en una habitación con condiciones de luminosidad opuestas. Por lo tanto, esto proporcionará un entorno más fiable e incluso más fácil de entender por un sistema. En definitiva, gracias a esta información tridimensional que proporciona la cámara de profundidad de Kinect es posible diseñar y construir herramientas más robustas para la detección y seguimiento de personas, así como localizar sus articulaciones y partes del cuerpo. 4.1.8 Librerías Kinect En la siguiente subsección se pretende proporcionar una visión general acerca del estado actual de las diferentes plataformas destinadas al desarrollo de aplicaciones para Kinect: SDK de Kinect, O PEN NI y OpenKinect. Para ello, se han descrito las principales características de cada una, cómo funciona cada framework, las funcionalidades soportadas por cada una, cómo ha evolucionado en los últimos años, así como las ventajas y desventajas que presenta cada una. La documentación requerida para esta subsección ha sido obtenida de diversas fuentes, intentando en todo momento proporcionar la visión más imparcial y objetiva posible. Por ello, se han empleado diversos libros como [KBC+ 12] [Cat12] [KHP11] [WA12] [Mil12] 39 [Dav12] [Jan12] [Fal13], además de las páginas oficiales de cada plataforma y sus correspondientes foros de discusión. 4.1.8.1. SDK Windows El SDK de Kinect es un kit de herramientas ofrecido por Microsoft para el desarrollo de aplicaciones basadas únicamente en el dispositivo Kinect escritas en C++, C#, o Visual Basic. La principal intención de Microsfot con esta plataforma es ofrecer una solución totalmente integrada y que, además, sea fácil de aprender y manejar por los desarrolladores. Para ello, el SDK proporciona una interfaz que permite, de una manera muy sencilla, interactuar con Kinect a través de los drivers que son proporcionados en el mismo SDK y que además permite interaccionar con el sistema operativo y las APIs directamente a través del mismo entorno de desarrollo. 4.1.8.1.1. Descripción del SDK De esta forma, el SDK integra todas las herramientas y APIs que un desarrollador puede necesitar para diseñar e implementar aplicaciones que interactúen con el dispositivo Kinect. Como ya se ha mencionado antes, uno de los objetivos de Microsoft con esta plataforma es ofrecer la solución más sencilla posible a los desarrolladores para que integren el uso de Kinect en sus aplicaciones. Para ello, Microsoft ha ideado el SDK de de forma que el desarrollo de una aplicación con Kinect sea esencialmente igual que el desarrollo de cualquier otra aplicación para Windows, a excepción de que el SDK integra el soporte necesario para las características de la Kinect, como son las imágenes de profundidad y color, entrada de audio, etc. Según la descripción proporcionada por Microsoft, algunos de los ejemplos del tipo de aplicaciones para Windows que se pueden desarrollar empleando la funcionalidad proporcionada por el SDK son los siguientes: Reconocimiento y seguimiento del movimiento de personas mediante seguimiento del esqueleto humano. Determinar la distancia existente entre un objeto y el sensor mediante datos de profundidad. Captura de audio usando mecanismos de cancelación de ruido y eco o encontrar la localización de la fuente donde se origina el sonido. Implementar aplicaciones de procesamiento de voz a través de un motor de reconocimiento del habla. No obstante, no se debe perder de vista otro de los objetivos clave de Microsfot con este SDK: Ofrecer una solución completa y totalmente integrada de forma que un desarrollador tenga a su disposición todo lo requerido para diseñar, implementar y distribuir una aplicación 40 basada en las funcionalidades de Kinect. De esta forma, el paquete distribuido por Microsoft incluye los siguientes componentes: Los drivers necesarios para interactuar con el dispositivo a través de Windows, así como toda la información técnica que es necesaria para desarrollar una aplicación basada en Kinect. Una gran variedad de APIs y fuentes de documentación que sirvan como referencia. Estas APIs ofrecen la posibilidad de recibir una gran variedad de datos multimedia provenientes del sensor con una latencia mínima. Una gran colección de muestras que tienen como objetivo dar a conocer a los desarrolladores un conjunto de buenas prácticas para el uso de Kinect. Un considerable surtido de ejemplos que facilitan el aprendizaje de las APIs. Para el desarrollo de una aplicación a través de este SDK es necesario tener algunas nociones básicas sobre como esta estructurada su arquitectura (ver Figura 4.30): Figura 4.30: Arquitectura del SDK [web14j]. Hardware Kinect: Módulo constituido por los componentes hardware, incluyendo el sensor Kinect y el puerto USB a través del cual se conecta a la computadora. Drivers Kinect: Es la capa software de más bajo nivel que se encarga de comunicarse con el módulo hardware a través de los drivers que son proporcionados con el propio SDK. Estos drivers dan soporte a: • El array de micrófonos como un dispositivo de audio en modo kernel que puede ser accedido a través de las APIs de audio estándar suministradas con el sistema operativo Windows. • Controles especializados para los flujos de audio y vídeo (imágenes RGB, imágenes de profundidad y esqueleto). • Funciones de enumeración de dispositivos que permiten que una aplicación se comunique con más de un dispositivo Kinect. 41 Componentes de audio y vídeo: Compuesta por la Natural User Interface (NUI) de Kinect, encargándose de realizar las tareas de seguimiento del esqueleto y del procesado del audio e imágenes RGB y de profundidad. DirectX Media Objec (DMO): Módulo encargado de la formación de haces provenientes del array de micrófonos, así como de determinar el origen del audio. APIs estándares de Windows 7: APIs de audio, voz y contenido multimedia que están incorporadas en el SDK de Windows 7 (también disponible para Windows 8) y en el SDK de reconocimiento del habla de Microsoft. No obstante, de todos los componentes que forman parte de la arquitectura del SDK de Kinect, el más importante para un desarrollador es NUI ya que constituye el núcleo de las APIs incluidas en el SDK. De entre todas las funcionalidades y los datos que este componente permite acceder, los más destacados son los datos de audio que son transmitidos a través del flujo de audio y los datos RGB y de profundidad de las imágenes que son transmitidas a través de los flujos de RGB y profundidad. En la Figura 4.31 se puede apreciar cuál es esquema de interacción entre el hardware y software de una aplicación a través de NUI. Figura 4.31: Interacción del hardware y software con una aplicación [web14j]. Además de las capacidades hardware que proporciona Kinect, los elementos software incorporados en NUI implementan: Un pipeline software que es capaz de reconocer y realizar el seguimiento del cuerpo humano. Para que esto sea posible, convierte en tiempo de ejecución la información de profundidad obtenida a través de Kinect en la ubicación de las articulaciones del cuerpo humano (ver Figura 4.32). De esta forma, es posible reconocer hasta seis personas personas que se encuentren ubicadas frente a la cámara del dispositivo y realizar el seguimiento de hasta dos. La integración con las APIs de reconocimiento de habla de Microsoft, haciendo posible la incorporación un potente motor de reconocimiento del habla en las aplicaciones. Un ejemplo de ello podría ser la implementación de una aplicación que responda a comandos de voz realizados por el usuario. Actualmente, esta API tiene soporte para doce idiomas, entre ellos el castellano. La integración con el SDK de seguimiento de rostros ofrecido por Microsoft, a través del cual es posible integrar en las aplicaciones funcionalidades que estén basadas en el reconocimiento y seguimiento de caras humanas. Por el momento, las características 42 Figura 4.32: Articulaciones reconocidas por el SDK de Kinect [web14j]. más interesantes de este SDK son la capacidad de detectar hasta 87 puntos del rostro humano (ver Figura 4.33), así como la orientación de la cabeza del usuario. Figura 4.33: Puntos del rostro humano reconocidos por el SDK de Microsoft [web14j]. Otro término importante del SDK de Kinect es el de “KinectInteraction”. KinectInteraction se refiere al conjunto de funcionalidades que permite a las aplicaciones incorporar interacción basada en gestos. Aunque no forma parte del SDK de Kinect para Windows, se encuentra disponible a través de del kit de herramientas asociado a Kinect. Algunas de las funcionalidades de alto nivel que proporciona KinectInteraction son las siguientes: Identificación y seguimiento de las manos de hasta dos usuarios. Servicios para detectar la localización y el estado de las manos del usuario. Detección de la presión ejercida con las manos. Información de control relacionada con los usuarios objetivo. Para que todas estas funcionalidades sean posibles, KinectInteraction emplea una combinación de flujos de profundidad y sofisticados algoritmos. En la figura 4.34 se puede apreciar 43 como está compuesta la arquitectura de este módulo. Figura 4.34: Arquitectura de KinectInteraction [web14j]. Además de todas las funcionalidades proporcionadas a través de las diferentes APIs, el SDK de Kinect incorpora una colección de potentes herramientas que permite a los desarrolladores llevar a sus aplicaciones a un nivel más alto. A continuación se describen las más destacadas: Kinect Studio: Es una herramienta que permite grabar y reproducir secuencias de vídeo de profundidad y RGB capturadas mediante Kinect. Gracias a esta herramienta, los desarrolladores podrán leer y escribir flujos de datos con el objetivo de depurar las funcionalidades de sus aplicaciones, así como para crear escenarios repetibles para realizar labores de testing y análisis de rendimiento. Kinect Fusion: Es una herramienta de gran potencia que en un principio sólo estaba disponible a nivel interno en los equipos de desarrollo de Microsoft. Gracias a esta herramienta, los desarrolladores podrán modelar objetos en tres dimensiones, crear aplicaciones de realidad aumentada e incluso tomar medidas de los escenarios en tiempo real. En la Figura 4.35 se puede observar el proceso de tratamiento que es necesario para conseguir un modelo en tres dimensiones. Figura 4.35: Resultado obtenido a través de Kinect Fusion [web14j]. 44 Plataformas soportadas Requerimientos hardware del computador: Procesadores de 32-bit (x86) o 64-bit (x64). Dual-core con un procesador a 2.66-GHz o superior. Bus USB 2.0 2 GB de RAM. Tarjeta gráfica que soporte DirectX 9.0c Requerimientos software: Visual Studio 2010 o Visual Studio 2012. .NET Framework 4 (incluido en Visual Studio 2010) o .NET Framework 4.5 (incluido en Visual Studio 2012). Sistemas operativos soportados: Windows 7. Windows 8. Windows Embedded Standard 7. Windows Embedded Standard 8. 4.1.8.1.2. Evolución del framework El SDK para Windows fue lanzado por primera vez como una versión Beta el 1 de Junio de 2010, pero debido a la gran aceptación con la que fue recibida, Microsoft decidió el lanzar una segunda versión Beta el 2 de Noviembre de 2011. Es importante destacar que inicialmente ambas versiones del SDK fueron “releases” no comerciales que estaban destinadas a los aficionados. No obstante, la primera versión comercial no se hizo esperar mucho más. Esta fue lanzada bajo el nombre “Kinect for Windows SDK 1.0” en febrero de 2012 junto con la nueva versión de Kinect (Kinect for Windows). En la Figura 4.36 se puede observar la evolución de diferentes versiones hasta el SDK 1.6. La última versión fue lanzada el 17 de Septiembre bajo el nombre de “Kinect for Windows SDK 1.8” con importantes mejoras en el rendimiento de toda la plataforma. Además, se incluyen dos nuevas funcionalidades que abren nuevas puertas a los desarrolladores: Webserver para los flujos de datos de Kinect: Se trata de un componente que dota a las aplicaciones hechas en HTML5 con la capacidad de poder acceder a los datos que Kinect obtiene. De esta manera es posible utilizar las interacciones de Kinect para controlar una aplicación hecha en HTML5. 45 Figura 4.36: Evolución del SDK de Kinect [WA12]. Kinect Background Removal: Consisten en un API que ofrece la funcionalidad de eliminar y/o cambiar el fondo de un usuario traqueado. También ofrece la capacidad de configurar a que usuario se le quiere aplicar el efecto en el caso de que halla más de uno en escena. 4.1.8.1.3. Ventajas y desventajas A continuación se describen los pros y los contras de emplear el SDK desarrollado por Microsoft. Ventajas Permite obtener soporte del mismo fabricante del dispositivo, lo cual suele ser sinónimo de seguridad para el desarrollador. Documentación de gran calidad muy extensa y detallada. Plataforma en continua evolución, con releases del SDK muy frecuentes y de gran calidad. Esto se traduce a un ciclo de liberación relativamente rápido (un ejemplo de ello es que en tan solo en año y medio se han liberado 5 releases) con importantes mejoras y novedades en cada release. Amplia compatibilidad entre las diversas versiones del SDK, es decir, es posible realizar tanto el donwgrade como el upgrade de una aplicación de manera relativamente cómoda y sencilla para el desarrollador. Gran variedad de APIs fáciles de emplear y bien diseñadas. Por lo general, estas APIs ofrecen un buen comportamiento y rendimiento. 46 Permite emplear diversos lenguajes de programación como C/C++ y .NET. Todas las prestaciones se encuentran integradas en el mismo SDK sin necesidad de integrar diferentes módulos para cada funcionalidad. Desventajas Sólo es compatible con el sensor Kinect desarrollado por Microsoft. Por lo tanto, el desarrollador queda atado a que su código sólo pueda ser empleado por este dispositivo. Sólo esta disponible para el sistema operativo Windows de Microsoft. Por este motivo, si el desarrollador desea emplear este SDK desde otras plataformas, el desarrollador debe emplear máquinas virtuales con los inconvenientes que eso conlleva. Fuertemente ligado a las herramientas ofrecidas por Microsoft, como es el caso del IDE Visual Studio. El código no es open source, por lo que el uso del SDK requiere aceptar el acuerdo de licencia de software impuesto por Microsoft. Constituye un ecosistema muy cerrado, por lo que la integración de módulos o middleware de terceros puede resultar una tarea bastante tediosa. Microsoft prohíbe distribuir código con su SDK que utilice o acceda a las características de los sensores de Kinect que no sean porporcionados por el propio SDK. Microsoft prohíbe distribuir aplicaciones de Kinect para Windows para usarlas con un sensor distinto del sensor de Kinect para Windows y sus controladores y software de ejecución asociados. Microsoft prohíbe distribuir código con el fin de que sea ejecutado en una plataforma distinta del sistema operativo Microsoft Windows. Microsoft prohíbe modificar o distribuir el código fuente proporcionado por el SDK. 4.1.8.2. OpenNI Establecido en Noviembre de 2012, Open Natural Interaction (O PEN NI) es un consorcio sin ánimo de lucro que fue formado con el objetivo de promover y estandarizar la compatibilidad e interoperabilidad de la Internación Natural (IN), dispositivos, aplicaciones y middleware. Actualmente, O PEN NI es uno de los frameworks de desarrollo con sensores en tres dimensiones más importantes, siendo además su SDK de código abierto un estándar reconocido para el desarrollo de middleware de visión por computador y soluciones en tres dimensiones. La comunidad O PEN NI proporciona a los desarrolladores una amplia gama de herramientas software, junto con una plataforma de ecosistemas en continua evolución para la colabora47 ción y la promoción de manera efectiva. Para ello abordan el ciclo de vida completo de desarrollo: Descubrimiento: En la comunidad O PEN NI un desarrollador podrá encontrar todo lo que necesita para desarrollar el uso de la tecnología de detección en tres dimensiones incluyendo el apoyo, recursos, tutoriales, software, bibliotecas de middleware, aplicaciones y una plataforma de intermediación activa. Desarrollo: La comunidad ofrece a los desarrolladores una plataforma de código abierto que les permite desarrollar middleware de IN y aplicaciones orientadas a diversos mercados, como son la robótica, la televisión, los videojuegos, ordenadores o dispositivos móviles, la sanidad, etc. Distribución: O PEN NI proporciona a los desarrolladores una plataforma de marketing para mostrar sus innovaciones, abriendo de esta manera la puerta hacia nuevas oportunidades. 4.1.8.2.1. Descripción del framework El framework que ofrece O PEN NI es un framework “open source” bajo una licencia “GNU Lesser General Public License (LGPL)” que proporciona numerosas APIs para el desarrollo de aplicaciones basadas en el paradigma de interacción natural con el usuario, es decir, una interacción basada en los sentidos del ser humano como pueden ser el oído o la vista. Para ello, este framework simplifica la comunicación con una gran variedad de sensores de audio, vídeo y profundidad incorporados en los dispositivos hardware compatibles, como son por ejemplo Kinect o el AXUS Xtion (ver Figura 4.37), donde ambos están basados en el chip PS1080 de PrimeSense. También facilita la comunicación con diversos middlewares de percepción que se encargan de analizar e interpretar los datos que son obtenidos de una escena mediante algoritmos de visión por computador. Un ejemplo de ello podría ser un software que tras recibir imágenes, es capaz identificar la posición de los usuarios que están presentes en la escena. Figura 4.37: AXUS Xtion [web14d]. Como se puede apreciar en la Figura 4.38, este framework proporciona a las aplicaciones una interfaz de comunicación con los diferentes sensores hardware disponibles y, también, 48 con los diferentes componentes middleware que se integren en el framework. Es importante destacar que únicamente proporciona interfaces, por lo que relega la lógica necesaria para cada funcionalidad a los diferentes componentes, sean sensores o middlewares; de este modo, algunas operaciones de la API estarán implementadas por los dispositivos hardware y otras por los diferentes componentes middleware. Así, por ejemplo, el framework proporciona operaciones que permiten obtener el mapa de profundidad (véase § 4.1.6.2) de una escena dada o los datos en crudo de la cámara RGB desde los sensores, cuya lógica estará implementada en el propio sensor. Figura 4.38: Arquitectura del framework O PEN NI 2 [web14u]. De manera análoga, para los diferentes componentes middleware el framework proporciona operaciones que permiten obtener diferentes datos, como por ejemplo la posición del usuario, cuya lógica estará implementada en el propio middleware. De esta forma, los distintos proveedores de hardware y middleware O PEN NI pueden desarrollar su propia implementación de las diferentes funcionalidades provistas por O PEN NI y posteriormente integrarlas en el framework para su utilización. Además, también permite registrar varios componentes que implementen la misma funcionalidad y elegir cuál de ellos utilizar al momento de solicitar los datos. Esta API común provista por O PEN NI lo hace extremadamente flexible para la incorporación de nuevos componentes middleware, así como también para el desarrollo y ejecución de aplicaciones, que pueden utilizar la API de forma trasparente e independiente del dispositivo hardware o sensor que haya generado los datos. Un punto muy positivo de este framework es que, además de todo el soporte que pro49 porciona la comunidad a través de su documentación y sus foros oficiales, ofrece una gran cantidad de ejemplos que facilitan en gran medida los primeros pasos para comenzar a familiarizarse con el entorno. En la última versión del framework, O PEN NI 2.2 Beta, se encuentran los siguientes ejemplos: SimpleRead: Muestra cómo codificar una aplicación de consola que abre un flujo de profundidad y lee los frames recogidos. MultipleStreamRead: Muestra la misma funcionalidad que el ejemplo SimpleRead, pero utilizando tanto el flujo de profundidad como el de color. SimpleViewer: Muestra cómo implementar una aplicación con interfaz gráfica que abre flujos de profundidad y de color mostrándolos por pantalla de forma simultanea. MultiDepthViewer: Muestra cómo implementar una aplicación que abre flujos de profundidad y de color simultáneamente desde varios sensores conectados en el mismo ordenador. EventBasedRead: Muestra la misma funcionalidad que el ejemplo SimpleRead pero usando una API basada en eventos. MWClosestPoint: Muestra cómo desarrollar un nuevo middleware sobre O PEN NI. En este caso concreto analiza muestra de frames pare encontrar el píxel más cercano. MWClosestPointApp: Muestra cómo implementar una aplicación de consola que emplea el middleware MWClosestPoint. ClosestPointViewer: Muestra cómo implementar una aplicación con interfaz gráfica que emplea el middleware MWClosestPoint. Otro aspecto interesante que ha aparecido con la segunda versión del SDK de O PEN NI es que se ha solucionado la incompatibilidad de los drivers que existían hasta entonces entre el driver de este y el que proporcionaba el SDK de Microsoft. No obstante, cada día se está llegando más lejos consiguiendo propuestas muy interesantes, como la presentada por Tomoto S. Washio: “kinect-mssdk-openni-bridge”. Esta solución (ver Figura 4.39) pretende ofrecer un módulo que conecte el SDK de Microsoft con el framework de O PEN NI, permitiendo de esta manera desarrollar aplicaciones que hagan uso de ambas plataformas de manera simultanea. No obstante, es muy probable que en futuras versiones del framework de O PEN NI ambas plataformas sean compatibles por defecto sin necesidad de módulos extra. Plataformas soportadas Hardware soportado: Ordenadores basados en arquitecturas x86: Pentium 4, 1.4 GHz o superiores o AMD Athlon 64/FX 1 GHz o superiores. 50 Figura 4.39: Solución propuesta por Tomoto S. Washio [web14m]. Sistemas operativos soportados: Windows XP (32/64 bits) con SP2 y superiores, Windows 7 (32/64 bits) y Windows 8 (32/64 bits). OSX 10.7 y superiores. Ubuntu 12.04 (32/64 bits) y superiores. Entornos de desarrollo soportados: Microsoft Visual Studio 2008 y 2010. GCC 4.x. NiTE y otros middlewares de interés Actualmente existe una gran variedad de middlewares para O PEN NI. No obstante, uno de los más importantes y conocidos es “NiTE” (el cual será empleado para el desarrollo del presente proyecto). NiTE ha sido desarrollado por PrimeSense (creador del hardware de Kinect), constituyendo uno de los middleware más avanzados y robustos en el campo de visión por computador. Entre los muchos beneficios que los diferencian de otras alternativas disponibles en el mercado, destacan los siguientes: Amplias posibilidades de configuración, ofreciendo una solución flexible y extensible por lo usuarios del estándar definido por O PEN NI. Soporte multiplataforma, estando disponible para Windows, Linux, OS X y Android. Mínima carga de CPU, estando optimizado para arquitecturas ARM x86. Gran escalabilidad. Implementado en C/C++. 51 NiTE se integra perfectamente con O PEN NI, proporcionando una API clara y cómoda de usar. Este middleware implementa potentes algoritmos que trabajan a partir de los datos obtenidos de la cámara RGB, del sensor de profundidad y de los micrófonos que incorpora el dispositivo hardware. De esta forma, permite al desarrollador obtener un mayor nivel de abstracción y realizar funciones muy interesantes. A continuación se muestran algunas de las más destacadas: Localización y seguimiento de manos. Analizador de escena, permitiendo aislar al usuario del fondo. Seguimiento preciso de la ubicación y orientación de las articulaciones de los usuarios. Reconocimiento de varios gestos. Aunque NiTE es el más conocido, no es el único middleware disponible a los desarrolladores para integrar en el framework O PEN NI. Gracias a la filosofía de esta comunidad open source, cada día aparecen nuevos e interesantes componentes creados por desarrolladores del todo el mundo y que son puestos al alzance de todo aquel que quiera utilizarlos. A continuación se exponen brevemente alguno de los más llamativos hasta el momento: 3D Hand (ver Figura 4.40): Middleware desarrollado por Foundation for Research and Technology-Hellas (FORTH) que permite el seguimiento en tres dimensiones de la mano humana, así como su orientación y articulación. Todo ello es posible sin necesidad de realizar ningún proceso previo de calibración ni la necesidad de emplear ningún tipo de guantes especiales [web14h]. Figura 4.40: 3D Hand [web14h]. KScan3D (ver Figura 4.41): Solución desarrollada por LMI Technologies, una empresa líder en escaneo 3D, que proporciona un proceso completo para escanear y procesar 52 datos en tres dimensiones. Para ello, incorpora un editor gráfico que permite escanear, editar, procesar y exportar los datos obtenidos en diferentes formatos, como por ejemplo .obj o .fbx. Figura 4.41: Resultado obtenido con KScan3D [web14a]. SigmaNIL (ver Figura 4.42): Solución propuesta por SigmaRD Computer Vision & Graphics que consiste en un framework para el desarrollo de interfaces de usuario con capacidades de reconocimiento de gran precisión, como los dedos de las manos o formas, así como seguimiento y reconocimiento del esqueleto y de las manos de los usuarios. 4.1.8.2.2. Evolución del framework Como consecuencia de un minucioso análisis de la anterior API de O PEN NI, la versión 1.5, la comunidad fue consciente de que muchas de las funcionalidades que hasta aquel entonces eran incluidas en el framework raramente eran utilizadas por los desarrolladores. Como 53 Figura 4.42: Ejemplo de gesto reconocido con SigmaNIL [web14y]. consecuencia PrimeSense decidió realizar un importante lavado de cara al SDK reduciendo en gran medida la complejidad de la API. El primer y principal cambio que se llevó a cabo fue simplificar la interfaz middleware (ver Figura 4.43). De esta forma, O PEN NI es ahora simplemente un API cuyo único objetivo es llevar a cabo la comunicación entre los diferentes sensores a través de los drivers y las aplicaciones o middlewares de terceros. Con esta nueva arquitectura, los desarrolladores de middleware tan sólo deben ser construidos para ser ejecutados por encima de O PEN NI. Sin embargo, en la anterior versión toda esta funcionalidad era proporcionada directamente por O PEN NI mediante la adicción de plug-in’s, dando como resultado una plataforma mucho más compleja de mantener y un API demasiado difícil de manejar. Figura 4.43: Evolución de la arquitectura O PEN NI [web14u]. El segundo cambio que se realizó fue el de simplificar los tipos de datos, como por ejemplo los mapas de profundidad. Estos en un principio eran mapeados como metadatos, lo cual era mucho más complejo de manipular e interpretar que las actuales matrices de profundidad. También se produjeron otros cambios de gran interés para facilitar su aprendizaje y com54 prensión, como por ejemplo la reducción del numero de clases existentes. De este modo, se pasó de tener más de cien clases complejas, estructuras de datos y enumeraciones a tener poco más de una docena. Como resultado se obtuvo una librería que se centraba principalmente en tan sólo cuatro clases: openni::OpenNI. openni::Device. openni::VideoStream. openni::VideoFrameRef. Finalmente, el último cambio significativo que se produjo fue el de implementar un proceso más eficiente para la notificación de eventos. Hasta aquel momento, los datos capturados por los sensores eran accedidos colocando un bucle alrededor de la función que los proporcionaba. Por el contrario, aunque aún sigue siendo posible realizarlo de la anterior manera, en O PEN NI 2 se ofrecen funciones especiales que reciben un evento cuando un nuevo frame, por ejemplo, es capturado. 4.1.8.2.3. Ventajas y desventajas A continuación se describen los pros y los contras de emplear la segunda versión del SDK de O PEN NI. Ventajas Soporta las últimas generaciones de sensores 3D. Fácil para el desarrollo con una API clara y en continua mejora. Amplia portabilidad y soporte multiplataforma, ya que se encuentra disponible para Windows, Linux y OS X. Código “open source”, distribuído bajo una licencia “GNU Lesser General Public License (LGPL)”. Documentación muy extensa y detallada. Permite programación orientada a eventos. Existe una gran variedad de librerías middleware de terceros: Seguimiento del cuerpo, reconstrucción en tres dimensiones, reconocimiento de objetos, etc. Compatible con otro de los principales SDKs para Kinect, como es el SDK desarrollado por Microsoft. 55 Desventajas El núcleo de la plataforma se encuentra muy fragmentado, ya que la segunda versión del SDK O PEN NI fue separada del middleware NITE. Por este motivo, ahora es necesario emplear dos SDK diferentes para llevar a cabo muchas de las tareas básicas. Pocos lenguajes de programación soportados. Este dato resulta muy curioso ya que la primera versión del SDK O PEN NI ofrecía soporte a C/C++, .NET/C# y Java. No obstante, con la reescritura del núcleo de O PEN NI en su geunda versión de SDK, tan sólo es posible emplear C/C++. Es incompatible con el SDK de OpenKinect. 4.1.8.3. OpenKinect Como ya se menciono anteriormente (véase § 4.1.2.3), OpenKinect es una comunidad abierta de personas interesada en obtener el máximo provecho del hardware de Kinect mediante ordenadores y otros tipos de dispositivos, siempre bajo una licencia Apache 2.0 o GPL2. Esta comunidad, que surge el 6 de Noviembre de 2010 como un grupo de personas interesadas en ganar el concurso propuesto por Johnny Chung Lee y AdaFruit cuyo objetivo era desarrollar un controlador para el dispositivo e implementar una aplicación que convirtiera los flujos de datos del sensor de vídeo y visión de profundidad de Kinect, cuenta ya con más de dos mil miembros que contribuyen día a día ofreciendo su tiempo y esfuerzo. Es importante destacar que su esfuerzo y dedicación fue una pieza clave para la aparición de otras plataformas de desarrollo para Kinect como son el SDK de Windows (véase § 4.1.8.1) y O PEN NI (véase § 4.1.8.2). 4.1.8.3.1. Descripción del framework Su principal y más popular librería es “libfreenect”. Esta librería incluye todo el código necesario para activar, inicializar y comunicar datos con el hardware de Kinect. Se trata de una librería de muy bajo nivel que incluye los drivers necesarios para trabajar con sistemas operativos basados en Windows, Linux y OS X. El API que proporciona ofrece soporte y extensiones para los siguientes lenguajes/plataformas: C. C++. .NET (C# y Visual Basic). Java (Java Native Access (JNA) y Java Native Interface (JNI)). Python. C Synchronous Interface. 56 Además, la librería se comunica con el API de OpenKinect y analiza los datos en crudo que son obtenidos por el dispositivo para proporcionar a los desarrolladores un mayor nivel de abstracción. Aunque la librería se encuentra en continua evolución, aún se sigue trabajando para conseguir o mejorar las siguientes funcionalidades: Seguimiento de la posición de las manos. Seguimiento del esqueleto humano. Procesamiento de datos de profundidad especializados. Cancelación de ruido en el audio. Generación de nubes de puntos. Reconstrucción en tres dimensiones. La actual librería cuenta a día de hoy con una gran variedad de wrappers para facilitar la tarea del desarrollador, como son: Python, C Synchronous, C++, C#, Java JNI, Java JNA, Javascript, Common Lisp y GFreenect (GLib). Por último, tan sólo destacar que la librería cuenta con dos herramientas bastante interesantes. La primera de ellas es “Record”, la cual permite realizar un volcado de los datos obtenidos a través de los sensores de Kinect en diferentes formatos como PPM o PGM. Y la segunda, “Fakenect”, que consiste en un simulador que permite realizar pruebas de las aplicaciones sin necesidad de tener una Kinect. 4.1.8.3.2. Ventajas y desventajas A continuación se describen los pros y los contras de emplear la librería libfreenect desarrollada por la comunidad OpenKinect. Ventajas Soporta una gran cantidad de wrappers y lenguajes de programación. Código “open source”, distribuído bajo una licencia Apache 2.0 o GPL2. Amplia portabilidad y soporte multiplataforma, ya que se encuentra disponible para Windows, Linux y OS X. Desventajas Librería de muy bajo nivel. Pocas funcionalidades implementadas. 57 No tiene soporte. Muy poca documentación. No es compatible con otras plataformas como el SDK de Kinect y O PEN NI. Sólo es compatible con el sensor Kinect desarrollado por Microsoft. Por lo tanto, el desarrollador queda atado a que su código sólo pueda ser empleado por este dispositivo. 4.2 Visión por computador El campo de visión por computador es un área que puede ser considerada relativamente novedosa y que actualmente se encuentra en constante expansión [TV98]. No obstante, este campo retrasó su despliegue hasta hace tan sólo unos cuarenta años debido a las grandes dificultades que se encontraban al procesar las grandes cantidades de información que proporcionaban las imágenes. Es importante destacar que esta rama de la tecnología abarca un amplio espectro de problemas cuyas soluciones normalmente suelen encontrase relacionadas con otras disciplinas como pueden ser el procesamiento de imágenes, la inteligencia artificial, visión robótica, etc. Quizá, este sea el motivo por el cuál no hay definido un estándar que marque los límites entre visión por computador y otras muchas disciplinas. Además, también es posible establecer que hasta el momento no existe una formulación estándar de cómo la visión por computador debería resolver los diversos problemas que se plantean. Muchos de las soluciones que se plantean a problemas concretos y bien definidos aún se encuentran en fase de investigación. No obstante, cada vez existen más métodos que pueden presentar posibles usos comerciales, contribuyendo por lo tanto a popularizar la visión por computador y su muchas aplicaciones. A continuación se comentan algunos de los usos ya explotados de la visión por computador en los diferentes campos en los que ya se encuentran disponibles aplicaciones que empleen esta disciplina: Medicina: En la actualidad hay una gran multitud de aplicaciones médicas que hacen uso de la visión por computador, convirtiéndose en herramientas imprescindibles para diferentes tareas. Una de las más destacadas es la diagnosis de enfermedades ya que mediante el uso de estas herramientas es posible destacar aquellas zonas que resultan de vital importancia en las imágenes que son proporcionadas por sensores y escáneres de diversos tipos como por ejemplo las ecografías. Educación: Se han desarrollado una gran multitud de aplicaciones en este campo con el objetivo de hacer de la enseñanza una tarea más atractiva, dinámica y eficiente. Se podrían mencionar una gran cantidad de ejemplos, pero uno de los más interesantes y que cada vez más gente tiene la oportunidad de utilizar son los libros de realidad aumentada donde es posible interactuar con modelos en tres dimensiones. 58 Entretenimiento: Como ya se viene mencionando en las secciones anteriores, una de las aplicaciones más populares y extendidas que hacen uso de la visión por computador con el objetivo de proporcionar entretenimiento son los videojuegos. No obstante, existen muchas otras aplicaciones que van más allá de los juegos como podría ser el uso de reconocimiento de edificios emblemáticos permitiendo de esta manera obtener información interesante desde un punto de vista turístico. Robótica: Uno de los campos que se encuentra más estrechamente relacionado con la disciplina de visión por computador es la robótica. Ejemplo de ello pueden ser los robots autónomos que requieren de la reconstrucción de escenas y el rastreo de caminos. Accesibilidad: Quizás sea uno de los campos más “pioneros” donde la aplicación de técnicas de visión por computador pueden resultar de gran ayuda. Para ello, cada día son desarrolladas más y más aplicaciones que tienen como principal objetivo el proporcionar una ayuda extra a aquellas personas que sufren alguna discapacidad. Un ejemplo muy ilustrativo de ello podría ser que las personas que padecen problemas de visión sean capaces de esquivar eficientemente obstáculos mediante señales acústicas proporcionadas por un sistema basado en visión por computador. En las siguientes subsecciones se pretende ofrecer una breve recapitulación del trabajo que ha sido realizado para resolver el problema del reconocimiento de acciones humanas desde la perspectiva de la visión por computador. También se presentan algunas técnicas para el reconocimiento de acciones basado en vídeo. 4.2.1 Perspectiva de visión por computador Desde la perspectiva de la visión por computador se han ideado diferentes enfoques que tratan de hacer frente al problema del reconocimiento de acciones humanas. Un ejemplo de ello es el trabajo desarrollado por Roberto Vezzani, Davide Baltieri, y Rita Cucchiara en la Universidad de Modena y Reggio Emilia, Italia. Para resolver este paradigma, proponen un modelo para reconocimiento de acciones basado en Hidden Markov Models (HMM) con un histograma de proyección de características [VBC10]. Según su trabajo, la función de probabilidad de emisión se modela como una mezcla de Modelos de Mezclas Gaussianas (GMM), el cual es uno de los métodos de clustering más empleados y el conjunto de características obtenido de los histogramas de proyección. Estos histogramas contienen el número de píxeles en movimiento para cada fila y columna del frame capturado, proporcionando de esta manera información suficiente para inferir la postura tomada en ese momento por la persona. Entonces, el framework HMM recupera la evolución temporal de las posturas reconocidas englobándolas como una acción global. Francisco Martínez-Contreras, Carlos Orrite-Uruñuela, José Elías Herrero Jaraba, Hossein Ragheb y Sergio A. Velastin proponen en la sexta conferencia Institute of Electrical and Electronics Engineers (IEEE) sobre Advanced Video and Signal Based Surveillance (AVSS) 59 un sistema de reconocimiento de acciones humanas [MCOUHJ+ 09]. En su trabajo tratan de abordar el problema de la modelización y reconocimiento de la acción humana basándose en la silueta, especialmente cuando el numero de muestras de acciones son escasas. El primer paso del sistema que proponen es el modelado en dos dimensiones de las acciones humanas basándose en plantillas de movimiento a través de Motion History Images (MHI). Estas plantillas se proyectan en un nuevo subespacio usando el Kohonen Self Organizing feature Map (SOM), el cual se encarga de agrupar las perceptivas (espacial) y los movimientos (temporal) en un colector principal y de modelar el espacio dimensional en plantillas estáticas. El siguiente paso está basado en HMM con el fin de realizar el seguimiento del comportamiento en secuencias temporales de MHI. Cada nuevo modelo MHI se compara con el mapa de características obtenido durante el entrenamiento. En el caso de que el número de muestras no sea suficiente, se aplica el algoritmo Sampling Importance Resampling (SIR) para incrementar el número de observaciones para el HMM. Finalmente, el patrón de reconocimiento temporal es llevado a cabo por un clasificador Maximum Likelihood (ML). Otro ejemplo es el aprendizaje de acciones humanas a partir de películas propuesto por Ivan Laptev, Marcin Marszalek, Cordelia Schmid y Benjamin Rozenfeld [LMSR08]. El objetivo de su trabajo es abordar el reconocimiento de acciones naturales en diversos entornos realistas. Ellos contribuyen a solucionar el problema de la falta de conjuntos realistas de datos de vídeo investigando cómo podrían ser usados los guiones de cine para la anotación automática de acciones humanas. Para ello, evalúan métodos alternativos para la recuperación de acciones y mostrar los beneficios de un clasificador basado en texto presentando de esta manera un nuevo método para la clasificación de la acciones obtenidas en los vídeos. Este nuevo método aprovecha y amplía varias ideas recientes incluyendo características locales espacio-temporales, pirámides espacio-tiempo y Support Vector Machines (SVM) no lineales. 4.2.2 Algoritmos de reconocimiento de acciones basados en vídeo Los algoritmos de reconocimiento de acciones basados en vídeo se basan, principalmente, en el aprendizaje a partir de ejemplos y técnicas basadas en máquinas de aprendizaje como por ejemplo HMM, reducción dimensional o Bag of Words (B OW). A continuación se exponen algunos de los estudios más destacados. Mohiuddin Ahmad y Seong-Whan Lee en [AL08] presentan un método para el reconocimiento de acciones humanas para secuencias simultaneas de imágenes utilizando una combinación de flujos de movimiento y formas. Con este enfoque, las acciones humanas son representadas como un conjunto multidimensional de flujos ópticos Combined LocalGlobal (CLG) y vectores de características de los límites espacio-temporales de la acción. De esta forma, las acciones son modeladas usando un conjunto de HMM multidimensionales para múltiples puntos de vista mediante las características combinadas. Un de los resulta60 dos más interesantes que se obtienen de su investigación es que fue posible demostrar que el reconocimiento de acciones desde múltiples puntos de vista tuvo una tasa de acierto más elevada que con un único punto de vista. Otro estudio interesante es el realizado por Liang Wang y David Suter que versa sobre el aprendizaje visual y el reconocimiento de los colectores de datos secuenciales con aplicaciones para el análisis de movimiento humano [WS08]. En su estudio se distinguen tres etapas bien diferenciadas para el reconocimiento de acciones humanas: Extraer características simples y fiables de las secuencias de imágenes. Para esta etapa son examinadas dos alternativas: La silueta y la silueta transformada a distancia. Encontrar una representación con una baja dimensionalidad de las características extraídas. Esta etapa es el núcleo del proceso, en el cual es empleado Locality Preserving Projections (LPP), que consiste en una aproximación lineal óptima de una técnica espectral no lineal. Caracterizar y clasificar los movimientos en este espacio de características. Tres métodos muy diferentes son usados para esta etapa: 1) Clasificación basada en GMM; 2) un enfoque basado en la distancia media de Hausdorff y 3) modelado y reconocimiento basado en HMM. En esencia, el objetivo de este estudio es demostrar que mediante el núcleo propuesto en la segunda etapa, junto con los diferentes enfoques de las etapas 1 y 3, es posible resolver los problemas a través de varios tipos de la actividad humana. Chin-Hsien Fang, Ju-Chin Chen, Chien-Chung Tseng, Jenn-Jier James Lien proponen en [FCTL10] el framework Temporal-Vector Trajectory Learning (TVTL) para el reconocimiento de acciones humanas. El concepto más importante de este framework es que intentan añadir información temporal en el proceso de reconocimiento de acciones. Para ello, distinguen tres tipos de información temporal: Locations’ Temporal motion of Mahalanobis distance (LTM), Difference’ Temporal motion of Mahalanobis distance (DTM) y Trajectory Temporal motion of Mahalanobis distance (TTM). Con estos tres tipos de información temporal, el clasificador k-NN basado en la distancia Mahanalobis es capaz de obtener mejores resultados que si se utiliza tan sólo la información espacial. Los resultados que obtuvieron de su estudio sugieren que este metodología es capaz de reconocer con bastante precisión las acciones, especialmente con los parámetros TTM y DTM los cuales obtienen elevadas tasas de precisión incluso en entornos que ofrecen información con un ruido elevado. En [LMN10], Michal Lewandowski, Dimitrios Makris, y Jean-Christophe Nebel introducen un nuevo enfoque para aprender de una forma compacta e intuitiva descriptores de los movimientos del cuerpo humano para el reconocimiento de actividades. Según su estudio, cada descriptor de acción se produce, primero, mediante la aplicación de “Temporal Laplacian Eigenmaps” a los vídeos de vistas dependientes. Después, todos los colectores 61 dependientes de la vista son automáticamente combinados para descubrir una representación unificada que es modelada como un único espacio de tridimensional independiente del estilo y punto de vista. También incorporan una función de mapeo no lineal bidireccional que permite la proyección de acciones entre los espacios originales y embebidos. Los resultados experimentales obtenidos de este estudio demuestran que la robustez en contraposición del estilo y de las variaciones de los puntos de vista proporcionan un método más preciso de reconocimiento de acciones. No obstante, ninguno de los enfoques expuestos anteriormente incluyen capacidades de razonamiento. De este modo, su eficiencia esta basada únicamente en el entrenamiento que reciban y en el alcance de todas las acciones presentes en un escenario determinado. Desafortunadamente, todos estos experimentos de reconocimiento de acciones están dirigidos con vídeos que no son representativos en la vida real, siendo demostrado por el pobre rendimiento obtenido con vídeos capturados en entornos no controlados [LMSR08]. En [KJG+ 11] exponen este problema, partiendo del hecho de que los dataset actuales contienen en el orden de diez categorías de acciones distintas recogidas bajo un entorno controlado. Para tratar de resolver este problema, han recogido en un gran dataset con vídeos de acciones con 51 categorías de acciones. Este contiene alrededor de 7000 clips etiquetados manualmente extraídos de una gran variedad de fuentes que van desde películas hasta vídeos de YouTube. En el Cuadro 4.2 se puede observar una tabla comparativa extraída de dicho estudio. Por último, emplearon este dataset para evaluar el rendimiento de dos sistemas de visión por computador para el reconocimiento de acciones y así explorar la robustez de estos métodos bajo varias condiciones, como por ejemplo movimiento de la cámara, punto de vista, calidad del vídeo y oclusión. Dataset Año Acciones Clips KTH Weizmann IXMAS Hollywood UCF Sports Hollywood2 UCF YouTube Olympic UCF50 HMDB51 2004 2005 2006 2008 2009 2009 2009 2010 2010 2011 6 9 11 8 9 12 11 16 50 51 100 9 33 30-129 14-35 61-278 100 50 min. 100 min. 110 Cuadro 4.2: Conjuntos de datos existentes, el número de categorías y el número de clips por categoría ordenados por año Esta teoría fue reforzada por Jean-Christophe Nebel, Michał Lewandowski, Jérôme Thévenon, Francisco Martínez, y Sergio Velastin en [NLT+ 11]. En dicho estudio concluyeron 62 que actualmente no existen técnicas basadas únicamente en visión por computador y máquinas de aprendizaje que sean realmente eficientes para vídeo en tiempo real en aplicaciones de vigilancia. Para llegar a esta conclusión, evaluaron dos de los escenarios más desafiantes para un sistema de reconocimiento de acciones: Las vistas independientes y las interacciones humanas. De este modo, los frameworks más prometedores, como por ejemplo los métodos de “reducción de dimensionalidad“, “Random Forest“ y B OW, son descritos y evaluados en su estudio empleando conocidos datasets como IXMAS y UT-Interaction. 63 Capítulo 5 Método de trabajo E este capítulo se explicará al lector la metodología de desarrollo empleada para la realización de este proyecto. Se mostrarán también las herramientas, tanto hardware como software, utilizadas en la realización del mismo. N 5.1 Metodología de trabajo Para el desarrollo del presente proyecto se considera que la metodología de trabajo más adecuada y que mejor se adapta a la naturaleza y a las necesidades del mismo es una metodología de desarrollo ágil [Mar03]. Esto se debe principalmente a que uno de los objetivos más importantes es el de minimizar los riesgos que pueden conllevar los plazos de entrega del mismo y el no disponer a priori de una especificación totalmente acotada del sistema, sobre todo al comienzo del planteamiento del mismo. Para conseguir este objetivo, se pretende realizar pequeños desarrollos de software en lapsos cortos de tiempo, también conocidos como iteraciones, dónde lo ideal sería que cada uno durase entre una y cuatro semanas. Cada una de estas iteraciones del ciclo de vida del proyecto deberá disponer de las etapas típicas en desarrollo de software: Planificación. Análisis de requisitos: Entender y comprender de forma detallada cual es la problemática a resolver, verificando el entorno en el cual se encuentra dicho problema, de tal manera que se obtenga la información necesaria y suficiente para afrontar su respectiva solución. Diseño: Una vez que se tiene la suficiente información del problema a solucionar, es importante determinar la estrategia que se va a utilizar para resolver el problema. Codificación: Partiendo del análisis y diseño de la solución, en esta etapa se procede a desarrollar el correspondiente sistema que solucione el problema mediante el uso de una herramienta computacional determinada. Revisión: Realizar las debidas pruebas que garanticen el correcto funcionamiento de dicho sistema bajo el mayor número de situaciones posibles a las que se pueda enfrentar. 65 Documentación: Comunicación escrita en sus diferentes formas, ya sea en enunciados, procedimientos, dibujos o diagramas que se hace sobre el desarrollo de un programa. Sirve para ayudar a comprender o usar un sistema o para facilitar futuras modificaciones. De esta forma, la metodología ágil que más se aproxima a las necesidades del proyecto es Scrum [SB01]. Este enfoque resulta muy atractivo para el desarrollo del proyecto ya que Scrum fomenta la comunicación entre los miembros del proyecto (en este caso, el alumno y los directores del proyecto), evitando de esta manera posibles desvíos durante el desarrollo. Además, Scrum adopta una aproximación pragmática, aceptando de esta manera que el problema no puede ser completamente entendido o definido desde el principio y que la idea inicial sobre el sistema puede ir cambiando o evolucionando, por lo que pueden surgir desafíos impredecibles que pueden no ser fácilmente enfrentados de una forma predictiva y planificada, permitiendo además responder a requisitos emergentes. Como se puede apreciar, en un proyecto dónde gran parte del trabajo reside en la investigación y en la búsqueda de soluciones a problemas aún en fases muy tempranas de su madurez, se ha considerado que esta aproximación resulta verdaderamente acertada e interesante. Para facilitar la comprensión de la planificación que se ha llevado a cabo en el proyecto, en el siguiente subapartado se describen los conceptos más importantes de Scrum así cómo las fases en las que se compone, los roles y responsabilidades de las personas que participan en el proceso y las prácticas seguidas. No obstante, si el lector ya se encuentra familiarizado con el proceso de desarrollo Scrum se recomienda comenzar directamente por la lectura del segundo subapartado (véase § 5.1.2) dónde se describe la planificación llevada a cabo a lo largo del desarrollo del proyecto. 5.1.1 Acerca de Scrum Scrum [ASRW02] es un proceso en el que se aplican de manera regular un conjunto de buenas prácticas para trabajar colaborativamente y obtener el mejor resultado posible de un proyecto. Estas prácticas se apoyan unas a otras y su selección tiene origen en un estudio de la manera de trabajar de equipos altamente productivos. En Scrum se realizan entregas parciales y regulares del producto final, priorizadas por el beneficio que aportan. Por ello, Scrum está especialmente indicado para proyectos en entornos complejos, dónde se necesita obtener resultados pronto, los requisitos son cambiantes o poco definidos o dónde la innovación, la competitividad, la flexibilidad y la productividad son fundamentales. Scrum también está enfocado en dar soporte al desarrollo de sistemas que conllevan diversas variables cómo pueden ser el tiempo, recursos y tecnología y que pueden cambiar a lo largo del proceso. De esta manera, el proceso de desarrollo se convierte en una labor alarmantemente impredecible y compleja, requiriendo flexibilidad para ser capaz de responder a los cambios que puedan ir apareciendo. 66 Además, el proceso Scrum permite mejorar la existencia de prácticas ingenieriles en la organización [MDD10], ya que involucra diversas actividades de gestión orientadas a la identificación de las potenciales deficiencias o impedimentos que aparecen en el desarrollo del proceso, así como las prácticas empleadas. 5.1.1.1. Fases de Scrum La metodología de desarrollo Scrum esta compuesta de tres fases: Pre-game: Esta primera fase está compuesta a su vez por dos subfases conocidas cómo planificación y diseño de alto nivel del sistema. La primera subfase abarca el desarrollo de la especificación del sistema que se pretende desarrollar así cómo la creación del “Product Backlog list”. El Product Backlog list es una lista que contiene los requisitos del proyecto, también conocidos como “historias de usuario” (creadas por el cliente en su propio lenguaje). Además se asigna un orden de prioridad a cada requisito identificado del sistema permitiendo conocer cuáles deberían ser implementados primero y una estimación aproximada del esfuerzo requerido para medir su nivel de dificultad. No obstante, esta lista cambia dinámicamente siendo actualizada continuamente mediante la adicción de nuevos requisitos, limitaciones, herramientas, etc. La segunda subfase, el diseño de alto nivel del sistema, consiste en el desarrollo de un primer diseño de alto nivel sobre el sistema a implementar incluyendo las decisiones de diseño que deben ser aplicadas posteriormente. Development: En esta fase, también conocida cómo fase de desarrollo, se lleva a cabo el proceso de decisión de que historias de usuario van componer cada una de las iteraciones o “Sprints”. Las iteraciones son intervalos de tiempo con una duración aproximada que oscila entre dos y cuatro semanas y que a su vez están compuestas por fases más pequeñas: Análisis, diseño, implementación, pruebas y entrega. Esta fase es iterativa e incremental dónde se van obteniendo las diferentes versiones y módulos del sistema. Por último, es importante destacar que cada una de de las iteraciones llevadas a cabo finalizan con una reunión dónde se analiza si los objetivos marcados al comienzo de la iteración han sido alcanzados y el nivel de satisfacción de los resultados obtenidos. Post-game: Fase final tras haber cumplido los requisitos de entrega pactados al comienzo del desarrollo. Abarca la preparación para el lanzamiento de la versión, incluyendo la documentación final y pruebas antes del lanzamiento de la versión. En la Figura 5.1 se muestra un simple esquema a modo de resumen de cada una de las actividades que se llevan a cabo en cada una de las fases descritas anteriormente con sus correspondientes entradas y salidas. 67 Figura 5.1: Fases de Scrum [web14z]. 5.1.1.2. Roles y responsabilidades Aunque en Scrum se pueden diferenciar hasta seis roles (Scrum Master, Product Owner, Scrum Team, Customer, User y Management) con diferentes propósitos, el presente apartado se centra en la descripción de los principales definiendo cuáles son las responsabilidades de cada uno así como las tareas que deben despeñar: Product Owner: Representa la voz del cliente. Se asegura de que el equipo Scrum trabaje de forma adecuada desde la perspectiva del negocio. El Product Owner escribe historias de usuario, las prioriza y las coloca en el Product Backlog. Scrum Master: Desempeña el rol de administrador dentro del proceso Scrum. Es el responsable de asegurar que el proyecto es realizado de acuerdo a las prácticas establecidas, además de que el proyecto evoluciona según lo previsto. También desempeña el rol de líder del Scrum Team cuando se presenta algún obstáculo y de mantener el equipo de modo que se ocupe de las tareas de la forma más productiva posible. Scrum Team: Pequeño equipo con las habilidades transversales necesarias para realizar el trabajo (análisis, diseño, desarrollo, pruebas, documentación, etc.) y que tiene la responsabilidad de entregar el producto. También poseen la autoridad para decidir sobre las acciones y la organización necesaria para alcanzar los objetivos. Por último, también destacar que están involucrados en la toma de decisiones en cuanto a estimación del esfuerzo. 68 No obstante, existen otros roles auxiliares en los “Scrum Team” que no tienen un rol formal y no se involucran frecuentemente en el proceso Scrum, sin embargo deben ser tomados en cuenta. Un aspecto importante de una aproximación ágil es la práctica de involucrar en el proceso a los usuarios, expertos del negocio y otros interesados (stakeholders). Es importante que esa gente participe y entregue retroalimentación con respecto a la salida del proceso a fin de revisar y planear cada sprint. A continuación una breve descripción: StakeHolders: Hacen posible el proyecto y para quiénes el proyecto producirá el beneficio acordado que justifica su producción. Sólo participan directamente durante las revisiones del sprint. Management: Establecen el ambiente para el desarrollo del producto. 5.1.1.3. Prácticas y conceptos relevantes Cómo ya se anticipaba en lo párrafos anteriores, uno de los principales objetivos del proceso Scrum es hacer frente a los cambios y problemas que puedan ir surgiendo a lo largo del proyecto. Para conseguir este propósito se llevan a la práctica diferentes conceptos para aumentar la comunicación entre los miembros participantes en el proyecto, así como una clara división de los roles que desempeñan cada uno. A continuación se exponen los conceptos más relevantes. Sprint/Iteración Período en el cual se lleva a cabo la mayor parte del trabajo. Aunque lo recomendable es que la duración de los sprints sea constante y definida por el equipo con base en su propia experiencia, es posible comenzar con una duración de sprint en particular (entre 2 y 4 semanas) e ir ajustándolo con base en el ritmo del equipo. Algunas de las actividades más importantes que se deben realizar son las reuniones de planificación de sprints, reuniones diarias y sprint backlog. Al final de cada sprint, el equipo deberá presentar los avances logrados. El resultado obtenido es un producto potencialmente entregable al cliente. Asimismo, se recomienda no agregar objetivos al sprint o sprint backlog a menos que la falta de estos objetivos amenace al éxito del proyecto. En la Figura 5.2 se presenta un pequeño esquema que muestra las diferentes entradas y salidas que se dan lugar en una iteración completa de Scrum. Product Backlog Documento de alto nivel para todo el proyecto que define las descripciones genéricas de todos los requisitos y las funcionalidades deseables que debe contener el producto final basándose en el conocimiento actual que se tiene del mismo. De esta forma, el Product Backlog está compuesto por una lista de requisitos ordenados por la prioridad de los mismos y están acompañados de estimaciones realizadas a grandes rasgos (valor aportado y esfuerzo de desarrollo requerido). Es abierto y sólo puede ser modificado por el Product Owner, representando de esta forma la visión del clien69 Figura 5.2: Iteración de la metodología Scrum [web14z]. te respecto a los objetivos del proyecto. Por último, es importante mencionar que se encuentra en continua evolución y suele ser modificado a lo largo de las iteraciones. Estimación de esfuerzo Realizado por el Product Owner junto con el equipo de desarrollo y consiste en un proceso interactivo dónde se pretende realizar una aproximación del esfuerzo requerido para llevar a cabo cada uno de los elementos descritos en el Product Backlog. Es importante mencionar que las estimaciones tendrán una mayor grado de precisión cuanta mayor sea la cantidad de información que se tenga acerca del proceso a estimar. Aunque existen diversas técnicas para realizar este tipo de procesos de estimación, uno de los más comunes es el juicio de expertos1 . Sprint Backlog Documento detallado que constituye el punto de partida de cada sprint o iteración. Está constituido por los elementos del Product Backlog que deben ser implementados en el presente Sprint y que han sido seleccionados por los miembros del equipos de desarrollo y el Product Owner en la “Sprint Planning meeting”. Es importante destacar que las tareas identificadas son divididas en horas pero que ninguna debe tener una duración superior a dieciséis horas. De este modo, si una tarea es mayor de dieciséis horas, deberá ser dividida en otras menores. Sprint Planning meeting Reunión organizada por el Scrum Master que es realizada al comienzo de cada Sprint. Esta compuesta por dos fases. En la primera el objetivo es definir los objetivos y funcionalidades que deben ser desarrollos en el siguiente Sprint, por lo que participan el cliente, Scrum Master, Scrum Team y administradores. Por el contrario, en la segunda fase tan sólo toman parte el Scrum Master y el Scrum Team con la finalidad de decidir el plan necesario para abordar las tareas planificadas para el 1 Técnica compuesta por un conjunto de opiniones que pueden brindar profesionales expertos en una industria o disciplina, relacionadas al proyecto que se está ejecutando. 70 siguiente Sprint. Daily Scrum meeting Reuniones realizadas diariamente que permiten tener información de seguimiento de primera mano. Deben ser cortas (no más de quince minutos) y son dirigidas por el Scrum Master. A parte de discutir acerca de los problemas que han aparecido, se debe responder a tres preguntas: ¿Qué has hecho desde ayer?, ¿Qué es lo que harás hasta la reunión de mañana? y ¿Has tenido algún problema que te haya impedido alcanzar tu objetivo?. Sprint Review meeting Reunión realizada el último día del sprint en la que el Scrum Master y el Scrum Team presentan los resultados (prototipo) obtenidos al final del Sprint a los interesados (cliente, usuario, administradores, etc.). Además, tras esta reunión se debe haber tratado sobre el trabajo que fue completado y no completado. Importante mencionar que no debe durar más de cuatro horas. 5.1.2 Descripción de la planificación En primer lugar, y antes de proceder a al desarrollo de las diferentes fases que se definen en Scrum, es importante mencionar como se han repartido los roles y responsabilidades durante el desarrollo del proyecto: Product Owner: Este rol será desempeñado principalmente por los directores del proyecto, quienes irán guiando de forma orientativa cuáles son los objetivos a conseguir con el proyecto, requisitos (historias de usuario), etc. No obstante, este rol también puede estar desempeñado por el alumno ya que será la última persona en decidir la dirección que va adoptando el proyecto. Scrum Master: Este rol será desempeñado únicamente por los directores del proyecto. Esto tiene sentido ya que, además de realizar las funciones típicas de un usuario estableciendo los requisitos, también van marcando las pautas necesarias para una correcta evolución del proyecto, resolución de problemas encontrados, desempeño de rol de líder, etc. Scrum Team: Mientras que en la definición original de Scrum el equipo está compuesto de varios integrantes, en el presente proyecto este rol es desempeñado únicamente por el alumno. Respecto a los sprints es importante mencionar que el producto obtenido al final de cada iteración no tiene porque ser estrictamente un módulo del sistema a desarrollar, sino que también debe considerarse cómo producto el conocimiento generado y los conceptos adquiridos, necesarios para la correcto desarrollo del proyecto y la implementación de los diferentes módulos. Por último, tan sólo destacar que los diferentes tipos de reuniones que presenta Scrum, así cómo su frecuencia y duración se han tratado de cumplir lo máximo posible. No obstante, al 71 tratarse un proyecto elaborado a lo largo de un curso académico ha sido necesario compaginarlo con más actividades docentes. De este modo, al igual que ocurre con la duración de los sprints, ha sido necesario adaptarlo a los intervalos de tiempo asignados a esta actividad docente así como a la disponibilidad de los directores. 5.1.2.1. Fase 1: Pre-game El principal objetivo de esta fase es la elaboración del Product Backlog. Para ello, se han definido los requisitos o historias de usuario que debe reunir el proyecto a un nivel de abstracción considerablemente elevado. La motivación de esto se debe a que al proyecto contiene diversas tareas de investigación y, por tanto, no se conocen a priori todos los aspectos que pueden surgir durante su desarrollo, las técnicas que se van a emplear ni resultados que se van obtener. Estos requisitos quedan definidos en el capítulo de Objetivos (véase § 2). No obstante, a continuación se muestra un listado de ellos junto con la correspondiente estimación del esfuerzo requerido: Evaluación de mercado: Primer objetivo ya que en función de los resultados obtenidos se determinará que dispositivo se empleará para realizar el proceso de capturas de imágenes. El esfuerzo requerido para cumplimentar este requisito es principalmente de labores de documentación y, por lo tanto, el tiempo estimado estará sujeto a la cantidad de información disponible. Análisis de librerías disponibles: El esfuerzo requerido para cumplimentar este requisito es principalmente de labores de documentación y, por lo tanto, el tiempo estimado estará sujeto a la cantidad de información disponible, dificultad de las diferentes librerías, etc.). Identificación y análisis de los datos recogidos por el dispositivo: El esfuerzo requerido para cumplimentar este requisito supone la adquisición de habilidades técnicas y conceptos de diferentes ámbitos (procesamiento de imágenes, concurrencia de procesos, conceptos hardware del dispositivo elegido, etc.) Identificación y análisis del conjunto de acciones a reconocer: El esfuerzo requerido para cumplimentar este requisito supone labores de documentación y pruebas mediante el módulo de captura de imágenes que haya sido desarrollado. Adaptación del modelo Bag of Words: El esfuerzo requerido para cumplimentar este requisito supone labores de documentación para comprender el funcionamiento de dicho modelo. También será necesario investigar y analizar las diferentes herramientas necesarias para su funcionamiento, así como estudiar la forma de abordar la integración de la solución proporcionada. Desarrollo de un clasificador (SVM): El esfuerzo requerido para cumplimentar este requisito supone la documentación sobre el funcionamiento sobre este tipo de elemen72 tos software, además de la adquisición de las habilidades técnicas necesarias para su implementación. Organización del conjunto de sujetos del experimento: El esfuerzo requerido para cumplimentar este requisito supone la programación, coordinación y convocatoria de los sujetos que participarán en el experimento. También incluye labores de documentación necesarias para la elaboración de los escritos pertinentes sobre la protección de datos personales, preparación del entorno, etc. Integración de los diferentes módulos: El esfuerzo requerido para cumplimentar este requisito supone la realización de pruebas para comprobar el correcto funcionamiento del sistema desarrollado. Desarrollo de una interfaz gráfica: El esfuerzo requerido para cumplimentar este requisito supone la documentación de las plataformas existentes para este cometido, estudio de su adecuación y la adquisición de las habilidades técnicas para su utilización, además de abordar la integración de los diferentes módulos desarrollados a lo largo del proyecto así como la realización de las pruebas pertinentes para la comprobación del correcto funcionamiento del sistema desarrollado. 5.1.2.2. Fase 2: Development Para la realización de la segunda fase del proyecto, se ha seguido una aproximación basada en lo descrito anteriormente en la sección de “Acerca de Scrum” (véase § 5.1.1). De esta forma, se ha dividido esta fase en seis iteraciones bien diferenciadas pero fuertemente dependientes entre ellas. A continuación se describe cada una junto con su correspondiente Sprint Backlog. 5.1.2.2.1. Iteración 0 Esta primera iteración tiene como objetivo general recoger y analizar la documentación necesaria para comenzar con el proyecto. De esta forma, el Sprint Backlog de esta iteración comprende los siguientes elementos de alto nivel del Product Backlog: “Evaluación de mercado” y “Análisis de librerías disponibles”. A continuación se presenta el Sprint Backlog desglosado en tareas de bajo nivel: Recoger la documentación relativa sobre la historia y evolución de Kinect. Recoger la documentación relativa sobre el desarrollo de aplicaciones alternativas en diferentes campos: Ocio, medicina, educación, accesibilidad, etc. Recoger y analizar detalladamente las características técnicas de las diferentes versiones de Kinect (Kinect para Xbox360, Kinect para Windows y nueva generación de Kinect). Realizar un estudio sobre las ventajas que ofrece Kinect frente a otros dispositivos. 73 Recoger y analizar la documentación relativa sobre el funcionamiento interno de Kinect y realizar un pequeño estudio. Realizar un estudio de mercado de las librerías disponibles. Esta tarea incluye el análisis de las diferentes posibilidades, su evolución en los últimos años y principales ventajas y desventajas frente a otras posibilidades. Recoger la documentación relativa sobre el estado del arte de visión por computador. Realizar un breve estudio sobre los algoritmos existentes para el reconocimiento de acciones basados en vídeo. Los resultados obtenidos de las tareas y requisitos descritos en el Sprint Backlog y la documentación generada en la presente iteración quedan recogidos en el capítulo de “Antecedentes” (véase § 4). 5.1.2.2.2. Iteración 1 Para llevar a cabo la tarea “Identificación y análisis de los datos recogidos por el dispositivo” del Product Backlog ha sido necesario segmentar el trabajo en tres iteraciones (Iteración 1, Iteración 2 e Iteración 3). Esto se debe principalmente a dos motivos. El primero de ellos debido a la gran cantidad de trabajo que abarca esta tarea general y, en segundo lugar, debido a la gran cantidad de nuevos conceptos que implica la realización de la tarea. Para afrontar este reto se ha decido comenzar afianzando los conceptos más generales en la primera iteración, para continuar en las siguientes iteraciones con conceptos más específicos según la problemática que se esté tratando. El objetivo general de esta iteración es realizar la primera toma de contacto con Kinect, permitiendo así familiarizarse con los aspectos más relevantes sobre el dipositivo. De este modo, el Sprint Backlog de la Iteración 1 queda desglosado en las siguientes tareas: Instalación y configuración de los drivers de Kinect, de la plataforma O PEN NI y del middleware NiTE. Instalación y configuración de la herramienta “Processing” y de la librería “SimpleOpenNI”. Comprender y afianzar los conceptos de reflexión, oclusión y desalineamiento entre cámaras. Comprender y afianzar los conceptos relacionados con los píxeles RGB y de profundidad. Comprender el funcionamiento necesario para la conversión a distancias reales. Comprender y afianzar los conceptos relacionados con las nubes de puntos. Entender el funcionamiento de los conceptos adquiridos mediante pequeños ejemplos en Processing (Dibujando con Kinect, Álbum de fotos y Batería virtual). 74 Los resultados obtenidos de las tareas y requisitos descritos en el Sprint Backlog y la documentación generada en la presente iteración quedan recogidos en la sección “Primeros pasos con Kinect” (véase § 6.1). 5.1.2.2.3. Iteración 2 En esta iteración se continua con la tarea “Identificación y análisis de los datos recogidos por el dispositivo” del Product Backlog. De esta forma, los principales objetivos de esta iteración son comprender los conceptos más importantes acerca del funcionamiento de O PEN NI, de la librería GLUT y obtener una primera versión “entregable” del módulo de captura de imágenes. A continuación se presenta el Sprint Backlog de la Iteración 2 desglosado en las siguientes tareas: Comprender y afianzar los conceptos más importantes acerca del funcionamiento de la plataforma O PEN NI. Comprender y afianzar los conceptos más importantes acerca del funcionamiento de la librería GLUT. Realizar la implementación de la primera versión del módulo de captura de imágenes. Esta primera versión debe permitir realizar las siguientes acciones: • Captura del flujo de datos de la cámara RGB. • Captura del flujo de datos del sensor de profundidad. • Visualizar los flujos de datos a través de una interfaz de usuario que implemente los comandos básicos para su control. Los resultados obtenidos de las tareas y requisitos descritos en el Sprint Backlog y la documentación generada en la presente iteración quedan recogidos en la sección “Comprendiendo el funcionamiento de OpenNI” (véase § 6.2). 5.1.2.2.4. Iteración 3 En esta iteración además de continuar y finalizar la tarea “Identificación y análisis de los datos recogidos por el dispositivo”, se lleva a cabo la tarea “Identificación y análisis del conjunto de acciones a reconocer” del Product Backlog. De este modo, el principal objetivo de esta iteración es obtener una versión definitiva del módulo de captura de imágenes. A continuación se presenta el Sprint Backlog de la presente iteración desglosado en tareas de bajo nivel: Comprender y afianzar los conceptos más importantes acerca del funcionamiento del middleware NiTE: Seguimiento de de manos y del cuerpo y detección de gestos. Análisis e interpretación de la información proporcionada por el middleware. 75 Integrar las funcionalidades proporcionadas por el middleware NiTE en el módulo de captura de imágenes. Para ello ha sido necesario realizar tres nuevas versiones de forma iterativa e incremental de la primera versión existente que fue desarrollada en la iteración anterior. En cada una de las diferentes versiones se introducen nuevas funcionalidades así como mejoras en el rendimiento y consumo de memoria. Para llevar a cabo esta tarea se han definido las siguientes subtareas: • Comprender y afianzar el concepto de “background substraction”. • Recoger la documentación relativa sobre el formato de imágenes PPM. • Recoger la documentación relativa y obtener las habilidades técnicas para el manejo de hilos de la librería POSIX. • Identificar, analizar y diseñar los diferentes tipos de hilos ha implementar para mejorar el rendimiento del módulo de captura de imágenes. • Análisis y estudio del impacto producido por el excesivo consumo de memoria y las soluciones existentes para su resolución. • Recoger la documentación relativa sobre el formato de imágenes JPEG. • Recoger la documentación relativa y obtener las habilidades técnicas para el manejo de la librería OpenCV para la comprensión de imágenes en formato JPEG. • Realizar un estudio de mercado de las librerías XML disponibles. Esta tarea incluye el análisis de las diferentes posibilidades. • Recoger la documentación relativa y obtener las habilidades técnicas para el manejo de la librería XML elegida. Los resultados obtenidos de las tareas y requisitos descritos en el Sprint Backlog y la documentación generada en la presente iteración quedan recogidos en la sección “Incorporación de NiTE” (véase § 6.3). 5.1.2.2.5. Iteración 4 Esta iteración tiene como objetivo general la adaptación del sistema de reconocimiento facilitado al módulo de reconocimiento de acciones del proyecto. De esta forma, el Sprint Backlog de esta iteración comprende los siguientes elementos de alto nivel del Product Backlog: “Adaptación del modelo Bag of Words” y “Desarrollo de un clasificador (SVM)”. A continuación se presenta el Sprint Backlog desglosado en tareas de bajo nivel: Recoger la documentación pertinente, analizar y comprender de forma exhaustiva el modelo de Bag of Words (B OW) y todos los conceptos relacionados. Adaptación de la solución propuesta. Para llevar a cabo esta tarea han sido necesarias las siguientes subtareas: • Recoger la documentación relativa y obtener las habilidades técnicas para el manejo de las herramientas ffmpeg, stipdept, Ann y bsvm. 76 • Recoger la documentación relativa y obtener las habilidades técnicas para el manejo del lenguaje de programación PERL. • Documentar y analizar el dataset público de acciones IXMAS. • Recoger y analizar la documentación relativa sobre las principales técnicas de extracción de características en vídeos. • Recoger y analizar la documentación relativa sobre las principales técnicas de clustering. • Recoger y analizar la documentación relativa sobre las principales técnicas de clasificación, especialmente SVM. • Realizar un estudio de mercado de las librerías SVM disponibles. Esta tarea incluye el análisis de las diferentes posibilidades. Los resultados obtenidos de las tareas y requisitos descritos en el Sprint Backlog y la documentación generada en la presente iteración quedan recogidos en la sección “Módulo de reconocimiento de acciones” (véase § 6.4). 5.1.2.2.6. Iteración 5 Esta iteración tiene como objetivo general el desarrollo de una interfaz de gráfica que facilite la utilización de los módulos desarrollados en las iteraciones anteriores mediante un panel de control que permita manipular todas las opciones implementadas de una forma sencilla e intuitiva. Además, también debe facilitar que el usuario pueda emplear todas las herramientas sin necesidad de emplear aplicaciones externas, centralizando en una única aplicación todos los módulos desarrollados. Por tanto, el Sprint Backlog de esta iteración comprende los siguientes elementos de alto nivel del Product Backlog: “Desarrollo de una interfaz gráfica” e “Integración de los diferentes módulos”. A continuación se presenta el Sprint Backlog desglosado en tareas de bajo nivel: Realizar un estudio de mercado de las librerías disponibles para el desarrollo de interfaces gráficas. Esta tarea incluye el análisis de las diferentes posibilidades. Recoger la documentación relativa y obtener las habilidades técnicas para el manejo de la herramienta seleccionada. Diseño e implementación de una interfaz gráfica adecuada para realizar la captura de vídeo mediante la integración del módulo de captura de vídeo. Diseño e implementación de una interfaz gráfica adecuada para realizar el etiquetado de vídeos. Diseño e implementación de una interfaz gráfica adecuada para realizar el proceso de clasificación mediante la integración del módulo de de reconocimiento. 77 Diseño e implementación de una interfaz gráfica adecuada que permita de forma sencilla e intuitiva inspeccionar los resultados obtenidos. Los resultados obtenidos de las tareas y requisitos descritos en el Sprint Backlog y la documentación generada en la presente iteración quedan recogidos en la sección “Interfaz gráfica” (véase § 6.5). 5.1.2.3. Fase 3: Post-game El principal objetivo de esta fase consiste en la realización de las pruebas pertinentes para comprobar el correcto funcionamiento e integración de los módulos implementados en la fase de desarrollo y el respectivo análisis de los resultados obtenidos (véase § 7). Además, también se lleva a cabo la finalización de la documentación generada a lo largo del proyecto. Por último, es realizado el proceso de revisión final del proyecto y se prepara el producto obtenido para su posterior presentación al cliente o usuario final. En este caso, cómo se trata de un proyecto académico este rol será interpretado por el correspondiente tribunal académico. 5.2 Herramientas En este apartado se mostrarán las distintas herramientas, tanto hardware como software, que han intervenido en la elaboración de K IN B EH R. 5.2.1 Aplicaciones de desarrollo Processing: Entorno de desarrollo integrado de fácil utilización, y que sirve como medio para la enseñanza y producción de proyectos multimedia e interactivos de diseño digital [pro14]. Fue iniciado por Ben Fry y Casey Reas a partir de reflexiones en el Aesthetics and Computation Group del MIT Media Lab dirigido por John Maeda. Se distribuye bajo la licencia GNU GPL. Shell: Programa informático cuya función consiste en interpretar órdenes. Incorpora características tales como control de procesos, redirección de entrada/salida, listado y lectura de ficheros, protección, comunicaciones y un lenguaje de órdenes para escribir programas por lotes o “scripts”. Fue el intérprete usado en las primeras versiones de Unix y se convirtió en un estándar de facto. Open Natural Interaction (O PEN NI): Framework “open source” bajo una licencia “GNU Lesser General Public License (LGPL)” que proporciona numerosas APIs para el desarrollo de aplicaciones basadas en el paradigma de interacción natural con el usuario mediante la utilización de diversos dispositivos hardware, entre ellos Kinect. NiTE: Uno de los middleware más avanzados y robustos en el campo de visión por compu78 tador. Fue desarrollado por PrimeSense (creador del hardware de Kinect). SimpleOpenNI: Es un wrapper basado en el framework O PEN NI y el middleware NiTE que permite desarrollar aplicaciones para Processing [sim14]. OpenCV: Es una biblioteca libre de visión artificial originalmente desarrollada por Intel. OpenCV [ope14] es multiplataforma, existiendo versiones para GNU/Linux, Mac OS X y Windows. Contiene más de 500 funciones que abarcan una gran gama de áreas en el proceso de visión, como reconocimiento de objetos (reconocimiento facial), calibración de cámaras, visión estérea y visión robótica. Se encuentra distribuida bajo licencia BSD lo cual permite que sea usada libremente para propósitos comerciales y de investigación con las condiciones en ella expresadas. Implementada en C y C++. OpenGL Utility Toolkit (GLUT): Es una biblioteca de utilidades para programas OpenGL que principalmente proporciona diversas funciones de entrada/salida con el sistema operativo [glu14]. Entre las funciones que ofrece se incluyen declaración y manejo de ventanas y la interacción por medio de teclado y ratón. También posee rutinas para el dibujado de diversas primitivas geométricas que incluyen cubos, esferas y teteras. También tiene soporte para creación de menús emergentes. La versión original de GLUT fue escrita por Mark J. Kilgard. GNU Compiler Collection (GCC): Colección de compiladores del proyecto GNU [gcc14]. GNU Make: Herramienta para la generación automática de ejecutables [SMS04]. Mercurial: Sistema de control de versiones distribuido. Se ha hecho uso de esta herramienta para el código del proyecto y la documentación [mer14]. Stipdet: Es una aplicación desarrollada por Ivan Laptev cuya finalidad es calcular los descriptores para cada uno de los puntos de interés espacio-temporal del vídeo que le es pasado como argumento [sti14]. ANN: Es una librería escrita en C++ destinada a ofrecer estructuras de datos y algoritmos para el cálculo de la búsqueda de vecinos próximos en ámbitos que presentan un elevado número de dimensiones [ann14]. BSVM: La implementación actual de BSVM toma prestada la estructura interna de LIBSVM 2 ofreciendo de este modo opciones muy similares [bsv14]. ffmpeg: Colección de software libre que puede grabar, convertir (transcodificar) y hacer streaming de audio y vídeo [ffm14]. Incluye libavcodec, una biblioteca de códecs. El proyecto comenzó por Gerard Lantau, un seudónimo de Fabrice Bellard, y ahora es mantenido por Michael Niedermayer. 2 Software integrado para la clasificación del vector de la ayuda, (C-SVC, NU-SVC), la regresión (épsilonSVR, NU-SVR) y la valoración de la distribución (uno-clase SVM). 79 Qt: Biblioteca multiplataforma de software libre y código abierto usada para desarrollar aplicaciones con interfaz gráfica de usuario [qt14], así como también para el desarrollo de programas sin interfaz gráfica, como herramientas para la línea de comandos y consolas para servidores. Qt es utilizada en KDE, entorno de escritorio para sistemas como GNU/Linux o FreeBSD, entre otros. Qt utiliza el lenguaje de programación C++ de forma nativa, adicionalmente puede ser utilizado en varios otros lenguajes de programación a través de bindings. GNU Emacs: Entorno de desarrollo de GNU que ha sido empleado tanto para realizar la implementación así como para la documentación [ema14]. 5.2.2 Lenguajes de programación Para la elaboración del presente proyecto ha sido necesario la utilización de diversos lenguajes de programación. A continuación se muestra la lista completa de todos ellos: C++: Creado por Bjarne Stroustrup [Str00], C++ proporciona mecanismos de orientación a objetos y compatibilidad con C. Es un lenguaje compilado que ofrece distintos niveles de abstracción al programador. Perl: Diseñado por Larry Wall en 1987. Perl toma características del lenguaje C, del lenguaje interpretado bourne shell (sh), AWK, sed, Lisp y, en un grado inferior, de muchos otros lenguajes de programación. Estructuralmente, Perl está basado en un estilo de bloques como los del C o AWK, y fue ampliamente adoptado por su destreza en el procesado de texto y no tener ninguna de las limitaciones de los otros lenguajes de script. Processing: Un lenguaje de programación de código abierto basado en Java. Se distribuye bajo la licencia GNU GPL. 5.2.3 Documentación y gráficos LATEX: Lenguaje de marcado de documentos de carácter técnico y científica, utilizado para realizar este documento [Tal13]. BibTex: Herramienta para la descripción de referencias para documentos escritos con LATEX. Dia: Editor de diagramas [dia14]. Se ha utilizado para construir los diagramas de clases, de flujo, etc. Gimp: Software de edición de imágenes y retoque fotográfico. Utilizado en la maquetación de fotografías e ilustraciones [gim14]. 5.2.4 Hardware Ordenador de sobremesa: Para el desarrollo de K IN B EH R se ha empleado un equipo de sobremesa. Este equipo cuenta con las siguientes características: 80 Intel(R) Core(TM) i7-2620M CPU @ 2.70GHz. 4 GB de RAM. 500 GB Disco Duro. Kinect para Xbox360: Es “un controlador de juego libre y entretenimiento” creado por Alex Kipman, desarrollado por Microsoft para la videoconsola Xbox 360, y desde junio del 2011 para PC a través de Windows 7 y Windows 8.3. Tratado en mayor profundidad en el capítulo de antecedentes (véase § 4). Disco duro externo de 1 TB 5.2.5 Sistemas operativos Debian: Se ha empleado Debian 7.0 (wheezy) 64-bit con núcleo Linux 3.0.0-1-amd64, instalado en el equipo de sobremesa indicado en la sección § 5.2.4, como sistema operativo principal para la realización del presente proyecto. 81 Capítulo 6 Desarrollo del proyecto E el presente capítulo se describe el proceso de desarrollo que se ha llevado a cabo para la realización del proyecto. Para ello, se ha estructurado su narración en varias secciones tratando de ser lo más fiel posible a las diferentes etapas que se han llevado a cabo a lo largo del proyecto. En cada una de estas secciones se describen los conceptos más importantes que se han ido adquiriendo a lo largo del proyecto así como todo aquello que se ha considerado relevante para la correcta comprensión y seguimiento del mismo. N Al tratarse del capítulo más extenso, se ha decidido incluir a continuación una breve guía para facilitar al lector su seguimiento. El capítulo se encuentra dividido en cinco grandes bloques, coincidiendo de esta manera con las iteraciones propuestas en la planificación, en los que se tratan los siguientes aspectos: Primeros pasos con Kinect: Presenta conceptos de relevancia para la realización del proyecto relacionados con el tratamiento e interpretación de imágenes, prestando especial atención a las peculiaridades de Kinect. A lo largo de este bloque se exponen diferentes ejemplos para apoyar los conceptos tratados y para familiarizarse con Kinect mediante la utilización de una librería de alto nivel. Comprendiendo el funcionamiento de O PEN NI: En este bloque se tratan los aspectos más relevantes sobre la bibliotecas empleadas, O PEN NI y GLUT. No obstante, si el lector se encuentra familiarizado con estos conceptos se recomienza comenzar su lectura por la sección “Primera versión del módulo de captura de imágenes” (véase § 6.2.3). En esta sección se narra como se ha llevado a cabo la implementación de la primera versión del módulo de captura de imágenes. Incorporación de NiTE: En este bloque se introducen los conceptos más importantes sobre el middleware NiTE. Algunos de los temas tratados son el seguimiento de manos y detección de gestos, su funcionamiento y el análisis e interpretación de la información proporcionada. No obstante, si el lector se encuentra familiarizado con estos conceptos se recomienza comenzar su lectura por la sección “Evolución del módulo de captura de imágenes” (véase § 6.3.2). En esta sección se narra como se ha llevado a cabo la implementación de las siguientes versiones del módulo de captura de imágenes. 83 Módulo de reconocimiento de acciones: Este bloque se encuentra dividido en dos partes bien diferenciados. En la primera de ellas se presentan los conceptos y aspectos más importantes y que se han tenido en cuenta sobre B OW. No obstante, si el lector se encuentra familiarizado con estos conceptos se recomienza que comienze la lectura por la segunda parte “Implementación de la solución propuesta” (véase § 6.4.2) Esta segunda parte describe detalladamente cada una las fases en las que se ha dividido el proceso de reconocimiento de acciones así como la forma en la que se ha procedido para adaptar la solución facilitada. Interfaz gráfica: Este último bloque versa sobre el proceso seguido para el desarrollo de una interfaz gráfica que permita integrar todos los componentes desarrollados a lo largo del proyecto. Además, para facilitar al lector la lectura del capítulo y evitar la complicación de su correcto seguimiento, se ha decidido dejar la descripción sobre la planificación efectuada y la descripción de la metodología de desarrollo seguida en el capítulo anterior (véase § 5). 6.1 Iteración 1: Primeros pasos con Kinect En esta sección se expone cómo se ha llevado a cabo la primera toma de contacto con Kinect. El principal objetivo de esta primera etapa es familiarizarse con los principales conceptos del dispositivo y su manera de trabajar, así como las peculiaridades más llamativas del mismo que se deben de tener en cuenta a la hora de trabajar. De esta forma, a lo largo de la presente sección se irán exponiendo ejemplos sencillos que permitirán obtener los conocimientos básicos sobre el dispositivo y las bases a tener en cuenta para el desarrollo en las siguientes etapas. Para ello, se ha empleado “SimpleOpenNI”1 como herramienta y [Bor12] como material de referencia de donde se ha extraído la base para los ejemplos. SimpleOpenNI es un wrapper basado en el framework O PEN NI y el middleware NiTE (véase § 4.1.8.2) que permite desarrollar aplicaciones para Processing2 (véase § 5.2.1). Aunque este wrapper no implementa todas las funcionalidades ofrecidas por O PEN NI y NiTE, como primera toma de contacto con Kinect resulta muy interesante ya que se trata de una herramienta relativamente sencilla de utilizar y proporciona un nivel extra de abstracción a las herramientas que serán empleadas en posteriores etapas del proyecto. De esta forma, SimpleOpenNI se convierte en el compañero perfecto para realizar la primera toma de contacto con Kinect y lo que es mucho más importante, ir familiarizándose con las peculiaridades de O PEN NI. No obstante, y a pesar de su sencillez, Processing junto con SimpleOpenNI supone una herramienta muy potente que ha sido utilizada en una gran cantidad de proyectos. Uno de 1 2 https://code.google.com/p/simple-openni/ http://www.processing.org/ 84 los más interesantes es “MAY THE FORCE BE WITH YOU”, que permite mover aguas virtuales proyectadas en una pared (ver Figura 6.1). Figura 6.1: Proyecto “MAY THE FORCE BE WITH YOU” de TeoPatk [wbT14b]. 6.1.1 Primer programa con Kinect Este primer ejemplo es muy simple ya que únicamente consiste en acceder a la Kinect, leer los datos proporcionados por la cámara de profundidad y RGB para posteriormente mostrarlos por pantalla. A partir de este ejemplo base se irán añadiendo pequeñas modificaciones que permitirán ir explorando nuevos conceptos. Aunque el código empleado para la implementación de los diferentes ejemplos de esta sección se encontrarán en un Anexo (véase § A), para mostrar la simplicidad que ofrece SimpleOpenNI, en este primer ejemplo se explicará brevemente los conceptos más básicos sobre cómo funciona (ver Listado 6.1). En la línea 2 se declara un objeto “SimpleOpenNI” con el nombre de Kinect. Este objeto permite acceder a todos los datos proporcionados por Kinect, como la cámara de profundidad o la cámara RGB. El método “setup()” se encarga de configurar e inicializar los diferentes parámetros de la aplicación: Linea 6: Se establece el tamaño de la aplicación. Como se va a trabajar con una resolución de 640 x 480 píxeles en ambas cámaras y se van a mostrar las imágenes capturadas por ambas, es necesario multiplicar el ancho por 2. Linea 7: Se inicializa el objeto “kinect” anteriormente declarado. Lineas 9 y 10: Indican a la aplicación que se quiere acceder a las imágenes de profundidad y RGB respectivamente. Por otra parte, el método “draw()” que funciona a modo de bucle se encarga de ir mostrando por pantalla los datos provenientes de ambas cámaras. Para ello, en la línea 15 se 85 1 2 import SimpleOpenNI .∗; SimpleOpenNI kinect ; 4 5 6 7 void setup () { size (640∗2 , 480) ; kinect = new SimpleOpenNI ( this ) ; kinect . enableDepth () ; kinect . enableRGB () ; 9 10 11 } 13 14 15 void draw () { kinect . update () ; 17 18 19 image ( kinect . depthImage () , 0 , 0) ; image ( kinect . rgbImage () , 640 , 0) ; } Listado 6.1: «Ejemplo 1» versión 1 invoca al método “update()” de la clase SimpleOpenNI, el cual se encarga de actualizar los datos que han sido indicados anteriormente (lineas 9 y 10). Por último, se indica a la aplicación (17 y 18) la posición en la que se quiere ubicar las imágenes capturadas por Kinect y que son recuperadas a través de los métodos “depthImage()” y “rgbImage()” de la clase SimpleOpenNI. En la Figura 6.2 se muestra el resultado obtenido de ejecutar la aplicación, donde la imagen de la izquierda se corresponde con los datos capturados por la cámara de profundidad y la imagen derecha con la cámara RGB. En este punto es necesario destacar que la imagen de profundidad emplea una escala de grises donde la tonalidad representa la longitud a la que se encuentra la superficie respecto la Kinect. No obstante, se aprecian algunos aspectos bastante interesantes que serán desarrollados detalladamente en las siguientes subsecciones. 6.1.1.1. La reflexión En primer lugar, a pesar de que el espejo se encuentra a la misma distancia que la persona que lo sostiene, este presenta un color bastante más oscuro. Esto se debe a que la reflexión provocada por el espejo está causando distorsión en los datos recogidos por la cámara de profundidad. Como se presentó en la sección acerca del funcionamiento de Kinect (véase § 4.1.6), este dispositivo posee un emisor de infrarrojos que emite una nube de puntos. Posteriormente, estos puntos rebotan con las superficies que se encuentran a su paso, lo cual es recogido por el sensor de infrarrojos para crear un mapa de profundidad. Sin embargo, en el caso del espejo, los puntos recogidos realizan un viaje mucho más largo, ya que cuando llegan al espejo, estos son rebotados hacía la pared de enfrente, dando como resultado una distancia mucho más larga (lo cual se traduce en el ejemplo una tonalidad más oscura). 86 Figura 6.2: Captura del primer ejemplo con Processing. No obstante, esto no tiene por qué ser siempre una desventaja. Un ejemplo de ello es el trabajo realizado por el investigador Kyle McDonald, en el cual colocando una serie de espejos similares a los encontrados en los probadores de una tienda de ropa, es capaz de representar escenas en 360 grados sin necesidad de mover el dispositivo en ningún momento (ver Figura 6.3). Figura 6.3: Scanner 3D con Kinect por Kyle McDonald [Bor12]. 6.1.1.2. La oclusión Otro concepto interesante extraído de este primer ejemplo es el de la oclusión y las sombras. Como se puede apreciar en la captura obtenida del ejemplo, la pared que se encuentra situada frente a la Kinect se encuentra totalmente paralela al dispositivo. No obstante, si se comparan las diferentes tonalidades que va tomando la pared en la imagen de profundidad se puede apreciar que, aunque deberían ser iguales ya que se encuentran a la misma distancia del dispositivo, la tonalidad no es uniforme. Este fenómeno se debe a que el patrón de puntos emitido por el dispositivo viajan hasta alcanzar un objeto, siendo a continuación reflejados por la superficie del mismo de vuelta al dispositivo para calcular el mapa de profundidad. 87 Sin embargo, ningún punto será alcanzado por los otros objetos que se encuentran detrás y por consiguiente la Kinect no obtendrá ninguna información acerca de la ubicación de estos, provocando de esta forma sombras negras en la imagen. 6.1.1.3. Desalineamiento entre cámaras Si se observa detenidamente las imágenes capturadas por ambas cámaras, se puede apreciar que, a pesar de que corresponden al mismo instante de tiempo, ambos frames no son exactamente iguales. Este hecho se aprecia claramente si se compara la posición de la cabeza de la persona que aparece en escena en ambas imágenes: Mientras que en la imagen RGB la cabeza ha sido capturada en su totalidad, en la imagen de profundidad tan sólo se ha capturado parcialmente. Como ya se explicó en la sección de características técnicas de Kinect (véase § 4.1.4), el dispositivo captura las imágenes RGB y de profundidad desde cámaras diferentes. Estas cámaras se encuentran separadas la una de la otra en la parte frontal del dispositivo por unos pocos centímetros. De este modo, al encontrarse en posiciones diferentes, los puntos de vista captados por ambas serán forzosamente distintos. 6.1.2 Apreciaciones a nivel de píxel El ejemplo que se expone en esta subsección tiene como objetivo obtener la nociones básicas sobre los valores recuperados por las cámaras y el comportamiento que van adoptando los píxeles en cada momento. Para ello, se ha implementado un ejemplo muy sencillo (ver Listado A.1) que permite obtener, pinchando con el ratón en el área deseada, los valores numéricos que toman en cada momento los diferentes píxeles capturados por las cámaras. A continuación se muestra una captura (ver Figura 6.4) obtenida con este ejemplo y que servirá como base para las explicaciones dadas a continuación. Figura 6.4: Captura del segundo ejemplo con Processing. 88 6.1.2.1. Píxeles RGB Como ya se comentó brevemente en la sección acerca del funcionamiento de la cámara RGB de Kinect (véase § 4.1.6.1), cada píxel de una imagen RGB se caracteriza por tres componentes que representan los valores de los colores rojo (R, red), verde (G, green) y azul (B, blue). Además, cada uno de estos componentes representan, a su vez, un valor decimal comprendido entre 0 y 255 (correspondiendo a un byte), es decir, la cantidad de rojo, verde y azul que hay en ese punto de la imagen. Para quien no esté familiarizado con estos conceptos, es muy posible que en primera instancia se lleve alguna sorpresa con los resultados que pueden ser obtenidos. Un ejemplo de ello puede ser la zona de la imagen que representa el jersey rojo que se encuentra situado encima de la silla. El primer pensamiento que puede venir a la mente es que los píxeles correspondientes a dicho jersey, al ser aparentemente rojo, el valor de la componente “R” debe ser prácticamente 255. No obstante, si se accede a los valores de esos píxeles se aprecia que no es así, obteniendo los siguientes valores: “R: 159.0 G: 1.0 B: 33.0”. A pesar de que para el ojo humano el jersey es completamente rojo, la componente roja de los píxeles correspondientes a esa área es de tan sólo de 158, es decir, poco más de la mitad de su máximo valor. Este hecho muestra la diferencia entre lo que el ojo humano ve e interpreta y los valores que un computador calcula para procesar los datos obtenidos de una cámara digital. De esta manera, es posible afirmar que el cerebro humano interpreta los datos obtenidos por los ojos de una forma “relativa”, centrándose en las variaciones entre las diferentes zonas de la imagen en vez de interpretar sus valores absolutos. Si se exploran otras zonas la imagen, las conclusiones que se pueden obtener son las mismas, como por ejemplo la pared que se encuentra en el fondo de habitación, que es la zona más clara para el ojo humano de toda la imagen. Examinando los valores de los píxeles correspondientes a esta zona, se obtienen resultados muy similares: R: 226.0 G: 219.0 B: 226.0. Esta vez se observa que las tres componentes tienen valores muy similares entre ellas y que además se encuentran muy próximas a los valores que debería tener un píxel completamente blanco (R: 255.0 G: 255.0 B: 255.0). De este modo, las conclusiones que se pueden extraer de esta primera parte del ejemplo son las siguientes: El color representado por un píxel está basado en la diferencia entre los valores que toman su tres componentes. Los píxeles que tienen valores muy próximos en sus tres componentes representan un color blanco o alguna tonalidad de gris. Mientras que los valores relativos de los componentes de un píxel son los que determinan el color percibido por el ojo humano, es la suma de las tres componentes quién determina el nivel de claridad que presentará el píxel. 89 Teniendo claras estas conclusiones, se pone en evidencia un gran problema: Distinguir que píxeles de la imagen pertenecen a cada objeto o persona que aparecen en la escena, una de las tareas de visión por computador que se abordan en este proyecto. En el caso del jersey que se exponía anteriormente, en principio puede ser una tarea relativamente sencilla ya que una posible aproximación podría ser considerar que los píxeles con tonalidades rojas que se encuentren en este área pertenecen al jersey. No obstante, antes se ha puesto en evidencia que los valores de las componentes de un píxel pueden variar drásticamente pudiendo llevar a equívoco. A continuación se exponen dos escenarios que podrían comprometer la validez de esta solución: Escenario 1: Imagine que delante de este jersey rojo se coloca, ocultando parte del mismo, una persona vestida con una prenda del mismo color. En este caso, una imagen RGB tan sólo proporciona información acerca del color de cada píxel de la imagen, y por lo tanto, una aproximación como la expuesta anteriormente establecería que tanto el jersey cómo la prenda roja de la persona son el mismo objeto. Escenario 2: Imagine que parte del jersey, debido a las sombras producidas por algún tipo de luz, tiene zonas muy oscuras próximas al negro. La imagen RGB capturada presentará el jersey con píxeles que varían drásticamente entre unas zonas y otras en función de la luz que esté recibiendo. De este modo, con una aproximación como la expuesta anteriormente el resultado obtenido será que sólo reconoce ciertas partes del jersey. Aunque este tipo de problemas han sido, en parte, solucionados mediante diversas técnicas de visión por computador, una solución perfecta empleando tan sólo cámaras RGB aún se encuentra lejos. En gran parte, esto se debe a que este tipo de cámaras sólo capturan el color de las diferentes partes de la escena sin proporcionar ningún tipo de información sobre la ubicación y distancia a la que se encuentran respecto la cámara 6.1.2.2. Píxeles de profundidad La presente subsección tiene como objetivo analizar los resultados obtenidos por la cámara de profundidad de Kinect y cómo esta información puede resolver de una manera relativamente sencilla los problemas expuestos en la subsección anterior. Para ello, se ha hecho uso del mismo ejemplo que se ha empleado para la anterior subsección. En este caso, al pinchar sobre el jersey rojo que se encuentra colocado sobre la silla, se obtiene un resultado muy diferente: “R: 175.0 G: 175.0 B: 175.0”. A diferencia de lo que ocurría en el caso de la imagen RGB, los valores de los componentes de la imagen de profundidad son idénticos. Si se tiene presente lo expuesto anteriormente, este hecho tiene sentido ya que una imagen de profundidad está representada en escala de grises y por tanto las componentes de cada píxel de la imagen serán siempre iguales variando tan sólo en el brillo, es decir, la distancia entre el blanco y el negro. 90 Gracias a este tipo de imágenes, es posible obtener información muy valiosa para determinar aspectos muy interesantes que resuelven algunos de los problemas encontrados con una cámara RGB. Por ejemplo, a pesar de que el respaldo y el asiento de la silla que aparece en la imagen (ver Figura 6.4) son del mismo color (marrón en este caso), los valores de los píxeles obtenidos en cada parte son muy diferentes: “R: 200.0 G: 200.0 B: 200.0” para el respaldo y “R:251.0 G: 251.0 B: 251.0” para el asiento. Por el contrario, si repetimos el mismo proceso pero con la imagen RGB, los valores obtenidos en este caso son prácticamente idénticos. Esto se debe a que la imagen RGB devuelve el valor del color que toma cada objeto en la imagen, y como en este caso el color de ambas zonas son iguales, los valores serán muy similares variando muy levemente debido a diversos factores como puede ser la incidencia de la luz en cada zona. Por el contrario, la información obtenida en la imagen de profundidad debe ser interpretada de manera muy diferente: Cada píxel representa la distancia entre el objeto que representa y la cámara. De esta forma, el valor de cada píxel de la imagen tomará valores más altos (es decir, colores más claros) en las zonas más próximas a la cámara y valores más bajos (es decir, colores más oscuros) en las zonas más lejanas a la cámara. Por lo tanto, al contrario de lo que ocurre con la imagen RGB que tan sólo proporcionaba información acerca del color de cada parte de la escena, la imagen de profundidad obtiene datos precisos que permiten determinar que el asiento y el respaldo están físicamente separados. Por consiguiente, examinando la imagen de profundidad, es posible determinar, a grosso modo, que los píxeles de la silla que se encuentren en un rango en torno a 200 pertenecen al respaldo y aquellos que se encuentren próximos a 251 pertenecen al asiento. Retomando los escenarios hipotéticos que se presentaban en la subsección anterior (véase § 6.1.2.1), se aprecia que complementando la información obtenida por la camára RGB con la imagen de profundidad es posible solucionar el problema de identificar a que píxeles corresponde cada objeto de la escena: Escenario 1: Es posible determinar que aquellos píxeles de color rojo (con la información obtenida por la cámara RGB) y que posean valores similares en los píxeles de la imagen de profundidad pertenecen al jersey. De esta forma, se puede distinguir entre aquellos píxeles rojos que pertenecen a la prenda de la persona y los que pertenecen al jersey, ya que van a presentar diferentes valores en los píxeles de la imagen de profundidad, es decir, se encuentran a diferente distancia de la cámara. Escenario 2: En esta situación, el ruido introducido en la imagen por la sombras producidas por la luz se puede eliminar gracias a la imagen de profundidad ya que este tipo de cámaras no se ven afectadas por la iluminación presente en la escena. La conclusión más importante que se ha obtenido tras este pequeño ejemplo deja algo muy claro, y es que combinando la información obtenida a través de una cámara de profun91 didad y una cámara RGB es posible obtener resultados mucho más precisos y de forma más eficiente. 6.1.3 Conversión a distancias reales En la subsección anterior (véase § 6.1.2) se presentaba un ejemplo con el cual se intentaba aprender los conceptos más básicos para ser capaces de entender la información proporcionada por Kinect. Uno de los aspectos más interesantes que se presentaban era el hecho de que a través de una imagen de profundidad es posible extraer información acerca de la distancia a la que se encontraba un objeto o persona en la escena. Para ello, se interpretaba el valor de los píxeles: Aquellos píxeles que tenían mayor brillo (valores más altos) se encontraban más cercanos que aquellos con menor brillo (valores más bajos). No obstante, para el desarrollo de aplicaciones más complejas dónde es necesario obtener información más precisa esta información no es suficiente. Como se comentaba en la subsección anterior, los valores que tomaban las diferentes componentes de un píxel pueden oscilar entre 0 y 255. Teniendo en cuenta esto y que el rango de detección de la cámara de profundidad oscila entre 0.5 metros y 7.5 metros, es posible llevar a cabo una aproximación para obtener la distancia real entre un objeto y la cámara. De esta forma, en una primera aproximación se podrían establecer los siguientes parámetros: Aquellos píxeles de la imagen de profundidad que tengan un valor de 0 se encuentran aproximadamente a una distancia de 7.5 metros o más. Aquellos píxeles de la imagen de profundidad que tengan un valor de 255 se encuentran aproximadamente a una distancia de 0.5 metros o menos. Aquellos píxeles de la imagen de profundidad que tengan un valor entre 255 y 0 se encuentran aproximadamente a una distancia comprendida entre 0.5 y 7.5 metros. No obstante, aún es posible hacer un poco más precisa esta primera aproximación. Para ello, simplemente es necesario realizar algunos cálculos bastante simples: Para obtener la distancia aproximada de un píxel con un valor X, donde X está comprendido entre 0 y 255 (0 <X <255), es necesario llevar a cabo lo siguientes pasos: Calcular el valor relativo de X: Este paso consiste tan solo en realizar una simple regla de 3 (ver Ecuación 6.1). V alor relativo de X = X ∗ 100 255 (6.1) Calcular el valor absoluto de la distancia: Una vez obtenido el valor relativo, tan solo es necesario calcular el valor del intervalo entre 0.5 y 7.5 que le corresponde. Realizando estos cálculos, es posible determinar la distancia en metros a la que se encuentra un objeto o persona en la escena respecto a la Kinect a partir del píxel correspondiente de 92 la imagen de profundidad. Aunque en teoría estos cálculos son correctos, si se realiza alguna prueba real se observará que no es así y que la distancia calculada es incorrecta. Para ello, se toma como ejemplo un píxel con valor 96 de la imagen de profundidad capturada con el ejemplo de la subsección anterior (ver Figura 6.4). Si se aplican los cálculos propuestos, se obtiene que el objeto que corresponde a ese píxel se encuentra a una distancia de la Kinect del 37 % entre 0.5 y 7.5 metros, o lo que lo mismo a una distancia de 4.41 metros aproximadamente. No obstante, si se mide la distancia a la que realmente se encuentra ese píxel no es más de tres metros. El motivo de que el resultado de estos cálculos sea incorrecto es que la relación entre el valor del brillo de un píxel en la imagen de profundidad y la distancia real que este representa es mucho más compleja que una simple relación lineal. Como se ha mostrado antes, los píxeles que representan colores de la escala de grises tienen valores que van desde el 0 hasta 250, mientras que la distancia real cubierta por la Kinect se encuentra entre 0.5 y 7.5 metros. Sin embargo, la lecturas obtenidas por una Kinect puede llegar a alcanzar un precisión casi milimétrica que varia entre 0 y 8000 milímetros aproximadamente. Es por este motivo que los píxeles que componen una imagen de profundidad necesiten más de ocho bits para representar la distancia real entre la cámara y el objeto como se venía haciendo hasta este momento. Para obtener una mayor precisión en el calculo de la distancia, es necesario acceder a los datos de profundidad de Kinect de una manera que ofrezca una mayor resolución ya que es capaz de capturar información de profundidad a una resolución de 11 bits por píxel. De este modo, los píxeles capturados por el dispositivo tendrán valores que están comprendidos entre 0 y 2047, que como se puede apreciar a simple vista, es un rango mucho más amplio que el que se estaba empleando hasta ahora (entre 0 y 255). La solución más directa que a primera vista puede surgir es aumentar el tamaño de cada píxel. No obstante, representar las imágenes por pantalla a una mayor resolución por píxel sería totalmente ineficiente por diversos motivos, como por ejemplo el hecho de que el ojo humano no es capaz de apreciar lo suficiente este aumento de la resolución o que provocaría un aumento sustancial del consumo de memoria. Por ello, en el siguiente ejemplo se plantea la solución más eficiente para el objetivo que se persigue en la presente subsección: Experimentar con la cámara de profundidad y tener la posibilidad de comprobar hasta que nivel de precisión es realmente capaz de proporcionar Kinect. Como ser puede ver en el Listado A.2, la solución propuesta continua representando las imágenes de profundidad con píxeles de 8 bits. No obstante, se ha incorporado una modificación muy importante con el objetivo de proporcionar los resultados más precisos que es posible de obtener con Kinect. Para conseguirlo, ya no se accede directamente al valor del píxel de la imagen de profundidad, sino al mapa de profundidad proporcionado por la Kinect. No obstante, se introduce un nuevo concepto que debe tenerse en cuenta: Mientras 93 que la información proporcionada por las imágenes de profundidad están almacenadas en forma de matriz bidimensional, la información proporcionada por el mapa de profundidad es devuelta como una matriz unidimensional. Por este motivo es necesario idear una estrategia que permita establecer la correspondencia directa entre un píxel concreto en la imagen y su correspondiente píxel en la matriz de profundidad. Este concepto es realmente sencillo de entender, pero que sin embargo es crucial para trabajar con las herramientas proporcionadas por O PEN NI y, por consiguiente, con SimpleOpenNI. Como se puede apreciar en la Figura 6.5, establecer una estrategia que permita calcular el píxel correspondiente entre una imagen y una matriz unidimensional resulta ser casi directo. Para este caso concreto, las imágenes tienen una resolución de 640 x 480 píxeles, o lo que es lo mismo, una matriz que está constituida por 640 filas y 480 columnas. Por lo tanto, para conocer la posición en el mapa de profundidad de un píxel que tiene un valor en la imagen de X para el eje x y un valor de Y para el eje y, tan solo es necesario aplicar la ecuación 6.2. Figura 6.5: Comparación entre los píxeles en una matriz bidimensional y una unidimensional [Bor12]. P ixel mapa de prof undidad = X + (Y ∗ 640) (6.2) Otra modificación menos importante, pero también muy interesante que se ha añadido a este ejemplo es la opción de mostrar la distancia en metros y milímetros del píxel pulsado con el ratón en vez de los valores de sus correspondientes componentes como se hacía hasta ahora. Por ejemplo, tomando como referencia la Figura 6.6, se han obtenido resultados increíblemente precisos (ver cuadro 6.1) y mucho más exactos que los que eran obtenidos en los anteriores ejemplos en los que se empleaba un rango de tan solo 255 unidades. 6.1.4 Trabajando en tres dimensiones La información proporcionada por Kinect acerca de la profundidad de los diferentes puntos pertenecientes a una escena ha sido tratada, hasta ahora, como simples metadatos de una imagen en dos dimensiones; sin embargo, hay otra manera en la que esta información de profundidad puede ser procesada. En vez de tratar los datos provenientes de Kinect como 94 Área pulsada Distancia Respaldo de la silla Asiento de la silla Pared del fondo Estantería 1539 milímetros 1039 milímetros 2777 milímetros 2478 milímetros Cuadro 6.1: Resultados del tercer ejemplo con Processing. Figura 6.6: Captura del tercer ejemplo con Processing. una imagen de profundidad bidimensional, es posible pensar que son algo más que la distancia entre un punto en el espacio y la cámara: Un conjunto de puntos en un espacio en tres dimensiones. Si se profundiza en este concepto, la información de profundidad pasaría de ser unos simples metadatos que permiten determinar la distancia de cada punto a ser un conjunto de puntos que proporciona información acerca de la ubicación exacta de cualquier objeto o persona en un espacio tridimensional, es decir, como el mundo real. De esta forma, en vez de crear las típicas imágenes en dos dimensiones, es posible simular modelos tridimensionales de las escenas donde el punto de vista de la cámara puede cambiar de perspectiva sin necesidad de variar la posición de la cámara en ningún momento. Este nuevo concepto ofrece posibilidades muy interesantes ya que, gracias a esta información tridimensional capturada por Kinect, es posible presentar al usuario una escena desde cualquier punto de vista donde puede navegar a través de una habitación sin necesidad de que nada ni nadie se mueva de su sitio. Por otro lado, también es posible desarrollar aplicaciones más avanzadas donde se interactúa con el usuario mediante objetos virtuales representados en tres dimensiones ubicados en una posición concreta dentro de la escena. 95 6.1.4.1. Nube de puntos Como se ha mencionado en los ejemplos anteriores, en Processing el origen del eje de coordenadas se encuentra situado en la esquina superior izquierda del sketch (así se denominan las aplicaciones en Processing). De esta forma, para ser capaces de entender cómo funciona una nube de puntos en Processing es importante conocer que cuando los valores de “x” aumentan, la posición se desplaza hacia la derecha hasta alcanzar el ancho máximo del sketch y que de forma análoga, cuando los valores de ‘‘y” aumentan la posición se desplaza hacía abajo hasta alcanzar la altura del sketch. En la Figura 6.7 se aprecia como los valores de “x” al aumentar su valor se desplazan hacía la derecha del sketch hasta alcanzar cómo máximo el valor 100 y al aumentar los valores de “y” se desplaza hacía abajo del sketch hasta alcanzar cómo máximo el valor 100. Tener claro este concepto será muy importante ya que para trabajar con nubes de puntos en Processing será necesario manipular constantemente el sistema de referencia de coordenadas. Figura 6.7: Origen de coordenadas bidimensional en Processing [web14v]. No obstante, al trabajar con tres dimensiones, entra en juego otra nuevo eje de coordenadas: El eje “z”. Este eje “z” tiene una dirección perpendicular a la pantalla por lo que cuando los valores de “z” aumentan la posición se desplaza hacía fuera de la pantalla (de manera figurada) y cuando disminuyen la posición de desplaza hacía el interior de la pantalla. Por lo tanto, a mayores valor de “z” la imagen se verá más cercana y por el contrario, a menores valores de “z” más pequeña. En la Figura 6.8 se observa el sistema de coordenadas tridimensional resultante. En la subsección anterior se explicaba como trabajar con los valores de profundidad proporcionados por SimpleOpenNI. Estos valores se representaban como una simple matriz unidimensional de enteros donde era necesario traducir los valores “x” e “y” de la pantalla. Sin embargo, además de estos valores de profundidad, la librería puede proporcionar los valores capturados por Kinect como un conjunto de puntos tridimensionales mediante una matriz de vectores. A su vez, cada uno de estos vectores estará compuesto por los valores correspondientes a su posición “x”, “y” y ‘‘z” en el espacio. 96 Figura 6.8: Origen de coordenadas tridimensional en Processing [web14v]. En el Listado A.3 se presenta el código necesario para implementar una nube de puntos de manera estática, es decir, desde un punto de vista fijo. No obstante, es importante destacar algunos conceptos introducidos en este nuevo ejemplo: Cambio del origen de coordenadas: Con este cambio se pretende mover el origen de coordenadas al centro del sketch de modo que la nube de puntos quede centrada en todo momento. Además, también se ha manipulado el eje “z” para que la nube de puntos esté más alejada y de esta forma no quede en ningún momento por delante de la vista. Cambio de sentido del eje “y”: Con el objetivo de ajustar correctamente la información proporcionada por Kinect y la forma en que Processing procesa esta información. SimpleOpenNI ofrece una función, depthMapRealWorld(), que permite obtener la posición de todos los puntos capturados por Kinect. Sin embargo, el sistema de coordenadas de O PEN NI (recordar que SimpleOpenNI está basada en O PEN NI) es diferente al manejado por Processing, ya que los valores de “y” aumentan con posiciones más altas en el espacio. Es por este motivo por lo que es necesario rotar 180 grados el sentido original del eje “y” en Processing. En la Figura 6.9 se presenta una captura de la aplicación durante la ejecución. No obstante, es necesario destacar algunos aspectos que pueden llamar la atención de los resultados obtenidos. En primer lugar, se puede apreciar la similitud que mantiene con las imágenes de profundidad tratadas en las subseciones anteriores como es que sigue tratándose de una imagen en blaco y negro o que siguen apareciendo sombras negras en aquellos zonas donde Kinect no ha capturado ninguna información. El motivo por el cual siguen apareciendo estas sombras negras es que, a pesar de que Kinect captura la información de cientos de puntos, el espacio es una variable continua y por lo tanto infinita. De este modo, el dispositivo tan sólo es capaz de capturar una ínfima parte de este. Por otro lado, sin embargo, se pueden apreciar algunas diferencias interesantes en el resultado. En primer lugar, se produce un aumento considerable de la carga necesaria para ejecutar 97 Figura 6.9: Captura del primer ejemplo de “Nube de puntos”. la aplicación que es debida a la gran cantidad de información que debe ser recogida, procesada y representada por cada frame capturado. En segundo lugar, llama la atención como algunos artículos del mobiliario de la habitación apenas se aprecian, como es por ejemplo el caso de la estantería que está situada al fondo (ver Figura 6.4). Esto se debe principalmente a que la gran cantidad de puntos que se están representando por pantalla en cada frame hace que estos se superpongan y por lo tanto se pierda una gran cantidad de detalle pareciendo un cuerpo sólido. Una posible solución a este problema es representar sólo parte de los puntos que han sido recogidos (ver Figura 6.10). Figura 6.10: Captura del primer ejemplo de “Nube de puntos” donde sólo se representa uno de cada diez puntos capturados. Una modificación muy interesante que se le puede aplicar a este primer ejemplo es hacer que el punto de vista vaya cambiando (ver Listado A.4). Para poder ver la nube de puntos 98 generada desde diferentes ángulos es necesario rotar esos puntos manteniéndolos en todo momento en el centro para provocar la ilusión de que el punto de vista está orbitando alrededor de la nube y no es la nube la que se está moviendo. Para lograr este efecto, es necesario introducir dos pequeños cambios al ejemplo anterior. El primero consiste en añadir una variable que vaya almacenando el ángulo de de rotación actual que será incrementado en cada frame y que será usado para rotar el origen de coordenadas. Y en segundo lugar, es necesario asegurar que esta rotación se está produciendo en todo momento con la nube de puntos en el centro del sistema de coordenadas en vez de en uno de los lados. Si esto no se hace así, cuando se esté produciendo la rotación, la nube de puntos se estará moviendo alrededor del punto de vista y por tanto en ciertos momentos la nube de puntos desaparecerá ya que se encuentra tras el punto de vista. En la Figura 6.11 se muestra una captura mediante la aplicación obtenida una vez aplicados estos cambios. Figura 6.11: Captura del primer ejemplo de “Nube de puntos” desde otro punto de vista. Como se puede apreciar, el resultado obtenido es increíble ya que sin mover la cámara en ningún momento se ha conseguido capturar y representar el perfil de la persona que se encuentra de frente a la cámara. Evidentemente hay multitud de zonas del escenario que aparecen en negro. Esto se debe, como ya se ha explicado antes, a que para esa zona no hay ninguna información, lo cual tiene mucho sentido si se considera, por ejemplo, que la parte trasera del respaldo de la silla se encuentra en todo momento oculto a la cámara y por tanto ningún infrarrojo puede incidir sobre su superficie. No obstante, en ninguno de estos ejemplos se ha explotado el potencial que puede proporcionar la combinación entre la cámara de profundidad y la cámara RGB (ver Listado A.5). Hasta este momento las nubes de puntos representadas se encontraban en blanco y negro 99 debido a que cada uno de los puntos capturados era representado como un punto de color blanco sobre un fondo negro. La idea necesaria para dotar a estos puntos con el color correspondiente de la escena simplemente consiste en acceder, para cada punto de la nube, a su píxel correspondiente de imagen RGB obtenida. Sin embargo, a pesar de que no hay nada que impida llevar a cabo la idea de combinar la información obtenida por ambas cámaras, anteriormente se explicaba (véase § 6.1.1.3) como el punto de vista de ambas cámaras no es exactamente el mismo, ya que la posición de ambas es diferente. Por este motivo es necesario llevar a cabo un alineamiento de los resultados obtenidos por ambas cámaras. Aunque el concepto es muy simple ya que tan solo sería necesario mover la referencia de la matriz obtenida en proporción a la distancia que separa las cámaras, SimpleOpenNI ofrece una función que realiza este proceso directamente de modo que la posición “x” e “y” de la matriz de profundidad y de color corresponden al mismo punto en el espacio. En la Figura 6.12 se muestra una captura mediante la aplicación obtenida una vez aplicado esta modificación donde la persona que aparece en la imagen se encuentra sentada justamente delante de la cámara. En esta ocasión es mucho más latente los pequeños agujeros negros producidos por falta de información de profundidad en determinados puntos, como por ejemplo la sombra detrás de la persona o los numerosos puntos negros en la pared. Figura 6.12: Captura del primer ejemplo de “Nube de puntos” a color. Aunque en los ejemplos se ha mostrado únicamente el concepto de cambiar el punto de vista de la cámara alrededor de la nube de puntos, esta no es la única posibilidad. También es posible realizar aplicaciones interactivas que permitan acercarse a la nube de puntos, rotar o simplemente provocar alguna acción en la aplicación. En la siguiente subsección se mostrará como algunos de los conceptos mostrados en esta subsección han sido llevados a la práctica para desarrollar aplicaciones interactivas en las que la posición del usuario establece el comportamiento de la aplicación. 100 6.1.5 Afianzando los conceptos adquiridos En la siguiente subsección se exponen algunas de las aplicaciones más llamativas que se han implementado en el transcurso del proyecto. El principal objetivo de estas aplicaciones de ejemplo no es otro que el de afianzar y poner en práctica algunos de los conceptos más importantes que se han ido recogiendo a lo largo de la presente sección y que serán de gran utilidad para comprender y manejar las siguientes etapas del proyecto. 6.1.5.1. Dibujando con Kinect La aplicación que se presenta en este apartado consiste en dibujar en la pantalla del ordenador mediante Kinect y guardar la imagen obtenida en un fichero. Para hacer esto posible, es necesario hacer un seguimiento del punto que se encuentra a una menor distancia del dispositivo. Para llevar a cabo esta tarea, es necesario ir comprobando uno a uno todos los píxeles del mapa de profundidad obtenido a través de la Kinect para averiguar cuál posee el valor mas pequeño. En el Listado 6.2 se muestra en pseudocódigo la técnica seguida para conseguirlo. Una vez que se conoce el valor y las coordenadas correspondientes del píxel más cercano, simplemente es necesario dibujar una línea que tiene como origen las coordenadas del píxel más cercano del frame anterior y como final las coordenadas del píxel más cercano del frame actual. Obtener mapa de profundidad de Kinect valo r_mas _cerca no = 8000 por cada fila ‘‘y ’ ’ en la imagen de profundidad por cada pixel ‘‘x ’ ’ de la fila i = x + y ∗ ancho de la imagen valorActual = mapaProfundidad [ i ] si valorActual > 0 y valorActual < v alor_ mas_ce rcano val or_mas _cerca no = valorActual x_mas_cercano = x y_mas_cercano = y dibujar_linea ( anterior_x , anterior_y , x_mas_cercano , y_mas_cercano ) anterior_x = x_mas_cercano anterior_y = y_mas_cercano Listado 6.2: «Dibujando con Kinect» No obstante, siguiendo la estrategia propuesta en esta primera versión, surge un pequeño inconveniente que dificulta la utilización de la aplicación: El efecto espejo. El efecto espejo hace que cuando el usuario mueve la mano hacia su derecha, el lapicero virtual dibuje la línea hacia la izquierda. Este problema se debe simplemente a que la Kinect se encuentra 101 frente al usuario y, por lo tanto, tienen los puntos de vista invertidos. La solución a este contratiempo es bastante sencilla, ya que tan solo es necesario invertir el punto de vista con el que la Kinect captura la imagen. De este modo, simplemente se debe invertir el orden de los puntos de profundidad en el eje “x”. Otro inconveniente que aparece con este primer planteamiento es que mientras que el usuario está dibujando se producen saltos entre cada frame haciendo que sea muy difícil controlar el lapicero para conseguir el resultado deseado. La solución que se ha llevado a cabo para solucionar este problema consiste en realizar una interpolación entre los puntos obtenidos en el frame anterior y los obtenidos en el frame actual. La interpolación es un proceso que permite rellenar el espacio perdido entre dos puntos conocidos, es decir, en vez de saltar directamente al siguiente punto, se orienta la línea con una dirección consistente. De esta manera, las trazas del lapicero virtual serán mucho más suaves, precisas y fáciles de controlar. En el Listado A.6 se encuentra el código resultante de la aplicación una vez aplicados las correcciones que se acaban de exponer y en la Figura 6.13 una captura obtenida a través de la aplicación. Figura 6.13: Captura de la aplicación “Dibujando con Kinect”. 6.1.5.2. Álbum de fotos En las siguientes líneas se expone como desarrollar una aplicación que lleve un poco más lejos los conceptos obtenidos a lo largo de la presente sección y que fueron ya puestos en práctica en el ejemplo “Dibujando con Kinect” mediante el seguimiento del punto más cercano. La aplicación que se propone pretende capturar, a grosso modo, la esencia de las interfaces futuristas mostradas en la película Minority Report de las que ya se habló brevemente en el capítulo de antecedentes de Kinect (véase § 4.1.2.1). 102 Básicamente, la aplicación “Álbum de fotos” permite controlar la posición de tres imágenes a través de la pantalla mediante el movimiento de la mano. Además, también ofrece la posibilidad de ampliar o reducir su tamaño acercando o alejando la mano respectivamente. No obstante, para lograr este comportamiento, los fundamentos desde los que se debe partir son básicamente los mismos que los que se emplearon en el ejemplo “Dibujando con Kinect”: Controlar la posición más cercana a la Kinect en cada momento. Una vez logrado esto, simplemente se debe incluir el comportamiento esperado de las diferentes fotografías: Cuando el punto más cercano al dispositivo se mueva a la derecha, izquieda, arriba o abajo entre frame y frame, debe cambiarse la posición de la fotografía aplicando los mismos principios empleados para mover el lapicero virtual en “Dibujando con Kinect”. Cuando la distancia entre el punto más cercano y la Kinect varíe debe realizarse un escalado de la imagen de forma relativa al valor tomado en ese momento por el punto más cercano. Cuando se pulse el botón derecho del ratón, debe cambiarse a la siguiente imagen. Por lo tanto, en este caso es necesario ir almacenando en cada momento la fotografía que se encuentra activa en ese instante y las posiciones anteriores de cada una. En el Listado A.7 se encuentra el código resultante y en la Figura 6.14 una captura obtenida a través de la aplicación. Figura 6.14: Captura de la aplicación “Álbum de fotos”. 6.1.5.3. Batería virtual La aplicación que se presenta en este apartado (Listado A.8 y A.9) tiene como objetivo afianzar los conceptos relacionados con la nube de puntos que se han aprendido en los apartados anteriores (véase § 6.1.4.1). Para ello se ha propuesto la implementación de una batería virtual que permite al usuario simular que está tocando una batería. Esta batería estará 103 compuesta por dos tambores que serán representados como cubos virtuales colocados en la región que se encuentra delante del dispositivo. De esta forma, cuando el usuario entre en contacto con alguno de los cubos se reproducirá el sonido correspondiente a dicho cubo. Una vez entendido cómo funciona las nubes de puntos, es hora de introducir un nuevo concepto para hacer posible la batería virtual, los puntos calientes. Un punto caliente consiste en una zona en el espacio, en este caso el cubo virtual, donde se tiene especial interés en averiguar si hay algún punto contenido en ella o contabilizar cuántos puntos se encuentran en esa zona. De esta forma, un punto caliente es similar a los típicos botones que se utilizan diariamente en las aplicaciones de escritorio donde se detecta cuándo ha sido pulsado por un usuario mediante un ratón cuyo puntero se encuentra situado sobre él. No obstante, a diferencia de estos botones bidimensionales que presentan un estado binario (pulsado o no pulsado), un punto caliente representa un botón tridimensional que puede ser activado por una gran variedad de eventos: Hay algún punto dentro de sus límites, hay más de cien puntos en su interior, etc. De este modo, principalmente es necesario llevar acabo dos tareas. La primera consiste en indicar al usuario cuáles son las zonas del espacio con las que puede interactuar, mientras que la segunda consiste en monitorizar esas zonas para determinar si el el usuario ha interactuado con ellas. Para realizar la primera tan sólo se necesita dibujar en el sketch las aristas de dos cubos en el área donde se quiera ubicar el punto caliente y dotarles de color cuando el usuario introduzca la mano o cualquier objeto dentro de ellos. Para llevar a cabo la segunda será necesario controlar en cada frame si cualquier parte de la nube de puntos está contenida dentro del punto caliente. La manera de contabilizar el numero de puntos de la nube que está contenida en el punto caliente, en este caso el cubo, es necesario comprobar punto a punto si cumplen los siguientes requisitos: Su coordenada x debe ser mayor que la coordenada x más pequeña del cubo y menor que la coordenada x más grande. Su coordenada y debe ser mayor que la coordenada y más pequeña del cubo y menor que la coordenada y más grande. Su coordenada z debe ser mayor que la coordenada z más pequeña del cubo y menor que la coordenada z más grande. Si cualquier punto de la nube cumple estas condiciones, es posible afirmar que se encuentra dentro del cubo. En el caso concreto de Processing, un cubo está definido por un punto origen y el tamaño de su arista. Por lo tanto, para comprobar en Processing si un punto está contenido dentro de el es necesario considerar los requisitos anteriores de la siguiente manera (ver Figura 6.15): Su coordenada x debe ser mayor que la coordenada x del origen del cubo menos la mitad del tamaño de la arista y menor que la coordenada x del origen del cubo más la 104 mitad del tamaño de la arista. Su coordenada y debe ser mayor que la coordenada y del origen del cubo menos la mitad del tamaño de la arista y menor que la coordenada y del origen del cubo más la mitad del tamaño de la arista. Su coordenada z debe ser mayor que la coordenada z del origen del cubo menos la mitad del tamaño de la arista y menor que la coordenada z del origen del cubo más la mitad del tamaño de la arista. Figura 6.15: Distribución de un cubo en Processing [Bor12]. Finalmente, para que el comportamiento de la aplicación sea lo más realista posible, es necesario tener en cuenta otro requisito más para reproducir el sonido aparte del que establece que debe haber algún punto contenido en el cubo. Este requisito indica que, para reproducir un sonido, es necesario que en el frame anterior no debía haber ningún punto en el cubo. De esta manera se asegura que el usuario debe, una vez que a tocado el cubo, levantar la mano para que sea posible volver a tocarlo, tal y como se haría en un tambor de verdad. En la Figura 6.16 se presenta una captura del resultado conseguido al llevar a la práctica todos los conceptos expuestos. 6.2 Iteración 2: Comprendiendo el funcionamiento de O PEN NI Una de las primeras etapas necesarias para el desarrollo de un sistema de reconocimiento de acciones es la implementación de una aplicación que permita capturar la información del entorno a través de un dipositivo hardware, en este caso Kinect. Es por este motivo por el que en la presente sección se pretende proporcionar una visión general acerca de los aspectos más básicos acerca de la plataforma O PEN NI que han sido cruciales para el desarrollo y depuración de esta etapa del proyecto. No hay que olvidar que uno de los aspectos que hace más interesante la utilización de Kinect para el reconocimiento de acciones es la posibilidad de capturar la posición real de las personas y objetos que se encuentran en el entorno a través de su sensor de profundidad, función que será implementada a través del middleware NiTE para O PEN NI. Motivo de más por el que una completa 105 Figura 6.16: Captura de la aplicación “Batería virtual”. y correcta comprensión sobre el funcionamiento de más bajo nivel de O PEN NI es crucial para la constitución de una base sólida sobre la que llevar a cabo las siguientes etapas del proyecto. Además, también se realiza una pequeña introducción acerca de una de las librerías de OpenGL (GLUT3 ) a través de la cual se ha logrado realizar una interfaz de usuario que permita mostrar por pantalla los datos capturados por Kinect así como interactuar con la aplicación. Por último, se muestran los resultados obtenidos de la primera aproximación del módulo que constituirá la captura de datos a través de Kinect mediante de la integración de de O PEN NI y GLUT. 6.2.1 Aspectos básicos sobre la librería Como ya se explicó anteriormente, O PEN NI es una plataforma que proporciona acceso a los sensores de profundidad compatibles con PrimeSense. Además, permite a los desarrolladores de aplicaciones inicializar los sensores y recibir los flujos de datos de profundidad, RGB y vídeo IR del dispositivo. O PEN NI también proporciona una interfaz uniforme a módulos middleware desarrollados por terceros que pueden ser usados para interactuar con estos dispositivos de profundidad. Por lo tanto, las aplicaciones son capaces de utilizar tanto el middleware de terceros, así como los datos de profundidad y de vídeo básicos subyacentes proporcionados directamente por O PEN NI. Tras esta visión general y la introducción proporcionada acerca de la evolución de la arquitectura interna de la plataforma en el capítulo de antecedentes (véase § 4.1.8.2), es el mo3 http://www.opengl.org/resources/libraries/glut/ 106 mento de profundizar un poco más y bajar un nivel más el nivel de abstracción proporcionado hasta el momento. Esto se debe a que más adelante será esencial su completa comprensión para solventar los problemas que irán surgiendo debido a la alta sobrecarga de este tipo de sistemas. Es importante destacar que algunos aspectos resultarán ya familiares. La causa de esto se debe a que la herramienta utilizada en la sección anterior, la librería “SimpleOpenNI” para Processing (véase § 6.1), estaba basada internamente en funciones proporcionadas por O PEN NI. Este hecho será de gran utilidad para comprender más fácilmente como funciona la plataforma. Para proporcionar esta visión de bajo nivel se pretende explicar en qué consiste el funcionamiento de las cuatro clases principales necesarias para obtener los flujos de información obtenidos por el dispositivo: openni::OpenNI openni::Device openni::VideoStream openni::VideoFrameRef Además de estas cuatro clases fundamentales, también se comentarán brevemente otras clases de soporte así como las estructuras que son proporcionadas por la plataforma para el almacenamiento de diferentes tipos específicos de datos. 6.2.1.1. openni::OpenNI La primera de las principales clases de las que está compuesta O PEN NI 2.0 es openNI::OpenNI. Esta clase es fundamental ya que proporciona un punto de entrada estático a la API, además de ser empleada para proporcionar acceso a todos los dispositivos en el sistema. Entre las funcionalidades más importantes que ofrece esta clase, destacan la posibilidad de realizar varios eventos de conexión y desconexión de los dispositivos que se encuentran disponibles en un momento determinado, así como proporcionar funciones que permitan el acceso a todos los flujos de datos que son capturados por el sensor. 6.2.1.1.1. Acceso al dispositivo Para proporcionar el punto de entrada estática a la API, es necesario hacer uso de la función “initialize()” proporcionado por esta clase. Esta función inicializa todos los controladores de los sensores disponibles y explora el sistema para localizar los dispositivos que se encuentran disponibles. Es importante destacar que cualquier aplicación que utiliza O PEN NI debe llamar a esta función antes de realizar cualquier otro uso de la API. Una vez que la función “initialize()” haya sido invocada, será posible crear objetos de la clase “Device” que posteriormente serán empleados para comunicarse con el hardware actual del sensor. La función “enumerateDevices()” de la clase O PEN NI permite averiguar que 107 dispositivos se encuentran conectados al sistema y que se en ese momento están preparados para ser usados. Por último, cuando una aplicación está lista para finalizar, la función “shutdown()” debe ser invocada para apagar todos los controladores y realizar una salida limpia de la ejecución. 6.2.1.1.2. Acceso a los flujos de vídeo La función “waitForAnyStream()” permite implementar un sistema de pulling para el acceso a los diferentes flujos de información proporcionados por el dispositivo. De esta forma, cuando es invocada se bloquea hasta que cualquiera de los flujos de datos de la lista pasada como parámetro tienen nuevos datos disponibles. Esta función es ideal para ser invocada desde un bucle en el que cada vez que nuevos datos son capturados, se desea realizar alguna operación con ellos, ya se mostrarlos por pantalla, procesarlos, etc. 6.2.1.1.3. Acceso a los dispositivos a través de eventos La clase O PEN NI proporciona un framework para el acceso a los dispositivos a través de un marco de ejecución dirigido por eventos. Para ello, O PEN NI define tres tipos de eventos: “onDeviceConnected”: Este evento es generado cada vez que un nuevo dispositivo es conectado y se encuentra disponible a través de la interfaz O PEN NI. “onDeviceDisconnected”: Este evento es generado genera cuando un dispositivo es retirado del sistema. “onDeviceStateChanged”: Este evento es generado cada vez que se cambia alguno los parámetros del dispositivo. Para controlar estos eventos, O PEN NI proporciona una serie de clases “listener” que pueden ser añadidas a través de los siguientes métodos: “addDeviceConnectedListener()”, “addDeviceDisconnectedListener()”, “addDeviceStateChangedListener()”, “removeDeviceConnectedListener()”, “removeDeviceDisconnectedListener()”, “removeDeviceStateChangedListener()”. Los tres eventos descritos anteriormente proporcionan un puntero a un objeto “OpenNI::DeviceInfo” que puede ser utilizado para obtener los detalles y la identificación del dispositivo contemplado por el evento. Además, el evento “onDeviceStateChanged” proporciona un puntero a un objeto “DeviceState” que permite ver cuál es el nuevo estado del dispositivo. 6.2.1.1.4. Información de errores Muchas funciones proporcionadas por la plataforma tienen un tipo de retorno especial: 108 "Status". De esta forma, cada vez que se produce un error, el estado devuelto por la función contendrá un código que puede estar tratado por el código correspondiente o simplemente ser mostrado al usuario. Además, el método “OpenNI::getExtendedError()” devuelve información adicional sobre el error que se ha producido de una manera legible para los humanos. 6.2.1.2. openni::Device Esta clase proporciona una interfaz para controlar un único dispositivo hardware. De esta manera, un objeto “Device” es usado para conectar y configurar un dispositivo y crear los diferentes objetos “Stream” que permitirán recuperar los flujos de información capturados por los sensores. No obstante, antes de que un objeto de la clase “Device” pueda ser conectado a un dispositivo hardware, es necesario que este último se encuentre físicamente conectado al ordenador. También es necesario que la función “openni:initialize()” haya sido previamente invocada para inicializar los drivers correspondientes al dispositivo y marcarlo como disponible a través de la API. A continuación se describen las funciones más importantes que se encuentran disponibles a través de esta clase: Constructor: Esta función no toma argumentos ya que simplemente crea el objeto en la memoria para que otras funciones puedan ser invocadas. Device:open(): Esta función es muy importante ya que es la que realmente conecta el objeto “Device” con el dispositivo hardware. Para ello toma tan solo la URI del dispositivo como argumento, devolviendo un código de estado indicando si la operación ha sido realizada con éxito o qué error se ha producido. No obstante, el uso más simple de esta función es invocarla con la constante “OpenNI::ANY_DEVICE” como URI para que el sistema se conecte a cualquier dispositivo hardware compatible que se encuentre activo en ese momento. Esto puede resultar verdaderamente útil cuando es posible suponer con total seguridad que hay exactamente un dispositivo activo conectado al sistema. En el caso de que haya múltiples dispositivos conectados al sistema, se debe realizar antes una llamada al método “enumerateDevices()” de la clase O PEN NI para obtener una lista de todos los dispositivos que se encuentran conectados y así poder obtener la URI correspondiente al dispositivo deseado para la función “open()” . Device:close(): Esta función permite cerrar correctamente el dispositivo de hardware. de esta forma, tanto el driver como el dispositivo hardware quedarán en un estado conocido para que las aplicaciones futuras no tengan dificultades para conectarse a ellos. Device:isValid(): Esta función permite determinar si existe actualmente un dispositivo activo conectado a este objeto “Device”. 109 Por último, es necesario destacar que también es posible obtener la información básica acerca de un dispositivo y que posteriormente puede ser de gran utilidad como son el nombre, el proveedor, la URI, etc. Para ello, O PEN NI proporciona la clase “OpenNI::DeviceInfo” para contener toda esta información. De esta manera, si se desea obtener el objeto “DeviceInfo” de un dispositivo concreto es necesario llamar a la función “Device:getDeviceInfo()”. 6.2.1.3. openni::VideoStream Esta clase encapsula todos los flujos de datos creados por la clase de “Device” permitiendo al programador solicitar que la captura de determinados flujos de datos comiencen (“VideoStream::start()”), paren (“VideoStream::stop()”) o simplemente indicar su configuración. Una vez que un VideoStream ha sido creado a través de la función “VideoStream::create()”, los datos pueden ser leídos de ella directamente con la función “VideoStream::readFrame”. De esta forma, si hay nuevos datos disponibles, esta función facilitará el acceso al objeto VideoFrameRef más reciente que haya sido generado por el VideoStream. Si no hay ningún nuevo frame listo todavía, la función se bloqueará hasta que un nuevo frame esté disponible. Por último, tan sólo destacar que la clase VideoStream ofrece la posibilidad de recuperar la información capturada por los dispositivos a través de eventos. 6.2.1.4. openni::VideoFrameRef Esta clase tiene el objetivo de encapsular todos los datos relacionados a un solo tipo de frames leídos a través de un VideoStream mediante la función “VideoStream::readFrame()”. De esta forma, mediante la función “VideoFrameRef::getData()” proporciona acceso a la matriz subyacente que contiene los datos del frame, así como los metadatos que son requeridos por el programador para trabajar con dichos datos. Esta metainformación en las venideras etapas del proyecto serán básicas para el procesamiento y categorización de los frames que serán capturados por la aplicación. Algunos de los más destacados son la marca temporal de captura, la resolución, el índice de frame, etc. 6.2.2 GLUT OpenGL Utility Toolkit (GLUT) es una interfaz de programación enlazada con ANSI C y FORTRAN con el objetivo de facilitar el desarrollo de programas basados en OpenGL de manera independiente del sistema operativo. Las funcionalidades más destacadas ofrecidas por esta biblioteca de utilidades son: Múltiples ventanas de renderizado OpenGL. Dispositivos de entrada sofisticados. Rutinas para la generación de objetos. Diversas funciones de gestión de ventanas. 110 Soporte de mapas de bits. Procesamiento de eventos. Rutina “idle” y temporizadores. La biblioteca GLUT original fue escrita por Mark Kilgard, autor de OpenGL Programming for the X Window System [Kil96] y The Cg Tutorial: The Definitive Guide to Programmable Real-Time Graphics [FK03]. Sin embargo, el proyecto inicial de Kilgard ya no ofrece mantenimiento y su licencia no libre no permite la redistribución de versiones modificadas de la biblioteca. Es por este hecho por el que comenzaron a surgir diferentes implementaciones libres de la API implementadas desde cero. La primera fue freeglut4 , con la intención de convertirse en un clon bastante exacto de la original, aunque con un un pequeño número de nuevas funciones para hacer frente a las limitaciones de GLUT que más adelante se comentan. Existe también otra variante de freeglut llamada OpenGLUT 5 , que añade algunas nuevas funcionalidades respecto de la API original. No obstante, no hay que perder de vista que GLUT surgió con el objetivo de simplificar la implementación de programas usando OpenGL como herramienta de renderizado y permitir el desarrollo de código más portable entre diferentes sistema operativos. Es por esta razón por la que el API de GLUT está compuesto de tan solo unas pocas rutinas para mostrar escenas gráficas renderizadas a través de OpenGL. Estas rutinas, a su vez, están lógicamente organizadas en varias sub-APIs de acuerdo a su funcionalidad: Inicialización: Se encarga del procesamiento de la línea de comandos, la inicialización del sistema de ventanas y el estado de creación de la ventana inicial. Procesamiento de eventos: Esta rutina entra en bucle de procesamiento de eventos de GLUT. Además, no retorna nunca y llama continuamente a los “callbacks” de GLUT siempre que es necesario. Gestión de ventanas: Rutinas encargadas de la creación y control de ventanas. Gestión de superposición: Rutinas encargadas de establecer y gestionar la superposición de ventanas. Gestión de menús: Rutinas encargadas de crear y controlar los menús “pop-up”. Registro de devolución de llamadas: Rutinas encargadas de registrar los callbacks que serán llamados por el bucle de procesamiento de eventos GLUT. Gestión del “Colormap”: Estas rutinas permiten la manipulación de los mapas de colores empleados en las ventanas. Recuperación de estado: Estas rutinas permiten a los programas recuperar el estado de GLUT. 4 5 http://freeglut.sourceforge.net/ http://openglut.sourceforge.net/ 111 Renderizado de fuentes: Estas rutinas permiten el renderizado del trazado y mapas de bits de las diferentes fuentes. Renderizado de formas geométricas: Estas rutinas permiten el renderizado de formas geométricas en tres dimensiones incluyendo esferas, conos, icosaedros, etc. Para trabajar con esta herramienta, es necesario estar relacionado con algunos aspectos de la terminología de GLUT. Algunos de los más destacados son los siguientes: “Callback”: Rutina específica que puede ser registrada en GLUT para ser llamada en respuesta de un tipo de evento concreto. También es utilizada para referirse a una rutina “callback” específica para la devolución de una llamada. “Colormap”: Proporciona un mapeo entre los valores de un píxel y los valores de los colores RGB. “Idle”: Estado en el que se notifican los eventos del sistema de ventanas para su procesamiento. Si se existe algún “callback” registrado para el evento correspondiente, será invocado. “Menú pop-up”: Menú que puede ser configurado para que aparezca cuando se presiona un botón específico del ratón en una ventana. “Sistema de ventanas”: Concepto que se refiere al mecanismo y política del sistema y gestión de ventanas. Por ejemplo, en el sistema X Window, tanto el administrador de ventanas y como el servidor X son parte integral de lo que GLUT considera el sistema de ventanas. Como se puede apreciar, GLUT es una herramienta ideal para programas simples en las que las necesidades del programador son muy concretas y de alto nivel. Además, introducirse en la programación con OpenGL utilizando GLUT conlleva normalmente sólo unas pocas líneas de código y hace innecesario el conocimiento de las APIs específicas de cada sistema operativo. No obstante, esta biblioteca multiplataforma se encuentra con algunas limitaciones que dificultan la labor del programador para el desarrollo de tareas específicas. Entre las más destacadas se encuentran: La biblioteca exige a los programadores invocar a la función “glutMainLoop()”, función que nunca finaliza. Es por esto por lo que los programadores se encuentran con serios problemas para integrar GLUT en aplicaciones o bibliotecas en las que es necesario poder tener control sobre su propio ciclo de ejecución. No obstante, existen diferentes aproximaciones para solucionar este inconveniente. Una de las más habituales consiste introducir una nueva función, que suele llamarse “glutCheckLoop()“, que ejecute una sola iteración del ciclo de ejecución de GLUT. Otra posible solución puede ser la de ejecutar GLUT por separado mediante hilos, aunque esto puede ser distinto dependiendo del sistema operativo pudiendo provocar de esta manera problemas 112 de sincronización. El hecho de que la función “glutMainLoop()” nunca termine supone que el programa no sale nunca del ciclo de ejecución. Otra implementaciones basadas en GLUT, como por ejemplo freeglut, soluciona este problema introduciendo una nueva función “glutLeaveMainLoop()” que permite decidir en tiempo de ejecución si salir del bucle principal. La biblioteca termina el proceso cuando se cierra la ventana principal del programa suponiendo un inconveniente en determinadas situaciones en las que este comportamiento puede no ser el deseable. Por eso muchas implementaciones incluyen una función extra llamada “glutWMCloseFunc()”. A pesar de estas limitaciones, durante esta etapa del proyecto se decidió emplear GLUT ya que, además de que la funcionalidad que proporcionaba resultaba completamente suficiente para los objetivos marcados, ofrecía una solución rápida de aprender, relativamente ligera en comparación a otras alternativas y que además permitía obtener un código sencillo y claro. 6.2.3 Primera versión del módulo de captura de imágenes En esta primera aproximación de la solución se pretende desarrollar la base sobre la que se asentará el módulo de captura de imágenes. De este modo, el principal objetivo marcado en esta etapa no será otro que el desarrollo del esqueleto de la aplicación a partir del cual se irán añadiendo de manera iterativa diversas mejoras y funcionalidades a lo largo del proyecto. Por lo tanto, será necesario realizar un pequeño estudio acerca de las posibilidades ofrecidas por las herramientas comentadas en los apartados anteriores y la manera de integrarlas en el módulo para obtener el máximo rendimiento. El primer paso realizado para la consecución de este objetivo es la definición de cuáles serán las funcionalidades deseadas para esta primera versión. Para ello, se han definido los siguientes hitos: Captura del flujo de datos de la cámara RGB. Captura del flujo de datos del sensor de profundidad. Visualización de los flujos de datos capturados por el dispositivo a través de una interfaz de usuario sencilla y minimalista. Integración de comandos de teclado básicos que permitan a través de la interfaz de usuario interactuar con la aplicación: • Cerrar la aplicación. • Seleccionar que flujo de datos se debe mostrar por pantalla. 113 Una vez que los hitos que deben ser alcanzados con esta primera iteración del módulo están definidos, es el momento de realizar el primer diseño de clases. Como se puede apreciar en la Figura 6.17, la solución propuesta está compuesta de dos clases. La clase “Main” es la clase principal y su función no es otra que inicializar todos los aspectos necesarios para comenzar a utilizar el dispositivo y controlar que los resultados obtenidos de esta inicialización son los esperados. En segundo lugar se ha definido la clase “Recorder”, encargada de gestionar todos los aspectos relacionados con el procesado de los flujos obtenidos a través del dispositivo y su posterior renderizado para mostrarlos por pantalla. Figura 6.17: Diagrama de clases del módulo de captura de imágenes (versión 1). Una vez que la solución propuesta para esta primera versión fue implementada, se llevó a cabo una pequeña batería de pruebas para verificar que los resultados son los deseados y corregir aquellos errores no deseados que se puedan producir durante la ejecución como pueden ser desbordamientos de memoria, pérdida de frames, etc. A continuación se muestran algunas capturas de los resultados obtenidos (ver Figura 6.18 y Figura 6.19) 6.3 Iteración 3: Incorporación de NiTE Una vez que se han entendido los principios más importantes acerca del funcionamiento de O PEN NI y GLUT y se tiene la base del módulo de captura de imágenes a partir de la cual 114 Figura 6.18: Módulo de captura de imágenes en modo RGB. Figura 6.19: Módulo de captura de imágenes en modo profundidad. se van a implementar el resto de funcionalidades, es el momento de realizar la primera toma de contacto con NiTE. Es por este motivo por el que en la presente sección se pretende proporcionar una visión general acerca de los aspectos más relevantes que deben de ser tenidos en cuenta a la hora de utilizar la plataforma NiTE. También se desarrollará la forma en que funciona internamente este middleware así como los principales algoritmos de reconocimiento y seguimiento de usuarios que pone a disposición de los desarrolladores. No obstante, será necesario proporcionar también una visión aproximada sobre la forma en la que trabaja NiTE internamente, algo indispensable para solucionar algunos aspectos que deberán de ser mejorados en módulo de captura durante su desarrollo. Por último, se muestra la evolución que ha ido experimentando el módulo a lo largo de las diferentes iteraciones según se iban incorporando nuevas funcionalidades y se corregían los problemas que se iban encontrando. 115 6.3.1 Toma de contacto con NiTE Como ya se comentaba brevemente en la sección de antecedentes (véase § 4.1.8.2), uno de los middleware más importantes y potentes para la plataforma O PEN NI es NiTE. De esta forma, NiTE constituye un de los middlewares más avanzados y robustos del mercado en el campo de visión por computador en 3D. NiTE proporciona a los desarrolladores una API relativamente sencilla poniendo a su alcance potentes algoritmos que permiten el diseño de aplicaciones controladas por las manos y la posición del cuerpo del usuario. Estos algoritmos utilizan la información de profundidad, color e IR recibida por el sensor para realizar tareas como la localización y seguimiento de las manos, análisis de escenas (separando a los usuarios del fondo de la imagen), seguimiento preciso del esqueleto, reconocimiento de gestos, etc. A continuación se desarrollarán los aspectos más básicos e importantes sobre los dos componentes principales de la API, cuyo análisis y entendimiento es crucial para la presente etapa del proyecto: Seguimiento de manos y detección de gestos. Seguimiento del cuerpo. 6.3.1.1. Seguimiento de manos y detección de gestos El seguimiento basado en las manos es la posibilidad que ofrece NiTE para seguir a los usuarios a través de los algoritmos de seguimiento de manos o detección de gestos discretos. Para alcanzar este objetivo, las aplicaciones que empleen cualquiera de estos dos tipos de algoritmos deben seguir las instrucciones y convenciones desarrolladas a continuación. De esta forma, será posible implementar pequeños ejemplos que faciliten el análisis de las posibilidades reales que ofrecen y por lo tanto recopilar suficiente información de primera mano que permita determinar si estas funcionalidades de seguimiento de manos y detección de gestos aportan resultados de valor para el objetivo del proyecto. Para ello, el primer paso es entender el funcionamiento de la API que, debido a la alta encapsulación que presenta, en primera instancia puede resultar verdaderamente complicada. Al igual que ocurría con la API de O PEN NI, el primer paso necesario para empezar a emplear los algoritmos que ofrece NiTE es inicializar la clase “HandTracker” para conectar con el objeto “Device” relacionado con un dispositivo hardware concreto (véase § 6.2.1.2). De esta forma, cada vez que un objeto “Device” crea un nuevo frame de profundidad, la clase HandTracker genera los datos correspondientes a la manos a las que se les está realizando el seguimiento. Toda esta información será devuelta en la clase contenedora “HandTrackerFrameRef” con los siguientes datos: Frame de profundidad. Manos identificadas. 116 Posiciones de las manos. Manos que aparecían en el frame anterior pero que en el actual han desaparecido de la escena. Gestos identificados en el frame actual. En el Listado 6.3 se muestra un fragmento de un pequeño ejemplo de cómo debería realizarse este proceso de detección de gestos. La dinámica a seguir es bastante sencilla, ya que tan solo es necesario indicar al algoritmo qué gestos son los deseados para realizar el seguimiento (líneas 1 y 2), recuperar los gestos detectados (línea 4) y posteriormente realizar las operaciones deseadas para aquellos gestos que hayan sido completados (líneas 5-12). 1 2 handTracker . s t a r t G e s t u r e D e t e c t i o n ( nite :: GESTURE_WAVE ) ; handTracker . s t a r t G e s t u r e D e t e c t i o n ( nite :: GESTURE_CLICK ) ; 4 const nite :: Array < nite :: GestureData >& gestures = handTrackerFrame . getGestures () ; for (int i = 0; i < gestures . getSize () ; ++ i ) { if ( gestures [ i ]. isComplete () ) { nite :: HandId newId ; handTracker . sta rtHand Tracki ng ( gestures [ i ]. ge tCu rr en tP os it io n () , & newId ) ; } } 5 6 7 8 9 10 11 12 Listado 6.3: Detección de poses con NiTE A pesar de que la detección de gestos que ofrece NiTE podría ser una herramienta verdaderamente útil para el posterior reconocimiento de acciones, uno de los principales objetivos del proyecto, tras un análisis exhaustivo se ha concluido que para tal fin presenta serias limitaciones. La más destacada es el hecho de que NiTE sólo tiene definido dos tipos de de gestos: “Click”: Consiste en acercar la mano hacia la cámara y después alegarla de ella. “Wave”: Consiste en mover la mano de un lado a lado, como si se estuviera saludando a la cámara. Una opción que podría haber sido interesante para enriquecer estos algoritmos es añadir los gestos deseados a la API. No obstante, es necesario recordar que la licencia bajo la que este middleware es distribuido lo impide. Por lo tanto, se ha decidido no integrar este tipo de algoritmos proporcionados por NiTE ya que no aportan valor real a la solución perseguida por este proyecto. 117 6.3.1.2. Seguimiento del cuerpo Los algoritmos de obtención de la posición del cuerpo humano a partir de las articulaciones de los usuarios hacen del middleware NiTE un componente de gran valor para el desarrollo del presente proyecto. Además, también proporcionan la capacidad de segmentar a los usuarios, detección del plano del suelo, detección de poses y el seguimiento del esqueleto. El primer paso que debió seguirse para la correcta integración de estos algoritmos en este módulo del proyecto fue analizar y comprender como procesa NiTE el flujo de datos proporcionados por el sensor, que información proporciona y cómo interpretarla y por último identificar las clases y funciones correspondientes a estos algoritmos así como su manera de proceder junto con las limitaciones que presenta. 6.3.1.2.1. Funcionamiento Aunque el funcionamiento interno de NiTE no es de dominio público, realizando un análisis exhaustivo de su forma de trabajar y del API es posible realizar una aproximación de cómo procede internamente para la detección de usuarios. En la Figura 6.20 se puede apreciar que los usuarios pasan por tres estados: Nuevo usuario: Un nuevo usuario ha entrado en la escena pero aún no se ha calibrado su posición. Siguiendo usuario: Tras ser detectado un nuevo usuario, este pasa al estado de usuario seguido dónde se encuentra disponible toda la información relativa a su posición, articulaciones, orientación, etc que se estudiará más adelante. Usuario perdido: Estado al que pasa un usuario que estaba siendo seguido tras haber salido de la escena o debido a la incapacidad de los algoritmos de NiTE de proporcionar información precisa sobre él. Cuando NiTE recibe la señal de realizar el seguimiento de usuarios, aplica internamente sus algoritmos de procesado a cada frame que es capturado por el dispositivo. Una vez que ha realizado los cálculos pertinentes, obtiene una lista de todos los posibles usuarios que hay presentes en la escena. En un segundo paso, NiTE aplica los algoritmos correspondientes para realizar la calibración de la posición de cada usuario detectado en la etapa anterior. Si esta última etapa es realizada con éxito, NiTE será capaz de proporcionar toda la información relativa al usuario. 6.3.1.2.2. Análisis e interpretación de la información proporcionada La correcta realización del análisis e interpretación de la información ofrecida por los algoritmos de NiTE es crucial y potencialmente crítica para una correcta integración de las funcionalidades de seguimiento de usuario en este módulo del proyecto. Por este motivo, 118 Figura 6.20: Funcionamiento del seguimiento de usuarios con NiTE [web14u]. durante el desarrollo del proyecto esta etapa abarcó varias semanas ya que un error de interpretación de los resultados sería arrastrado en las etapas posteriores. En primer lugar, es muy importante tener en cuenta que NiTE trabaja con dos tipos de coordenadas: Coordenadas de profundidad (proyectivas) y coordenadas del mundo real. Este último tipo de coordenadas son medidas en milímetros siguiendo un sistema de coordenadas como el que se muestra en la Figura 6.21. De esta manera, cuando un punto en el espacio se desplaza hacía la izquierda del dispositivo la coordenada x aumentará; según aumente la distancia del punto con respecto el suelo mayor será el valor de y; y por último cuando más alejado se encuentre un punto respecto la Kinect mayor será su componente z. No obstante, NiTE ofrece la posibilidad de convertir un punto entre ambos tipos de coordenadas. Figura 6.21: Sistema de coordenadas de NiTE. NiTE distingue entre los diferentes usuarios que se encuentran mediante un id que le será 119 asignado en el primer frame en el que aparece en escena. Una vez que el usuario es calibrado, NiTE proporciona la siguiente información: Límites del usuario: Proporciona un cubo de volumen mínimo que contiene completamente el usuario. Las coordenadas son proyectivas, por lo que son aptas para su uso directo en un mapa de profundidad. Centro de masa: Permite encontrar el centro geométrico de la masa del usuario. Este valor viene dado en las coordenadas del mundo real, por lo que debe ser convertido antes de ser superpuesto sobre un mapa de profundidad. Pose: Representa toda la información acerca de una postura específica para un usuario concreto. Estado: Este parámetro resultará de vital importancia para filtrar la información proporcionada por NiTE. De esta manera, será posible determinar en qué estado se encuentra un usuario concreto según la Figura 6.20. Es necesario tener en cuenta que cuando un usuario es perdido, su id podrá volver a ser asignado a otro usuario o volver a aparecer en escena con un id diferente. Esqueleto: Está compuesto por un estado y quince articulaciones. • Estado: Al igual que ocurre con el estado del usuario, este valor permitirá filtrar aquellos esqueletos según se encuentren en estado de calibración, calibrados o sin información. • Articulaciones: En la Figura 6.22 se representan las quince posibles articulaciones que pueden ser monitorizadas a través de NiTE. Cada articulación estará compuesta a su vez por: ◦ La orientación y confidence: Estimación de la orientación de una articulación en el espacio y su nivel de precisión. La orientación está representada por un cuaternión (w, x, y, z). El confidence será un valor comprendido entre 0 y 1, siendo 1 el máximo valor de precisión obtenible. ◦ La posición y confidence: Estimación de la posición de una articulación en el espacio y su nivel de precisión. La posición está representada por las coordenadas (x, y, z) en el mundo real. El confidence será un valor comprendido entre 0 y 1, siendo 1 el máximo valor de precisión obtenible. 6.3.2 Evolución del módulo de captura de imágenes En la sección anterior (véase § 6.2) se explicaban los aspectos más importantes sobre O PEN NI y GLUT así como la forma en la que se afrontó la implementación de la primera versión del módulo de captura de imágenes. En las siguientes subseciones se pretende desarrollar los aspectos más relevantes sobre el proceso de integración del middleware NiTE en la solución propuesta y la evolución que ha ido experimentado a lo largo del proyecto. 120 Figura 6.22: Articulaciones detectadas por NiTE [web14u]. Además se presentarán los principales problemas que han ido surgiendo durante su diseño e implementación así como la soluciones que se han propuesto para su solventación. 6.3.2.1. Segunda versión En la primera versión del módulo de captura de imágenes (véase § 6.2.3) se desarrolló la base a partir de la cual se pretende ir incorporando nuevas funcionalidades. Esta primera aproximación tan sólo permitía capturar los flujos de datos RGB y de profundidad capturados por Kinect mediante la plataforma O PEN NI así como su renderizado por pantalla a través del módulo de GLUT (módulo de OpenGL). Sin embargo, el principal objetivo de este módulo no es otro que la capacidad de almacenar, y no sólo mostrar, los datos que son capturados por el dispositivo. Además, se pretende enriquecer esta información recogida mediante los algoritmos que ofrece NiTE acerca del seguimiento de usuarios estudiados en los apartados anteriores. El primer paso que se llevó a cabo para afrontar esta tarea fue definir los hitos esperados de esta nueva iteración del desarrollo del módulo. A continuación se presentan los más significativos: Integración de NiTE: • Seguimiento del esqueleto. • Distinción entre píxeles pertenecientes a un usuario con los que pertenecen al entorno. • Procesamiento de la información de seguimiento. Almacenamiento en ficheros de las imágenes y metadatos. Visualización a través de la interfaz de usuario de la combinación del flujo de datos de 121 profundidad y los esqueletos de los usuarios. Incorporación de nuevos comandos de teclado para permitir interactuar con las nuevas funcionalidades integradas a través de la interfaz de usuario: • Dibujar esqueleto. • Dibujar etiqueta de estado. • Dibujar centro de masa. • Dibujar caja de volumen máximo de un usuario en el espacio. • Dibujar fondo. • Selección de que flujos de datos se desea almacenar. • Iniciar el almacenamiento de los datos capturados. • Mostrar el identificador del frame mostrado por pantalla. Una vez que los hitos que deben ser alcanzados en esta segunda iteración fueron definidos, fue necesario rediseñar algún aspecto del modelo de clases que se propuso anteriormente. Para dar soporte a estas nuevas funcionalidades fue necesario incorporar nuevos métodos que se encargaran de procesar y almacenar los flujos RGB y profundidad junto con sus metadatos en ficheros así como el dibujado del esqueleto. Además, también se realizó un proceso de reestructuración en los métodos ya existentes para integrar los aspectos relacionados con el seguimiento y tratamiento de las articulaciones de los usuarios. En la Figura 6.23 se muestra el modelo de clase resultante tras este proceso de análisis y diseño. Una de las novedades más interesantes que ha sido introducida en esta iteración es la forma en la que se procesa el flujo de datos de profundidad. Hasta el momento, simplemente se renderizaban los datos capturados por el dispositivo tras un simple procesamiento mediante el histograma proporcionado por la plataforma O PEN NI. Sin embargo, NiTE ofrece la posibilidad de distinguir qué puntos pertenecen a un usuario y cuáles pertenecen al entorno que le rodea. De esta forma, resultó muy interesante la idea de introducir una nueva forma de procesar los datos de profundidad capturados por el dispositivo mediante la combinación de ambos procesamientos. Por lo tanto, es posible producir imágenes que distingan entre aquellos píxeles que pertenecen a un usuario y los que pertenecen al entorno pintándolos de una color diferente a la escala de grises. En la Figura 6.24 se muestra el resultado obtenido tras aplicar ambas técnicas de procesamiento. Una técnica muy utilizada en el análisis de secuencia de imágenes es el “background substraction”. Esta técnica consiste la eliminación del fondo o “background” y que para el objetivo de este proyecto sería realmente interesante ya que permitiría eliminar mucho ruido permitiendo así obtener mejores resultados en el clasificador de acciones. Por lo tanto, también se ha introducido la posibilidad de eliminar de la imagen todo aquello que no fueran usuarios pintando de negro aquellos píxeles que no pertenezcan a un usuario (ver Figura 6.25). El resultado obtenido es comúnmente conocido como “blob”.Esto resulta verdaderamente 122 Figura 6.23: Diagrama de clases del módulo de captura de imágenes (versión 2). Figura 6.24: Resultado de la combinación de las técnicas de procesamiento. interesante ya que reducirá sustancialmente la carga en futuras etapas del proyecto debido a que no sería necesario realizar este proceso mediantes técnicas más complejas. De manera similar, es posible combinar las funciones de dibujado de figuras proporcionadas por GLUT y la información acerca de la posición de cada una de las articulaciones de los usuarios facilitada por NiTE. El resultado obtenido se puede observar en las Figuras 6.26 y 6.27. Para conseguir este resultado simplemente ha sido necesario dibujar sobre la imagen de profundidad líneas que unen cada una de las articulaciones capturadas conformando el 123 Figura 6.25: Resultado de la eliminación del fondo. esqueleto aproximado del usuario. Además, se han dibujado etiquetas con las coordenadas correspondientes de cada articulación para obtener de esta forma cierta retroalimentación y poder así comprobar la precisión de las medidas calculadas por NiTE. Por último, para estudiar de manera visual como varía el nivel de “confidence” para cada articulación que se comentaba anteriormente (véase § 6.3.1.2.2) se ha integrado en el dibujado del esqueleto la funcionalidad de variar la intensidad y el color de las líneas en función del valor tomado por este parámetro. Figura 6.26: Dibujado del esqueleto sobre la imagen de profundidad. El último paso que queda para completar esta iteración es el de implementar la funcionalidad de guardado de imágenes tras ser capturadas y procesadas con las técnicas expuestas en los párrafos anteriores. Para llevar a cabo esta tarea se decidió emplear un formato de imagen sencillo que permitiera guardar en crudo los valores obtenidos. Aunque en la siguiente interacción se comprobaría que no se trata de la mejor opción, el formato elegido fue Portable PixMap format (PPM). PPM es un formato de imagen sin comprensión perteneciente a la familia Netpbm diseñado para ser extremadamente fácil de comprender por humanos 124 Figura 6.27: Dibujado del esqueleto eliminando el fondo. y máquinas. A continuación se muestra cómo es la estructura interna de este formato para ejemplificar el porqué de su sencillez: Un “número mágico” que identifica el tipo de fichero (en este caso “P3”). Un espacio en blanco. El ancho de la imagen especificado en caracteres ASCII. Un espacio en blanco. El alto de la imagen especificado en caracteres ASCII. Espacio en blanco. “Maxval”: El valor máximo del color especificado en caracteres ASCII. Valores de los componentes de cada píxel en caracteres ASCII. Como se puede apreciar en el ejemplo 6.4 y su correspondiente imagen (Figura 6.28), PPM es un formato verdaderamente sencillo de entender y procesar. Este hecho permitió poder generar los ficheros sin herramientas especializadas en el tratamiento de imágenes, ya que al estar codificado en ASCII, era posible emplear directamente las funciones facilitadas por las librerías estándar de C++. Además, como ofrece la posibilidad de incluir comentarios dentro del fichero, la inclusión de los metadatos asociados a cada imagen era realmente sencilla de realizar con la ventaja de estar contenida en el mismo fichero que los propios datos. Figura 6.28: Imagen correspondiente al ejemplo 6.4. 125 P3 # The P3 means colors are in ASCII , then 3 columns and 2 rows , # then 255 for max color , then RGB triplets 3 2 255 255 0 0 0 255 0 0 0 255 255 255 0 255 255 255 0 0 0 Listado 6.4: Ejemplo del formato PPM. Por último, para tener organizados los ficheros creados y facilitar así su posterior tratamiento, se ha decidido crear una estructura de directorios que permita separar las imágenes según el tipo de imagen (RGB o de profundidad). Para ello es necesario indicar como argumentos del programa la ruta y el nombre base dónde se desea que trabaje. Como se puede apreciar en la Figura 6.29, se crean dos directorios (uno para cada tipo de imagen) donde se guardarán los ficheros con un nombre significativo. Este nombre estará compuesto por el nombre base que se ha pasado como argumento, el índice dentro de la secuencia de frames que le pertenece y por último una marca temporal. Esta decisión fue tomada para que posteriormente sea posible obtener la información más importante sobre una imagen sin necesidad de abrir el fichero para conocerla. Figura 6.29: Estructura de directorios. 6.3.2.2. Tercera versión La tercera iteración del módulo de captura de imágenes está destinada a la mejora y corrección de problemas. Tras la realización de diversas pruebas de rendimiento, se identificaron dos contratiempos importantes: Pérdida de frames debido al procesamiento y la generación de los frames y de los ficheros. 126 Consumo de memoria excesivo de los ficheros PPM de las imágenes RGB y de profundidad. No obstante, debido a la complejidad y a la gran variedad de cambios que supone la resolución de estos dos problemas, se ha decidido abordarlos por separado posponiendo la solución al problema del excesivo consumo de memoria para la siguiente iteración. En primer lugar, es importante destacar que la pérdida de frames es un problema potencialmente crítico para el sistema que se está desarrollando ya que se estarían produciendo saltos en los datos capturados que impedirían obtener la secuencia completa de una acción y, por lo tanto, espacios temporales en los que el sistema no tendrá información que cotejar. Como ya se trató en la sección acerca de las especificaciones técnicas (véase § 4.1.4), Kinect tiene una tasa de captura de 30 frames por segundo. Por consiguiente, teóricamente se deben generar y procesar aproximadamente tres mil ficheros por segundo. No obstante, estas cifras son siempre teóricas ya que alcanzar esta tasa es realmente difícil debido a diversas causas: Retrasos debidos a la comunicación entre Kinect y el ordenador. Las características técnicas del ordenador (procesador, tarjeta gráfica, etc.) y otros procesos que se encuentren ejecutando en ese momento.. y NiTE introduce carga computacional al realizar tareas de preprocesado y refinamiento en los datos capturados. O PEN NI El procesamiento que se le está realizando a cada frame y su posterior almacenamiento se está llevando a cabo de manera secuencial. Como se puede apreciar, el problema más evidente que está produciendo esta gran pérdida de frames es el procesamiento secuencial. Para solucionar este problema es necesario tener claro cuál es el orden lógico en la realización de las diversas tareas que se están llevando a cabo. Como se puede apreciar en la Figura 6.30, cuando se capturan los frames RGB y de profundidad correspondientes, estos no vuelven a ser capturados hasta que no se hayan realizado todas las tareas de procesado de las imágenes y almacenamiento en ficheros PPM. Es en este momento cuando resulta crucial el buen entendimiento acerca de cómo funciona O PEN NI y NiTE, ya que cuando alguno de ellos recibe un frame, este se encontrará accesible sólo hasta que otro nuevo frame sea recibido. Por ejemplo, si en un momento dado se están procesando los frames 13500 y 13521, cuando estos terminen su tratamiento correspondiente, los siguientes frames que estarán disponibles podrían ser el 14001 y 140022. De este modo, esos 501 frames que no han sido solicitados ya no podrán ser recuperados. La solución propuesta a este problema consiste en paralelizar algunos aspectos en el tratamiento de las imágenes. De este modo, se podrán diferenciar tres tipos de hilos que han sido implementado mediante la librería POSIX: 127 Figura 6.30: Modelo de flujo de la ejecución secuencial. Hilo principal: Encargado de recoger los frames disponibles y realizar las tareas principales del programa. Hilo procesamiento RGB: Encargado de procesar el frame RGB enviado por el hilo principal y generar el fichero PPM correspondiente. Hilo procesamiento profundidad: Encargado de procesar el frame de profundidad enviado por el hilo principal y generar el fichero PPM correspondiente. De esta forma, cada vez que el hilo principal recibe nuevos frames generará dos nuevos hilos (uno por cada tipo de frame) y almacenará sus referencias en una lista. Posteriormente, cuando el hilo principal reciba una señal de finalización, esperará a que todos los hilos para los que tiene una referencia almacenada en la lista hayan terminado. Como se puede apreciar, entre los hilos hijos nunca habrá problemas de sincronización ya que el orden en que se ejecuten o terminen no afectará a los demás ni al resultado esperado. Tras realizar de nuevo las pruebas de rendimiento, se observa que la tasa de frames que son procesados ha aumentado sustancialmente consiguiendo no perder ningún frame ofrecido por O PEN NI y NiTE. De este modo, se ha logrado solucionar el problema de pérdida de frames alcanzando una tasa de procesamiento por encima de la necesaria para lograr una secuencia de imágenes óptima para su posterior tratamiento y clasificación por acciones. 128 Figura 6.31: Modelo de flujo de la ejecución concurrente. 6.3.2.3. Cuarta versión Como ya se adelantaba anteriormente, se ha identificado un serio problema que provoca un consumo excesivo de memoria. De esta forma, uno de los principales objetivos de esta nueva iteración será el de encontrar una solución apropiada a este problema así como llevar a cabo los cambios que puede acarrear. Además, se aprovechará para introducir una nueva funcionalidad que será de gran utilidad para el posterior reconocimiento de acciones. Anteriormente se explicó como se estructuraba internamente PPM. Además también se indicaba que este formato no utilizaba ningún tipo de comprensión. Este detalle es muy importante, ya que debido a la resolución de imagen con la que se está trabajando, se generarán ficheros realmente pesados. Para ser más concretos, tras realizar diversas pruebas se ha establecido que los ficheros resultantes se encuentran con un tamaño que oscila aproximadamente entre tres y cuatro megabytes. Para ser más conscientes del impacto que puede conllevar este tamaño de fichero, se han realizado diversas pruebas para comprobar el comportamiento real que presenta el módulo con este formato de imagen. A continuación se muestra una tabla con los resultados más relevantes (ver Cuadro 6.2). En vista de los resultados obtenidos, este consumo es totalmente insostenible a largo plazo ya que mover tal cantidad de ficheros con este tamaño sería terriblemente lento además de las 129 Tiempo (minutos) No ficheros Tamaño total (MB) 0,5 1 3 5 10 1300 2694 8673 12461 26643 4680 9429 32090.1 48587.9 102309.3 Cuadro 6.2: Resultados obtenidos con ficheros PPM. grandes cantidades de espacio de almacenamiento que requeriría. La solución al problema pasa por emplear un formato de imagen más eficiente y que permita conservar la sencillez y versatilidad que ofrecía PPM. Tras realizar un pequeño estudio de las diferentes posibilidades existentes, se ha llegado a la conclusión de que el formato de imagen más conveniente para el módulo de captura de imágenes es JPEG. JPEG, además de ser un formato de archivo, es un método de comprensión que utiliza habitualmente un algoritmo de compresión con pérdida para reducir el tamaño de los archivos de imágenes. Esto quiere decir que al descomprimir o visualizar la imagen, no se obtiene exactamente la misma imagen de la que se partía antes de la compresión. No obstante, existen también tres variantes del estándar JPEG que comprimen la imagen sin pérdida de datos como pueden ser JPEG2000, JPEG-LS y Lossless JPEG. Tras realizar diferentes pruebas para encontrar el equilibrio perfecto entre calidad y tamaño, se pudo comprobar que para los objetivos del proyecto bastaba con emplear JPEG y no sus variantes. De esta forma, se asume que la pérdida de calidad en la imagen que supone la utilización de esta técnica de comprensión no resultará ningún problema para la etapa de reconocimiento de acciones. Una vez que el nuevo formato a utilizar estaba claro, llega el momento de integrarlo en el módulo. Para acometer esta tarea se han empleado las funcionalidades ofrecidas por OpenCV, biblioteca libre enfocada en la visión artificial. La decisión de emplear OpenCV estaba basada en que proporcionaba un entorno de desarrollo fácil de utilizar y altamente eficiente, además de la interoperabilidad que ofrece al tratarse de una distribución multiplataforma disponible para GNU/Linux, Mac OS X y Windows. Una vez que esta nueva funcionalidad ya ha sido integrada en el módulo, se han vuelto a realizar las mismas pruebas de rendimiento que se realizaron con los ficheros PPM observando que la mejora en el consumo de memoria e incluso en el rendimiento que presenta el módulo durante su ejecución ha sido realmente impactante. A continuación se muestra una tabla con los resultados más relevantes (ver Cuadro 6.3). En Figura 6.32 y Figura 6.33 se muestran unas gráficas comparativas de las estimaciones realizadas para el número de ficheros y tamaño en Megabytes respectivamente según el tipo de formato. 130 Tiempo (minutos) No ficheros Tamaño total (MB) 0,5 1 3 5 10 1594 3190 9564 15944 31882 68 159 443.4 709.5 1434.7 Cuadro 6.3: Resultados obtenidos con ficheros JPEG. Figura 6.32: Gráfico comparativo del no de ficheros entre el formato PPM y JPEG. No obstante, al introducir esta mejora es necesario realizar más cambios en el módulo. Hasta este momento todos los metadatos generados para cada frame eran almacenados como un comentario en el interior del fichero PPM correspondiente al frame. Sin embargo, con JPEG esta opción no es una alternativa viable. Por lo tanto se han tenido que plantear diferentes soluciones que permitieran almacenar la imagen y su correspondiente metainformación de una manera eficiente y sencilla de procesar posteriormente. Las alternativas mas viables son las siguientes: Generación de un contenedor multimedia en el que se almacenará en forma de vídeo los diferentes frames junto su correspondiente metainformación. Generación de dos ficheros por cada frame de profundidad: • Fichero JPEG correspondiente al frame. • Fichero XML que contenga la metainformación correspondiente al frame. Aunque la primera opción resulta realmente atractiva ya que tan sólo sería necesario ge131 Figura 6.33: Gráfico comparativo del tamaño total en megabytes entre el formato PPM y JPEG. nerar un solo fichero de vídeo para cada flujo de información, en las etapas siguientes del proyecto se comprobará que esta no es la mejor solución ya que será necesario trabajar a nivel de fichero de imagen por cada frame capturado. Por lo tanto, se ha decidido integrar la funcionalidad al módulo de almacenar esta metainformación a través de ficheros XML. Para llevar a cabo esta tarea, el primer paso que ha sido necesario acometer es decidir qué librería es la mas interesante para perder el mínimo de eficiencia posible. De este modo, se ha realizado un análisis de las principales alternativas existentes para el lenguaje de programación que está siendo empleado para el desarrollo de este módulo (C++). A continuación se presenta un breve resumen de las librerías más interesantes así como sus principales características: Xerces6 : Ofrece una gran cantidad de funcionalidades (especialmente cuando es combinada con Xalan), pero por el contrario es muy pesada y fuerza al programador a la gestión de memoria. RapidXML7 : Excelente para realizar tareas de análisis in situ, pero no es una opción eficiente en la generación de ficheros XML. Boost XML8 : Herramienta potente y excelente sintaxis de C++. Sin embargo, el soporte y documentación acerca de la librería es insuficiente. 6 http://xerces.apache.org/ http://rapidxml.sourceforge.net/ 8 http://svn.boost.org/svn/boost/trunk/boost/ 7 132 Libxml9 : Buena herramienta para la generación, pero es demasiado pesada si tan solo se requieren realizar tareas de generación de ficheros XML. XiMOL10 : Herramienta fácil de emplear, aunque para realizar ciertas funciones puede resultar demasiado simple. TinyXML11 : Herramienta de licencia libre, ligera, simple e independiente del sistema operativo. Tras este análisis, se ha decidido emplear la librería TinyXML debido a que es la solución que presenta un mayor equilibrio entre sencillez, tamaño y versatilidad. Una vez que se ha decidido que TinyXML es la solución más apropiada para integrar la funcionalidad de generación de ficheros XML en el módulo de captura de imágenes, es el momento de diseñar la estructura más conveniente de estos ficheros. En el Listado 6.5 se muestra cuál ha sido la estructura elegida, intentando en todo momento generar ficheros que sean fáciles de manejar e interpretar. Para finalizar esta iteración, y cómo ya se anticipaba antes, se ha aprovechado para introducir una nueva funcionalidad al módulo. Esta funcionalidad consiste en ofrecer la posibilidad de generar ficheros de imagen en la cual sólo se represente el esqueleto correspondiente a los usuarios que aparecen en la escena (ver Figura 6.34). Para ello, se ha hecho uso de las funciones ofrecidas por la librería OpenCV y la metainformación proporcionada por el middleware NiTE acerca de la posición aproximada de las articulaciones de los usuarios detectados. De esta forma, fue necesario incluir algún método al modelo de clases así como rediseñar la forma en la que se construía la estructura de directorios. En el Anexo § B se muestran las versiones definitivas de ambos diseños. 6.4 Iteración 4: Módulo de reconocimiento de acciones En esta sección se expone cómo se ha llevado a cabo el diseño e implementación del módulo de reconocimiento de acciones. Para ello se ha dividido en dos subsecciones que se distribuyen de la siguiente manera: La primera describe el modelo conceptual que se ha seguido así como sus principales características. Es muy importante mencionar que se ha empleado el trabajo desarrollado por Jesús Martínez Del Rincón, Jean-Christophe Nebel y María Jesús Santofimia Romero12 , por lo que no ha sido necesario llevar el desarrollo desde cero sino adaptarlo a la solución requerida. En la segunda se expone el proceso que se ha seguido para la correcta implementación del mismo. A lo largo de esta subsección se detallaran las diferentes fases y etapas en las que se 9 http://xmlsoft.org/ http://ximol.sourceforge.net/ 11 http://www.grinninglizard.com/tinyxml/ 12 Código facilitado en la estancia de María José Santofimia Romero en la Kingston University London en Digital Imaging Research Centre (DIRC) durante el año 2011. 10 133 < frame > < timestamp > XXX </ timestamp > < frame_index > XXX </ frame_index > < users > < user > < id > XXX </ id > < isNew > XXX </ isNew > < isVisible > XXX </ isVisible > < isLost > XXX </ isLost > < skeleton_state > XXX </ skeleton_state > < joints > < joint_head > < position > < positionx > XXX </ positionx > < positiony > XXX </ positiony > < positionz > XXX </ positionz > < po s i t io n _ co n f id e n ce > XXX </ p os i t i on _ c on f i de n c e > </ position > < orientation > < orientationx > XXX </ orientationx > < orientationy > XXX </ orientationy > < orientationz > XXX </ orientationz > < orientationw > XXX </ orientationw > < o r i e n t a t i o n _ c o n f i d e n c e > XXX </ o r i e n t a t i o n _ c o n f i d e n c e > </ orientation > </ joint_head > ... </ joints > </ user > < user > ... </ user > </ users > </ frame > Listado 6.5: Estructura fichero XML. ha dividido el módulo acompañado de diversas comparativas, descripción de las herramientas utilizadas además de numerosos diagramas que facilitarán su completa comprensión. Finalmente se describe con un alto nivel de detalle los aspectos más relevantes de la solución generada así como el funcionamiento interno de los diversos submódulos de los que está compuesto. 6.4.1 Modelo Bag of Words Entre las diferentes técnicas de aprendizaje que pueden ser aplicadas para realizar la tarea de reconocimiento de acciones humanas [WBR07] [YKS08], el framework Bag of Words (B OW) [Joa98a] [CDF+ 04] es particularmente adecuado para el desarrollo del módulo de reconocimiento de acciones del presente proyecto. Se ha demostrado que B OW [KB10] [LAS08] [LP07] es uno de los métodos más precisos para el reconocimiento de acciones, 134 Figura 6.34: Funcionalidad introducida en el módulo (versión 4). capaz de actuar en una gran variedad de escenarios con un coste computacional realmente bajo. Al contrario de otras técnicas de clasificación, B OW no requiere ningún algoritmo adicional de segmentación, lo cuál simplifica la tarea de visión por computador haciendo, por lo tanto, posible trabajar directamente con datos de vídeo. Como consecuencia, la metodología de B OW ha sido elegida cómo base del presente módulo de visión por computador para el reconocimiento de acciones. Es importante destacar que el modelo B OW surgió como una aproximación motivada en métodos de categorización de texto [Joa98b] [TK02] [LSST+ 02] [CSTL02]. Sin embargo, la idea de adaptar la categorización de texto a la categorización de vídeo no es algo nuevo. Un ejemplo de ello es [ZRZ02] dónde se investigó la cuantificación y caracterización de vectores de pequeñas ventanas cuadradas en imágenes llamadas keyblocks. En este estudio demostraron que estas características producían más resultados orientados a la semántica que las aproximaciones basadas en el color y la textura cuando realizaban la combinación con histogramas y modelos análogos de la categorización de texto. No obstante, a diferencia del enfoque que se propone a continuación, los keyblocks que generaban no poseían propiedades de invarianza. En los siguientes párrafos se describe la aproximación basada en estás técnicas que ha sido llevada para la implementación del módulo de reconocimiento de acciones. Para ello se hará uso de unos simples gráficos que ayudarán a facilitar la comprensión del modelo propuesto. En la Figura 6.35 se muestra el estado inicial del ejemplo. 135 Figura 6.35: Imágenes originales. Extraídas de “Bag-of-words models” (S. Lazebnik, A. Torralba, L. Fei-Fei, D. Lowe, C. Szurka) y adaptadas por Rubén Cantarero Navarro. En la categorización de vídeo, de manera similar a la mayoría de las técnicas de aprendizaje, B OW confía en la etapa de entrenamiento para aprender a discriminar características de una secuencia de vídeo y en la etapa de clasificación que permitirá llevar a cabo el proceso de reconocimiento. De esta forma, la etapa de entrenamiento que se presenta en este proyecto consiste en tres pasos bien diferenciados: Creación de un codebook de descriptores de características, generación de un descriptor por cada vídeo que representa una acción disponible en el dataset de entrenamiento y finalmente entrenar el clasificador con los descriptores de los vídeos que hayan sido obtenidos. De esta forma, el flujo de trabajo comenzará con la extracción de las características en cada vídeo previamente etiquetado perteneciente al dataset de entrenamiento (ver Figura 6.36). Figura 6.36: Extracción de características. Extraídas de “Bag-of-words models” (S. Lazebnik, A. Torralba, L. Fei-Fei, D. Lowe, C. Szurka) y adaptadas por Rubén Cantarero Navarro. Una vez que los las características hayan sido extraídas de los vídeos, se lleva a cabo un proceso de clustering [KMN+ 02] para agrupar y cuantificar los descriptores obtenidos y así generar un diccionario (codebook) que proporcionará el vocabulario mediante el cual los datos serán descritos (ver Figura 6.37). Finalmente, cada vídeo del dataset de entrenamiento es descrito en términos de las nuevas “palabras” del diccionario generado y que posteriormente será empleado para realizar el proceso de entrenamiento de un clasificador lineal Support Vector Machines (SVM). De esta forma, el clasificador SVM aprenderá por cada acción defi136 nida el hiperplano óptimo que permita obtener la mejor separación entre los diferentes tipos de acciones. Figura 6.37: Generación del diccionario (clustering). Extraídas de “Bag-of-words models” (S. Lazebnik, A. Torralba, L. Fei-Fei, D. Lowe, C. Szurka) y adaptadas por Rubén Cantarero Navarro. Durante la etapa de clasificación propuesta, las acciones realizadas en los vídeos a analizar serán reconocidas mediante la aplicación de un procedimiento similar al empleado en la etapa de entrenamiento. Mediante la aplicación de una técnica de extracción de características que será descrita en los siguientes apartados se obtendrán los conjuntos de característicos más significativos de cada secuencia de vídeo. Posteriormente, estas características serán cuantificadas usando el diccionario (codebook) para generar los descriptores que caracterizan a cada secuencia de vídeo (ver Figura 6.38). Finalmente, estos descriptores serán entregados al clasificador SVM con el fin último de cuantificar la similitud entre cada nueva secuencia de vídeo y cada tipo de acción para las que haya sido entrenado (ver Figura 6.39). Como resultado se obtendrá una lista de etiquetas que describirán el la acción que se está realizando en el vídeo. 137 Figura 6.38: Cuantificación de características. Extraídas de “Bag-of-words models” (S. Lazebnik, A. Torralba, L. Fei-Fei, D. Lowe, C. Szurka) y adaptadas por Rubén Cantarero Navarro. Figura 6.39: Clasificador SVM. Extraídas de “Bag-of-words models” (S. Lazebnik, A. Torralba, L. Fei-Fei, D. Lowe, C. Szurka) y adaptadas por Rubén Cantarero Navarro. 6.4.2 Implementación de la solución propuesta Una vez que los conceptos clave del modelo B OW para el reconocimiento de acciones expuesto en el apartado anterior ha sido entendido, es el momento de llevar a cabo su implementación. Para ello se han empleado diferentes herramientas como “FFmpeg”, “stipdept”, “Ann”, “bsvm”, etc que serán descritas en las siguientes subsecciones a lo largo de cada fase del proceso en el que son empleadas. No obstante, es importante destacar que para conectar cada una de estas fases y llevar a cabo todo el procedimiento se ha empleado Practical Extraction and Report Language (PERL). PERL es un lenguaje de propósito general que toma características del lenguaje C, del lenguaje interpretado bourne shell (sh), AWK, sed, Lisp y, en un grado inferior, de muchos otros lenguajes de programación. Originalmente fue desarrollado para la manipulación de texto y que hoy en día también es ampliamente utilizado para realizar una gran variedad de tareas incluyendo administración de sistemas, desarrollo web, programación en red, desarrollo de GUI, etc. Entre sus principales, características las más destacadas son que es fácil de usar, soporta tanto la programación estructurada como la programación orientada a objetos y la programación funcional, tiene incorporado un poderoso sistema de procesamiento de texto y una enorme colección de módulos disponibles. A continuación se exponen algunas de las 138 ventajas más destacadas que se han deducido tras realizar un breve análisis sobre PERL: Reduce el ciclo de programación: No es necesario compilar la aplicación, PERL es interpretado y por ello, los programas pueden ser ejecutados en muchas plataformas sin necesidad de ser recompilado. Es portable: Hay un interpretador de PERL para cada variedad de Unix y Windows, por lo que los cambios que deben ser realizados a una aplicación escrita en este lenguaje son mínimos o nulos. Potencia y sencillez: Permite realizar muchas tareas que serían más complejas en otros lenguajes como C o Shell, como por ejemplo la manipulación de archivos de texto. La sintaxis: La sintaxis de otros lenguajes como Shell, Sed, AWK o C es muy similar a la de PERL. Inclusive cuenta con herramientas para traducir código de Sed y AWK a PERL de manera automática. Extensible: Hay una gran variedad de módulos disponibles que pueden ser incluidos en las aplicaciones de manera muy sencilla, dando además la posibilidad de desarrollar módulos propios. Gratuito. Como se puede apreciar, las ventajas que ofrece PERL son numerosas. No obstante, una de las más importantes y que ha sido decisiva en la decisión de emplear PERL y no otro lenguaje es su gran destreza en el procesado de texto y manipulación de archivos además de su portabilidad. En los siguientes apartados se podrá valorar como esta característica será crucial para el desarrollo de los scripts necesarios de una manera cómoda, sencilla y eficiente. Por el contrario, ha sido necesario llevar a cabo un trabajo extra ya que la utilización de este lenguaje conlleva una curva de aprendizaje alta debido a la gran cantidad de funcionalidades que ofrece. Para llevar a cabo la implementación de un sistema basado en el modelo de B OW ha sido necesario analizar y diseñar las diferentes fases de las que está compuesto este procedimiento y que este módulo de reconocimiento de acciones deberá llevar a cabo (ver Figura 6.40). Desde un punto de vista con un nivel de abstracción más elevado se pueden distinguir las siguientes: Configuración inicial: Preparación del entorno para llevar a cabo las tareas necesarias. Segmentación de vídeos: Tratamiento de los vídeos para su posterior procesamiento. Extracción de características: Obtención de los descriptores que caracterizan a una secuencia de vídeo. Clustering: Realización del proceso de clustering con los descriptores obtenidos. 139 Proceso de reconocimiento/clasificación: Fase de clasificación de las acciones a partir de un clasificador Support Vector Machines (SVM). Figura 6.40: Diagrama de flujo de la solución propuesta. No obstante, cada una de estas fases del módulo de reconocimiento de acciones así como la subtareas de más bajo nivel en las que se subdividen serán descritas en las siguientes subsecciones con todo nivel de detalle. Un concepto importante que debe ser entendido son las etapas o modalidades en las que se divide el proceso necesario para llevar a cabo el reconocimiento y clasificación de acciones. De esta forma se pueden distinguir dos etapas que estarán compuestas por algunas de las diferentes fases descritas anteriormente. Por lo tanto, este módulo de reconocimiento de acciones deberá dar soporte a ambas modalidades permitiendo realizar las fases correspondientes en función de la etapa que se este llevando a cabo. La etapa inicial, también conocida como etapa de “training”, es la encargada de entrenar al sistema para el posterior reconocimiento y clasificación de acciones que será llevado a cabo en la siguiente etapa. Por lo tanto, esta etapa de entrenamiento deberá ser realizada tan 140 solo una vez para obtener los elementos que serán requeridos en la realización de la segunda etapa. Para ello generará los siguientes elementos a partir de un dataset de entrenamiento: Clusters: Asocia el resultado entre los descriptores de los vídeos de entrenamiento y los clusters que son formados, generando de esta forma el diccionario o codebook. Posteriormente, en la siguiente etapa estos clusters serán empleados para medir la distancia con los clusters obtenidos de los descriptores generados mediante los vídeos de prueba. Modelo: Este modelo será empleado en la segunda etapa por el clasificador SVM. De esta forma, el modelo generado permitirá al clasificador desempeñar su tarea a partir del cual distinguirá a qué tipo de acción se corresponde en función de este modelo los datos que le son pasados. La segunda etapa, también conocida como etapa de “testing”, será realizada tantas veces como conjuntos de vídeos se desee procesar y clasificar. Para ello, hará uso de los elementos obtenidos en la etapa de entrenamiento que servirán como base para tomar las decisiones necesarias en las fases de clustering y clasificación de la segunda etapa. Aunque ambas etapas serán desgranadas en mayor profundidad en las siguientes subsecciones a través de la explicación de las diferentes fases de las que se componen, este concepto de training y testing es clave para comprender el proceso necesario para la realización de la clasificación de acciones basado en el modelo de B OW descrito anteriormente. En la Figura 6.41 se presenta una visión general del orden y los pasos requeridos en este proceso. Como se puede apreciar, ambas etapas se encuentran bien diferenciadas. Aunque las fases que deben llevarse a cabo son similares, los resultados y finalidad de alguna de ellas difieren un poco. A continuación se presenta a modo de resumen las principales diferencias entre ambas etapas para facilitar la comprensión de este proceso: Datos de entrada: En la etapa de training se emplea un dataset de entrenamiento mientras que en la etapa de testing se emplea el conjunto de vídeos que se desea clasificar. Número de veces que se realiza: La etapa de training se realiza una vez para entrenar al sistema a través de la generación de los elementos de clustering y el modelo del clasificador SVM, mientras que la etapa de testing se realiza tantas veces como conjuntos de vídeos se desee clasificar. Fase de clustering (Fase 4): En la etapa de training se obtiene un conjunto de clusters a partir de los descriptores de los vídeos del dataset de entrenamiento obtenidos en la fase de extracción de características, mientras que en la etapa de testing se emplea estos clusters obtenidos en la etapa de training para procesar los descriptores de los vídeos que se desean clasificar obtenidos en la fase de extracción de características. 141 Fase de reconocimiento (Fase 5): En la etapa de training se obtiene un modelo para el clasificador SVM de las acciones definidas para ser clasificadas, mientras que en la etapa de testing se usa en el clasificador SVM el modelo obtenido en la etapa de training para clasificar en función de las acciones previamente definidas. Figura 6.41: Diagrama de flujo de según las etapas. Una vez que se han presentado brevemente las diferentes fases a las que este módulo de reconocimiento de imágenes debe dar soporte así como las dos etapas necesarias para llevar a cabo el proceso de clasificación, es el momento de definir las acciones que se desean de identificar. Para ello, se ha empleado las acciones definidas por el dataset INRIA Xmas Motion Acquisition Sequences (IXMAS)13 . IXMAS es un dataset público desarrollado por Institut National de Recherche en Informatique et en Automatique (INRIA) y que será empleado posteriormente para llevar a cabo la etapa de training. No obstante, este dataset será explicado con mayor detalle así como el proceso seguido para el entrenamiento en el capítulo de resultados (véase § 7). A continuación se describen las quince acciones de la vida cotidiana definidas por IXMAS así como su correspondiente identificador que será empleado más adelante en el proceso de etiquetado: (0) Nada: No se está realizando ninguna acción. El usuario está parado. (1) Mirar reloj: El usuario realiza la acción de mirar el reloj de su muñeca. (2) Cruzarse de brazos: El usuario realiza la acción de cruzarse de brazos. (3) Rascarse la cabeza: El usuario realiza la acción de rascarse la cabeza. (4) Sentarse: El usuario realiza la acción de sentarse en el suelo. 13 http://4drepository.inrialpes.fr/public/viewgroup/6 142 (5) Levantarse: El usuario realiza la acción de levantarse. (6) Darse la vuelta: El usuario realiza la acción de darse la vuelta sobre sí mismo. (7) Caminar: El usuario realiza la acción de caminar. (8) Saludar: El usuario realiza la acción de saludar con su mano. (9) Dar puñetazo: El usuario realiza la acción de dar puñetazos. (10) Dar patada: El usuario realiza la acción de dar patadas. (11) Señalar: El usuario realiza la acción de señalar con el dedo. (12) Coger: El usuario realiza la acción de coger algo del suelo, una mesa, etc. (13) Lanzar: El usuario realiza la acción de lanzar algo sobre su cabeza. (14) Lanzar: El usuario realiza la acción de lanzar algo de abajo hacia arriba. Con todos los conceptos analizados y entendidos, tan solo queda un tarea antes de comenzar a desarrollar cada una de las fases que componen las etapas de training y testing anteriormente descritas: Definir la estructura interna del módulo de reconocimiento de acciones. Para ello se ha decidido implementar diferentes submódulos o scripts que serán los encargados de realizar las tareas especificas de cada fase. De este modo, habrá un programa principal (“run_all”) encargado de gestionar y ejecutar cada uno de los submódulos desarrollados mediante PERL. A continuación se muestra una lista de estos submódulos según la fase a la que pertenecen y que en los siguientes apartados serán explicados (ver Figura 6.42): Fase de segmentación de vídeos: build_segmented_videos. Fase de extracción de características: avi2stip, stip2featuredescriptors y stip2hof. Fase de clustering: new_sequence_cluster_choice_k. Fase de reconocimiento/clasificación: all_rcg_same_file, norm_hist_smallut2libsvm, norm_hist_biglut2libsvm y recognition_from_cluster_all. El principal motivo por el que se ha seguido este diseño es tener todas las fases y sus tareas correspondientes bien compartimentadas, facilitando de este modo su comprensión, manipulación y depuración. Además, gracias a este diseño se pueden definir cuáles son las entradas y salidas de cada submódulo o tarea, ofreciendo por lo tanto la capacidad de remplazar un módulo concreto por otro cuyas entradas y salidas sean las mismas. Este hecho ha sido realmente útil a lo largo del proyecto ya que permite depurar la solución propuesta así como solucionar los errores que se han ido identificado. 6.4.2.1. Fase 1: Configuración inicial Esta fase será idéntica tanto para la etapa de training como para la etapa de testing. Aunque esta fase no es parte del modelo de B OW, sino una fase específica del sistema a desarrollar, su 143 Figura 6.42: Módulos del sistema. realización es crucial ya que su principal objetivo es el de preparar todo el entorno del sistema para llevar a cabo las siguientes fases. Para ello se limpian los directorios correspondientes borrando los archivos generados de anteriores ejecuciones y creando a su vez los directorios correspondientes para la nueva ejecución, dejando así un estado consistente para obtener un correcto funcionamiento. En la Figura 6.43 se representa cómo es la estructura interna de directorios en el que trabajará el sistema. Como se puede apreciar, se ha intentado mantener una estructura similar a las diferentes fases de las que se compone el proceso de reconocimiento/clasificación de vídeos. Esta decisión de diseño ha sido de vital importancia ya que el sistema procesará y generará una gran cantidad de archivos a lo largo del proceso y por lo tanto mantener todo organizado será crucial para obtener un código claro y comprensible en los diferentes submódulos. 6.4.2.2. Fase 2: Segmentación de vídeos Esta fase será idéntica tanto para la etapa de training como para la etapa de testing. Para desempeñar esta fase se ha desarrollado un programa en PERL (buil_segmented_videos) que será ejecutado por el programa principal tantas veces como ficheros de texto haya disponibles en el directorio /videos/truth. Estos ficheros tendrán un nombre con una estructura concreta, ACTOR_frame_segmented.txt, dónde “ACTOR” será el nombre del vídeo. La estructura interna de estos ficheros también se encuentra predefinida: Cada línea estará compuesta por el número del frame donde comienza la acción, un espacio en blanco, el número de frame donde finaliza la acción, un espacio en blanco y el identificador de la acción que se está lle144 Figura 6.43: Estructura de directorios de la solución propuesta. vando a cabo (véase § 7.1). En el Listado 6.6 se muestra un pequeño ejemplo para facilitar su comprensión: Frames del 0 al 220: El usuario no esta realizando ninguna acción. Frames del 220 al 271: El usuario se encuentra caminando. Frames del 271 al 310: El usuario ha cogido algún objeto. Frames del 310 al 327: El usuario está caminando 1 2 3 4 0 220 0 220 271 7 271 310 12 310 327 7 Listado 6.6: Estructura fichero ACTOR_frame_segmented.txt. La finalidad del programa build_segmented_videos es segmentar los vídeos que contienen una secuencia de acciones (se encuentran en el directorio /videos) para los cuáles hay un fichero en el directorio /videos/truth en vídeos más pequeños correspondientes a una única 145 acción. Para indicar cómo deben ser descompuestos estos vídeos se hace uso del fichero correspondiente donde se indican los frames de inicio y fin de la acción. Para realizar esta tarea será necesario en primer lugar descomponer cada vídeo a segmentar en frames, los cuales serán almacenados temporalmente en el directorio /videos/segmented_videos/images/ con un nombre significativo que permita posteriormente ser procesadas por un procesador de vídeo. Como la tasa de frames por segundo es conocida (en el caso de Kinect es de 30 frames/segundo), se obtendrán treinta imágenes por cada segundo de vídeo. Finalmente, el fichero de vídeo resultante tras unir estos frames en vídeos será almacenado en el directorio /videos/segmented_videos/ACTOR/ACTOR_indice_identificadorDeAcción.avi. En la Figura 6.44 se muestra un diagrama de fujo dónde se muestra el proceso llevado a cabo por este programa. Figura 6.44: Diagrama de flujo de build_segmented_videos. Continuando con el ejemplo anterior, el proceso que se seguiría para descomponer un vídeo llamado pepe.avi con su correspondiente fichero pepe_frame_segmented.txt (ver Listado 6.6) sería el siguiente: 146 Paso 1: Se crea un directorio llamado pepe en /videos/segmented_videos/. Paso 2: Se crea un directorio llamado images en /videos/segmented_videos/. Paso 3: Se fragmenta el vídeo /videos/pepe.avi en frames que serán almacenados en /videos/segmented_videos/images/. Paso 4: Se crea un vídeo en el que el usuario no hace nada llamado pepe_000_0.avi en /videos/segmented_videos/pepe/ a partir de los frames correspondientes almacenados en /videos/segmented_videos/images/. Paso 5: Se crea un vídeo en el que el usuario está andando llamado pepe_001_7.avi en /videos/segmented_videos/pepe/ a partir de los frames correspondientes almacenados en /videos/segmented_videos/images/. Paso 6: Se crea un vídeo en el que el usuario ha cogido algún objeto llamado pepe_002_12.avi en /videos/segmented_videos/pepe/ a partir de los frames correspondientes almacenados en /videos/segmented_videos/images/. Paso 7: Se crea un vídeo en el que el usuario está andando llamado pepe_003_7.avi en /videos/segmented_videos/pepe/ a partir de los frames correspondientes almacenados en /videos/segmented_videos/images/. Paso 8: Se elimina el directorio /videos/segmented_videos/images/. Como se puede apreciar, para descomponer cada vídeo con las secuencias de acciones en vídeos con una sola acción es necesario descomponerlo antes en frames que serán almacenadas en imágenes. No obstante, llegados a este punto del proyecto y como ya se anticipaba anteriormente (véase § 6.3.2.3) se ideó una forma para que este proceso no fuera necesario llevarlo a cabo y así tener una menor carga computacional en el módulo de reconocimiento de acciones. La solución consiste en almacenar los flujos de información capturados por los sensores de Kinect directamente en imágenes por cada frame. Una vez incorporada esta modificación en el módulo de captura de imágenes, ya no será necesario este preprocesado de los vídeos. Finalmente, tan solo destacar que el procesador de vídeo empleado para realizar todas estas tareas de segmentación de vídeos es FFmpeg14 . FFmpeg es un proyecto de software libre muy popular para el tratamiento de datos multimedia que es utilizado en importantes proyectos como son VLC, MPlayer, HandBrake, Blender, Google Chrome y muchos más. Concretamente el componente que ha sido empleado es ffmpeg, una potente herramienta de línea de comandos que permite realizar conversiones entre formatos de vídeo y audio. 6.4.2.3. Procesamiento Una vez que se ha preparado el entorno del sistema y se han dividido las secuencias de vídeo a analizar en vídeos de una sola acción, ya está todo preparado para llevar a cabo el 14 http://www.ffmpeg.org/index.html 147 procesamiento de los mismos siguiendo el modelo B OW expuesto al comienzo de la sección (véase § 6.4.1). Al contrario de lo que ocurría con las fases de configuración y segmentación, en las siguientes fases ya se introducen pequeñas diferencias en función de la etapa del procesamiento en la que se encuentre el sistema: training o testing. No obstante, a lo largo de la descripción de cada fase se describirá en detalle cuáles son esas diferencias y su finalidad. Llegado este punto, el programa principal (run_all) se encargará de ejecutar las siguientes fases para cada uno de los vídeos originales una vez que se hayan generado los vídeos segmentados en la fase anterior. En la Figura 6.45 se representa a muy alto nivel cómo serán las fases del procesamiento así como las entradas y salidas de cada una en función de la etapa en la que se encuentre el sistema, donde ya se pueden apreciar las principales diferencias que caracterizarán a cada etapa. Figura 6.45: Fases de procesamiento. 6.4.2.3.1. Fase 3: Extracción de características Antes de comenzar con la implementación de esta fase ha sido necesario llevar a cabo un primer paso para realizar una exhaustiva investigación y completo análisis sobre las técnicas existentes para extraer las características más significativas de una secuencia de vídeo y así poder decidir cuál es la más apropiada para el sistema que se está desarrollado. En los siguientes párrafos se exponen las conclusiones más importantes que se han extraído de este análisis y el proceso llevado a cabo para aplicar la técnica escogida. De este modo, el primer paso descrito por el modelo de B OW quedará implementado. Cómo ya se comentaba en el capítulo de antecedentes (véase § 4.2), el análisis e interpretación de vídeo es un tema en continúa evolución y crecimiento en el campo de visión por computador. Los enfoques tradicionales para el análisis de movimiento en secuencias de vídeo implican principalmente el cálculo del flujo óptico [BFB94] o el seguimiento de características [SB95] [IB98]. Aunque son efectivas para muchas tareas, ambas técnicas tienen limitaciones. Las aproximaciones basadas en el flujo óptico capturan el primer orden de movimiento y por lo tanto a menudo fallan cuando se producen movimientos repentinos. La soluciones basadas en el seguimiento de características generalmente asumen una apa148 riencia constante en la imagen a lo largo del tiempo y por lo tanto se producen importantes fallos cuando esta apariencia constante cambia, como por ejemplo en situaciones en la que dos objetos de la imagen se unen o dividen. De forma contraría a lo que exponen las anteriores técnicas, la mayoría de los eventos de interés que se producen en una secuencia de vídeo están caracterizados por importantes variaciones en los datos de las dimensiones tanto espacial como temporal. Ejemplos de ello podrían ser escenas en las que una persona entra a una habitación, una persona se sienta, etc. En el domino espacio-temporal, el cálculo de puntos con variaciones significativas en las intensidades de una imagen han sido extensamente investigadas en el pasado [FG87] [HS88] [SMB00]. Este tipo de puntos son comúnmente denominados como “puntos de interés”, los cuales constituyen importantes fuentes de información debido a la gran cantidad de información que proporcionan para el análisis de vídeo. Como muestra de las posibilidades que ofrecen este tipo de puntos de interés y el importante éxito que han tenido, se han desarrollado una gran variedad de aplicaciones: indexado de imágenes [SM97], estimación del flujo óptico y seguimiento [SB95] y reconocimiento [Low99] [HVC00]. Siguiendo este razonamiento, la aproximación que se ha decidido seguir para extraer las características de las secuencias de vídeo a analizar ha sido la extracción de puntos de interés espacio-temporales, también conocida cómo Space-time Interest Points (STIP). Esta aproximación fue presentada por Ivan Laptev en 2005 [Lap05] basándose en la idea de puntos de interés desarrollada por Harris y Stephens en 1988 (conocido como algoritmo Harris3D [SB11]). Con esta técnica es posible detectar estructuras espacio-temporales donde los valores de las imágenes de una secuencia de vídeo representan variaciones significativas en la dimensión espacio-temporal. Estos puntos resultan especialmente interesantes ya que se centran en unos pocos puntos específicos de las imágenes que componen un vídeo. De esta forma, mediante la integración de la componente del tiempo es posible llevar a cabo un filtrado de los puntos de interés obtenidos y mantener tan solo aquellos que tienen una discontinuidad temporal. Por lo tanto, los puntos de interés de una imagen estarán definidos como píxeles con variaciones máximas de la intensidad en los píxeles vecinos, representando esquinas, intersecciones, puntos asilados y puntos específicos en la textura de la imagen. De esta forma, es posible extrapolar esta definición a los STIPs si se consideran una secuencia de vídeo en vez de una imagen. Consecuentemente, los STIPs pueden ser definidos como píxeles con cambios significativos en el espacio y tiempo, otorgando la posibilidad de representar movimientos irregulares del cuerpo humano como rodillas, hombros, etc. La técnica que se ha empleado en la presente fase del proyecto para generar los STIPs consiste en la búsqueda de puntos que maximicen la variación local de los valores de una imagen sobre las dimensiones espacio-temporal de manera simultanea. De acuerdo con la teoría de 149 Laptev, una secuencia de vídeo podrá ser por tanto representada mediante la función f : R2 xR → R (6.3) sobre dos dimensiones espaciales (x,y) y una dimensión temporal t. De esta manera, las características locales espacio-temporales quedan definidas cómo bloques tridimensionales de secuencias que contienen variaciones en el espacio y el tiempo. Una vez que se ha decidido la técnica que va a ser empleada para la extracción de características de las secuencias de vídeo, es el momento de implementar la solución propuesta. Es importante destacar que esa fase será idéntica para las etapas de training y testing, ya que tanto para el dataset de prueba como para las secuencias de vídeo a clasificar será necesario extraer las características. Para ello se han elaborado tres programas en PERL (avi2stip, stip2featuredescriptors y stip2hof ) que serán ejecutados por el programa principal. En la Figura 6.46 se representa la secuencia que debe ser llevada a acabo para la generación de los descriptores que serán empleados en la siguiente fase (clustering). Figura 6.46: Diagrama de la fase de extracción de características. El programa avi2stip será el encargado de generar los ficheros que contengan los STIP’s. En primer lugar, creará un directorio con el mismo nombre del vídeo original concatenado con la terminación _stip en /extracted_features. El siguiente paso que llevará a cabo será la generación de un fichero STIP para cada segmento del vídeo original que se este proce150 sando mediante el uso de la herramienta stipdept. stipdept es una aplicación desarrollada por Ivan Laptev15 cuya finalidad es calcular los descriptores para cada uno de los puntos de interés espacio-temporal del vídeo que le es pasado como argumento. Este programa permite integrar la técnica elegida en los párrafos anteriores para la extracción de características. El resultado obtenido a través de esta herramienta consiste en dos tipos descriptores, Histograms of Oriented Gradients (HOG) y Histograms of Optical Flow (HOF), calculados mediante cuadros de vídeo tridimensionales para cada STIP detectado. Estos cuadros se encuentran divididos en bloques espacio-temporales de 3x3x2. Los descriptores HOG estarán compuestos por setenta y dos elementos mientras que los descriptores HOF por noventa. Tan solo destacar que los parámetros con los que es ejecutado stipdept serán analizados con mayor detenimiento en el capítulo de resultados (véase § 7). Aunque la herramienta stipdept permite ver de forma muy visual y en tiempo de ejecución los puntos de interés que se van calculando sobre el vídeo (ver Figura 6.47), por motivos de eficiencia esta opción no será utilizada normalmente ya esta visualización supone una carga computacional importante. No obstante fue de gran utilidad en los primeros pasos para afianzar los conceptos de STIP y examinar también su comportamiento. Figura 6.47: Captura de stipdet de una imagen de profundidad capturada con Kinect. Este fichero “.stip” generado para cada fragmento de vídeo mediante esta herramienta será almacenado en el directorio /extracted_features/ACTOR_stip/ con el nombre “nombreVideoSgemnetado.stip”. Posteriormente los programas stip2featuredescriptors y stip2hof serán los encargados de extraer de los ficheros .stip los descriptores HOF que serán utilizados en la fase de clustering. Para ello, simplemente deben desechar la cabecera del fichero .stip y los siguientes setenta y dos elementos que se corresponden con los descriptores HOG. Los resultados obtenidos serán almacenados en un nuevo fichero en el directorio /extracted_fea15 http://www.di.ens.fr/~laptev/index.html 151 tures/ACTOR_fearure_descriptors/ con el nombre nombreVideoSgemnetado.hof. 6.4.2.3.2. Fase 4: Clustering Esta fase se encargará de la realización del proceso de clustering con los descriptores HOF obtenidos en la fase anterior. Para ello se ha implementado un programa en PERL (new_sequence_cluster_choice_k) con ciertas variaciones en función de la etapa, training o testing, en la que se encuentre el sistema. Como ya se adelantaba anteriormente, la principal diferencia entre ambas modalidades reside en el procesamiento que se dan a los descriptores y el resultado que es obtenido. En la fase de clustering correspondiente a la etapa de training se generarán los clusters característicos para cada una de las secuencias de vídeo que representan las diferentes acciones que se pretenden clasificar con el sistema que se está desarrollando. Para ello se emplearán los descriptores resultantes de la fase de extracción de características de los vídeos proporcionados por el dataset de entrenamiento. De esta forma, se está llevando a cabo la tarea del aprendizaje del vocabulario visual que se presentaba en modelo B OW. Como resultado se obtienen los archivos clusters_hof_300.pts (codebook) y biglut.lut. La fase de clustering correspondiente a la etapa de testing se encarga de realizar la asociación entre el conjunto de descriptores obtenidos en la fase anterior a partir de la secuencia de vídeos que se pretende clasificar y los resultados obtenidos en la fase de clustering en la etapa de training. Para ello hará uso del fichero clusters_hof_300.pts obtenido en la fase de clustering de la etapa de training y de una de las herramientas de ANN. ANN 16 es una librería escrita en C++ destinada a ofrecer estructuras de datos y algoritmos para el cálculo de la búsqueda de vecinos próximos en ámbitos que presentan un elevado número de dimensiones. La razón por la que se ha decidido hacer uso del algoritmo de búsqueda aproximada de vecinos próximos se debe principalmente a que la realización del cálculo exacto en dimensiones mayores de ocho se convierte en una tarea realmente compleja y con una alta carga computacional. De esta forma, pocos métodos parecen ser significativamente mejores que el cálculo mediante fuerza bruta de todas las distancias. Sin embargo, se ha mostrado en diversas ocasiones que realizando un cálculo aproximado de los vecinos más próximos es posible lograr tiempos de ejecución significativamente mejores (en el orden de 10 a 100 veces mejor) con errores relativamente pequeños. De esta forma se ha hecho uso de una las aplicaciones distribuidas junto a la librería ANN para realizar este cálculo. A través de la línea de comandos se le indican los diferentes parámetros que se desea que se tengan en cuenta a la hora de realizar el cálculo. A continuación se exponen los que han sido empleados en el presente proyecto: 16 http://www.cs.umd.edu/~mount/ANN/ 152 Dimensiones del espacio: Este valor se encuentra definido por el numero de elementos del descriptor HOF obtenido en la fase de extracción de características. Número máximo de puntos de datos: Valor definido en por el descriptor HOF. Nombre del fichero que contiene los puntos de datos: Fichero “.hof” calculado en la fase de extracción de características en la etapa de testing. Nombre del fichero que contiene los puntos de consulta: Fichero clusters_hof_300.pts obtenido en la fase de extracción de características en la etapa de training. Una vez proporcionados los datos, la aplicación de ANN construirá una estructura de árbol de búsqueda, leerá los puntos de consulta y posteriormente realizará el cálculo aproximado del k vecino más próximo para cada uno con un error . El resultado obtenido consistirá en los índices y las distancias de cada punto de consulta con respecto los puntos de datos. Teniendo claro cuál va a ser la técnica empleada para calcular a qué cluster pertenece cada descriptor y su funcionamiento, es el momento de llevar a cabo su implementación. Para ello el programa new_sequence_cluster_choice_k realizará los siguientes pasos: Paso 1: Obtiene la dimensión de los descriptores a partir de los ficheros .hof generados en la fase anterior. Paso 2: Crea un fichero smallut.lut en el directorio clustering/. Este fichero representa una Look Up Table (LUT) que representa la asociación entre cada descriptor y la acción que representa y que será empleado posteriormente en la fase de clasificación para preprocesar los datos que serán pasados al clasificador SVM. Paso 3: Por cada fichero .hof almacenado en el directorio /extracted_features/ACTOR_feature_descriptors realizará las siguientes operaciones: • Obtiene el número máximo de puntos de datos del descriptor contenido en el fichero .hof que será pasado como parámetro a la herramienta ANN. • Almacena en una LUT local este número máximo y que posteriormente será empleado para normalizar el histograma generado en el siguiente paso. • Almacena en el fichero smallut.lut el número de acción correspondiente al fichero .hof que se está procesando. • Ejecuta ANN con los parámetros descritos en los párrafos anteriores y almacena su resultado en un fichero llamado nombreDelFicheroHOF/nearest_cluster_300.hofpts en el directorio /clustering/nearest_neighbour/. Paso 4: Consiste en la construcción del histograma de clusters para cada secuencia. Para ello por cada fichero .hofpts generado en el paso anterior construirá su histograma correspondiente y lo almacenará temporalmente en una variable local. Paso 5: Consiste en normalizar los histogramas generados en el paso anterior. Para ello se hará uso del número máximo de puntos de datos de cada descriptor almacenado 153 en la variable LUT generado en el Paso 3 y del histograma generado en el Paso 4. Una vez normalizado el histograma, será almacenado en un fichero llamado nombreDelFicheroHOF_histogram_norm_300.hofhist en el directorio /clustering/histograms/. En la Figura 6.48 se muestra un diagrama en el que se representan los diferentes pasos que acaban de ser descritos. De este modo, el paso de la cuantificación de características descrito anteriormente en el modelo B OW queda completado. Figura 6.48: Diagrama de new_sequence_cluster_choice_k 6.4.2.3.3. Fase 5: Proceso de reconocimiento Esta fase se encargará de llevar a cabo el proceso de clasificación de las acciones mediante 154 un clasificador SVM. Al igual que ocurría en la fase anterior, existirán diferencias importantes en función de la etapa en la que se encuentre el sistema. Para la implementación de esta fase se han empleado diferentes programas desarrollados en PERL que se encargarán de llevar a cabo el preprocesamiento de la información obtenida en la fase de clustering para que pueda ser empleada finalmente por el clasificador SVM. En la Figura 6.49 se muestra un diagrama que representa la secuencia de ejecución de los diferentes programas así como las entradas y salidas de cada uno. En los siguientes apartados serán descritos con mayor detalle en función de la etapa en la que sean ejecutados. No obstante, antes de entrar en los detalles de cada etapa y de cómo funcionan internamente estos programas es necesario tener en cuenta algunos conceptos. El primero de ellos es conocer los aspectos más básicos sobre el funcionamiento de un clasificador SVM. Ya que no se va a implementar un clasificador desde cero, sino que se va a emplear una solución ya existente, tan solo será necesario tener una idea básica sobre su funcionamiento. Los algoritmos SVM pertenecen a la familia de los clasificadores lineales. De este modo, dado una colección de puntos (subconjunto de un conjunto mayor) en el que cada uno de ellos pertenece a una de las posibles categorías definidas, un algoritmo basado en la técnica SVM construirá un modelo capaz de predecir si un nuevo punto (cuya categoría a la que pertenece se desconoce a priori) pertenece a una categoría u otra previamente definida en el modelo. Para llevar a cabo este proceso, el algoritmo SVM buscará un hiperplano que permita separar de la manera más óptima los puntos pertenecientes a cada una de las clases o categorías las cuales normalmente pueden haber sido proyectadas a un espacio de dimensionalidad superior. No obstante, es importante destacar que este concepto de separación óptima es donde realmente reside la característica fundamental de los algoritmos SVM: Buscan el hiperplano que posea la máxima distancia o margen con los puntos que se encuentren más cercanos de él mismo. Es por este motivo por el que este tipo de algoritmos también son conocidos como clasificadores de margen máximo. Una vez que se tiene una idea aproximada sobre el funcionamiento de los algoritmos SVM, llega el momento de decidir qué implementación del clasificador SVM va a ser empleado en la solución propuesta. Para ello se hizo un pequeño estudio de la soluciones existentes. Entre las más destacadas y conocidas se encuentran LIBSVM, SVMTorch II, mySVM, Dlib C++ Library y SVMLigth. Sin embargo, debido a su robustez y a la gran cantidad de funcionalidades que ofrece se ha decidido emplear la distribución BSVM desarrollada por Chih-Chung Chang y Chih-Jen Lin [HL02b] [HL02a]. Según su especificación, la implementación actual de BSVM toma prestada la estructura interna de LIBSVM ofreciendo de este modo opciones muy similares. Para solventar algunas de las limitaciones con las que se encuentra LIBSVM en el proceso de clasificación y regresión, BSVM implementa un método interno de descomposición y una selección múltiple de conjuntos de trabajo dando como resultado convergencias más rápidas en los casos más 155 complejos. Esta implementación ofrece dos herramientas, bsvm-train y bsvm-predict17 , que serán empleadas para las etapas de training y testing respectivamente. Aunque los parámetros necesarios para configurar el clasificador serán desarrollados con mayor detalle en los siguientes apartados, es necesario conocer antes el formato en el que deben ser pasados los datos a estas herramientas (ver Listado 6.7). Estos datos son pasados por medio de un fichero compuesto de los siguientes elementos: Label: Es el valor objetivo de los datos de entrenamiento. Para la clasificación debe ser un número entero que identifica una clase, mientras que para la regresión debe ser cualquier numero real. En el archivo de datos de prueba (testing) sólo se utilizan para calcular precisión. Si no se conocen, esta columna debe de ser rellenada con cualquier número. Index: Es un entero que comienza con el valor 1. Sirven para enumerar los elementos value. Value: Es un número real. < label > < index1 >: < value1 > < index2 >: < value2 > ... < label > < index1 >: < value1 > < index2 >: < value2 > ... . . . < label > < index1 >: < value1 > < index2 >: < value2 > ... Listado 6.7: Estructura fichero de datos del clasificador SVM. De esta forma, el fichero empleado en la etapa de training deberá tener tantos tipos de elementos label como clases distintas se quieran identificar, en este caso quince (véase § 6.4.2). Por el contrario, en la etapa de training en principio puede ser cualquier número entero al azar ya que a priori no se conoce a qué clase pertenece el elemento en cuestión. A continuación se muestra un ejemplo para entender mejor como funciona esta codificación: Imagine que se tienen dos puntos (x,y) bidimensionales, (0,3) y (5,8), que pertenecen a clases diferentes (1 y 2 respectivamente) y se desea codificarlos para que pueda ser llevado a cabo el proceso de clasificación. En la Listado 6.8 se presenta como debería ser el fichero correspondiente según la etapa en la que se vaya a emplear: Etapa de training En la etapa de training se generará un modelo a partir de los datos obtenidos en la fase anterior (clustering) y que posteriormente será empleado para llevar a cabo el proceso de 17 http://www.csie.ntu.edu.tw/~cjlin/bsvm/ 156 // Etapa de training 1 1 :0 2 :3 2 1 :5 2 :8 // Etapa de testing < Entero cualquiera > 1 :0 2 :3 < Entero cualquiera > 1 :5 2 :8 Listado 6.8: Ejemplo de la estructura fichero de datos del clasificador SVM. clasificación por el clasificador SVM. Siguiendo el esquema planteado en la Figura 6.49, el primer programa a ejecutar es all_rcg_same_file cuyo propósito para esta etapa no es otro que el de preparar el entorno del sistema para que todo se encuentre en un estado correcto e invocar al siguiente programa en ejecutarse: nom_hist_biglut2libsvm. Este programa tiene como objetivo preprocesar los datos y dotarles del formato pertinente para que posteriormente puedan ser empleados por el clasificador SVM. Para ello, deberá emplear los ficheros generados en la etapa de clustering: biglut.lut (contiene una LUT en la cual asocia cada histograma con su identificador de acción correspondiente) y clustering_hist_norm_hof_300.hist (contiene todos los histogramas normalizados). A continuación se describen los pasos que han sido necesarios para realizar correctamente este tratamiento: Paso 1: Crear fichero learn_hist_norm_hof_300_libsvm en el directorio /recognition_process/. Paso 2: Por cada línea del fichero clustering_hist_norm_hof_300.hist: • Paso 2.1: Dividir la línea leída por elementos (separados por un espacio en blanco). • Paso 2.2: Incluir en el fichero learn_hist_norm_hof_300_libsvm el siguiente número de acción leído del fichero biglut.lut. Este elemento incluido en el fichero representa el <label>. • Paso 2.3: Por cada cada elemento obtenido en el paso 2.1: ◦ Paso 2.3.1: Incluir en el fichero learn_hist_norm_hof_300_libsvm un índice (comienza desde 1) seguido por “:”, el siguiente elemento y un salto de línea. Estos elementos incluidos en el fichero representan el <indexN> y el <valueN>. Por último debe ejecutarse el programa recognition_from_cluster_all. En la etapa de training este programa deberá generar el modelo correspondiente a los datos que le son pasados y que posteriormente será empleado por la etapa de testing. Para ello, simplemente deberá emplear la herramienta bsvm-train incluida en la distribución bsvm. A continuación se indican algunos de los parámetros más importantes para su configuración: Fichero de datos de entrenamiento: Fichero learn_hist_norm_hof_300_libsvm ge157 nerado por el programa nom_hist_biglut2libsvm. Tipo de kernel: Lineal (u0 ∗ v). Coste: Valor empleado descrito en el capítulo de resultados (véase § 7). bsvm-train generará cómo resultado el modelo correspondiente al fichero de datos de entrenamiento en el archivo learn_hist_norm_hof_300_libsvm_model_KERNEL_COST en el directorio /recognition_process/results/. Etapa de testing En esta etapa finalmente se determinará a qué clase pertenece cada uno de los segmentos de vídeo que se generaron al comienzo de todo el proceso en base al modelo obtenido en la etapa de training. Para ello, siguiendo el esquema propuesto en la Figura 6.49, el primer programa a ejecutar es all_rcg_same_file cuyo propósito para esta etapa es producir un archivo que contenga todos los histogramas de los vídeos segmentados generados en la fase de clustering y lanzar el programa nom_hist_smallut2libsvm. Este archivo se ubicará en el directorio /recognition_process/ con el nombre learn_hist_norm_hof_300t. De manera similar a nom_hist_biglut2libsvm, el programa nom_hist_smallut2libsvm tiene como objetivo preprocesar los datos y dotarles del formato pertinente para que posteriormente puedan ser empleados por el clasificador SVM. Para ello, deberá emplear el fichero generado en la etapa de clustering smallut.lut (contiene una LUT en la cual asocia cada histograma con su identificador de acción correspondiente) y el fichero learn_hist_norm_hof_300t (contiene todos los histogramas normalizados) generado por el programa all_rcg_same_file. A continuación se describen los pasos que han sido necesarios para realizar correctamente este tratamiento: Paso 1: Crear fichero learn_hist_norm_hof_300t_libsvm en el directorio /recognition_process/. Paso 2: Por cada línea del fichero learn_hist_norm_hof_300t: • Paso 2.1: Dividir la línea leída por elementos (separados por un espacio en blanco). • Paso 2.2: Incluir en el fichero learn_hist_norm_hof_300t_libsvm el siguiente número de acción leído del fichero smallut.lut. Este elemento incluido en el fichero representa el <label>. Este valor sólo es obligatorio en el caso de que se quiera obtener el grado de precisión en el clasificador. • Paso 2.3: Por cada cada elemento obtenido en el paso 2.1: ◦ Paso 2.3.1: Incluir en el fichero learn_hist_norm_hof_300t_libsvm un índice (comienza desde 1) seguido por “:”, el siguiente elemento y un salto de línea. Estos elementos incluidos en el fichero representan el <indexN> y el <valueN>. 158 El último paso a realizar es llevado a cabo por el programa recognition_from_cluster_all. A diferencia del comportamiento que presentaba en la etapa de training, en esta ocasión debe emplear la herramienta bsvm-predict proporcionada por la distribución BSVM. Para ello se le deben facilitar dos archivos: Fichero de datos: Archivo learn_hist_norm_hof_300t_libsvm generado por el programa nom_hist_smallut2libsvm. Modelo: Archivo learn_hist_norm_hof_300_libsvm_model_KERNEL_COST generado en la etapa de training por el programa recognition_from_cluster_all. Como resultado se obtendrán otros dos archivos ubicados en el directorio /recognition_process/results/ : classified_result_KERNEL_COST_hof_300_ACTOR: Contiene los índices (véase § 6.4.2) que identifican la acción predicha para cada fragmento de vídeo. accuracy_KERNEL_COST_hof_300_ACTOR: Contiene el porcentaje de acierto/precisión obtenido en la predicción de cada fragmento de vídeo. 6.5 Iteración 5: Interfaz gráfica En la presente sección se pretende desarrollar una interfaz gráfica para los diferentes módulos que se han explicado en las secciones anteriores. El principal objetivo es el de facilitar la integración y manipulación de las diferentes funcionalidades desarrolladas y adaptadas a lo largo del proyecto. De esta forma, mediante una interfaz de usuario amigable será posible trabajar con los diferentes módulos de una manera más cómoda y sencilla. Para ello se ha empleado la plataforma Qt. Qt es una biblioteca multiplataforma ampliamente usada para desarrollar aplicaciones con interfaz gráfica de usuario, así como también para el desarrollo de programas sin interfaz gráfica, como herramientas para la línea de comandos y consolas para servidores. Además, Qt ha sido desarrollada como software libre y de código abierto a través de Qt Project18 . Qt es utilizada en KDE, entorno de escritorio para sistemas como GNU/Linux o FreeBSD. No obstante, una de las características que hace realmente interesante la utilización de esta plataforma es que Qt utiliza el lenguaje de programación C++ de forma nativa. Una vez que se ha elegido la plataforma y el lenguaje de programación a emplear, es el momento de analizar y diseñar cuáles van a ser las funcionalidades que debe soportar e implementar esta herramienta. La interfaz de usuario que se propone está organizada en diferentes pestañas para separar de una forma muy intuitiva las diferentes funcionalidades que se presentan en la aplicación. A continuación se describen brevemente en los siguientes apartados. 18 http://qt-project.org/ 159 Captura de vídeo La funcionalidad principal de esta pestaña es la de realizar la captura de vídeo a través del dispositivo Kinect. Para ofrecer una mayor flexibilidad al usuario, se ha ofrecido la posibilidad de seleccionar mediante los diálogos correspondientes la ruta en la que se desea almacenar los resultados obtenidos así como el nombre del actor del que se va a realizar la captura. Una vez que toda esta información ha sido facilitada por el usuario, simplemente será necesario ejecutar de forma interna el módulo de captura de vídeo desarrollado (véase § 6.3.2.3) con los parámetros indicados por el usuario. Como ya se expuso anteriormente, este módulo da como resultado los diferentes frames capturados en formato JPEG. Es por ello por lo que también se ha incluido la posibilidad de, una vez que se han llevado el proceso de captura, transformar estos ficheros JPEG en el vídeo correspondiente. De esta forma, indicando simplemente la ruta donde se encuentran los resultados de las diversas capturas y la correspondiente al directorio /BoW 19 , se generarán los vídeos correspondientes dejándolos preparados para su posterior procesamiento por el módulo de reconocimiento de acciones. Finalmente también se ha incluido un área para facilitar al usuario la retroalimentación pertinente de realizar los diferentes procesos descritos en los párrafos anteriores. En la Figura 6.50 se muestra una captura de la pestaña de “Captura de vídeo”. Etiquetado de vídeo En esta pestaña se ofrece al usuario la posibilidad de realizar la tarea de etiquetado de vídeo de una forma bastante sencilla. Para lograrlo se ha integrado todas las herramientas que son necesarias en una única interfaz como se puede apreciar en la Figura 6.51. De esta forma, el usuario tendrá acceso a un pequeño reproductor de vídeo con funcionalidades muy interesantes para facilitar su trabajo. Algunas de las más destacadas son: Lista de reproducción integrada. Controles de pausa, rebobinado, sonido, etc. Control de velocidad de la reproducción. Barra de información de la reproducción (tiempo del vídeo, tiempo restante, etc.) Visualización del frame actual y posibilidad de saltar a un frame concreto. Herramientas de modificación del color. Reproducción en pantalla completa. Histograma. 19 En el directorio /BoW se encuentran los correspondientes directorios y ejecutables del módulo de reconocimiento de acciones. 160 También se ha integrado un pequeño editor de texto para generar los ficheros ACTOR_frame_segmented.txt descritos en la sección anterior (véase § 6.4.2.2). De esta forma el usuario tendrá todo lo necesario para etiquetar los vídeos en una única interfaz sin necesidad de manejar un reproductor de vídeo y editor de texto por separado. No obstante, aunque el usuario tendrá la posibilidad de editar el fichero directamente en este editor integrado, se ha incluido una funcionalidad extra que facilitará aún más su trabajo. Esta nueva funcionalidad consiste en proporcionar la posibilidad de que, sin necesidad de ir deteniendo la reproducción del vídeo, sea posible ir editando el fichero ACTOR_frame_segmented.txt de una manera muy mecánica y sencilla. Para ello se han introducido dos botones que permiten seleccionar el frame actual del vídeo que se esté reproduciendo y una lista seleccionable de las diferentes acciones posibles. De esta forma, cuando el usuario haya indicado los frames de inicio y fin de la acción así como la acción correspondiente, estos serán introducidos directamente en el editor. Para asegurar que el fichero generado mantiene la coherencia se han incluido diversos mecanismos que comprueban los elementos incluidos. Clasificación En esta pestaña se ofrece al usuario la posibilidad de ejecutar el módulo de reconocimiento de acciones. Para ello, una vez haya realizado las funciones incluidas en las dos pestañas anteriores, el usuario simplemente deberá seleccionar la ruta donde se encuentra el directorio /BoW. Finalmente también se ha incluido un área para facilitar al usuario la retroalimentación pertinente de realizar el proceso de reconocimiento de acciones. En la Figura 6.52 se muestra una captura de la pestaña de “Clasificación”. Inspector de resultados Esta pestaña está pensada para facilitar la revisión de los resultados obtenidos en el proceso de reconocimiento. Para ello el usuario simplemente deberá facilitar la ruta donde se encuentra el directorio /BoW. El programa se encargará, de forma transparente para el usuario, de procesar todos los resultados que se encuentren disponibles en el directorio /BoW proporcionado y mostrarlos de una manera amigable para el usuario. De esta forma, esta última pestaña se ha organizado en tres columnas (ver Figura 6.53): Vídeos: Lista que permite seleccionar el vídeo (para el cual hay resultados) del que se desean visualizar los resultados. Etiquetado: Tabla que muestra el contenido del fichero ACTOR_frame_segmented.txt correspondiente al vídeo seleccionado. 161 Resultado: Tabla que muestra el resultado obtenido del vídeo seleccionado tras llevar a cabo el proceso de clasificación. Esta tabla esta compuesta por dos columnas. La primera indica la acción predicha (de forma textual, no con el índice correspondiente), mientras que la segunda indica si dicha predicción es correcta o no. Para facilitar aún más la comprobación de si los resultados obtenidos son correctos se han empleado diferentes colores (rojo para el incorrecto y verde para el correcto). Finalmente, también se proporcionará el nivel de precisión (Accuracy) de cada vídeo si este se encuentra disponible. 162 Figura 6.49: Diagrama de la fase 163de proceso de reconocimiento. Figura 6.50: Funcionalidad de Grabación. Figura 6.51: Funcionalidad de etiquetado. 164 Figura 6.52: Sección de clasificación. Figura 6.53: Sección de Resultados. 165 Capítulo 7 Resultados E el presente capítulo se describen los resultados obtenidos tras realizar las pruebas de precisión al sistema elaborado, además del proceso seguido para su correcta realización. Para ello se han empleado los módulos implementados a lo largo del proyecto (módulo de captura de imágenes y módulo de reconocimiento de acciones). De este modo, se ha decidido dividir el capítulo en las siguientes secciones: N Dataset de entrenamiento empleado. Recogida de datos de prueba. Análisis de los resultados. Además, también se proporciona al lector la opción de acceder al repositorio (véase https: //bitbucket.org/arco group/tfg.ruben.cantarero) donde se encuentran todos los recursos generados a lo largo del proyecto. 7.1 Dataset de entrenamiento empleado En primer lugar es necesario destacar que los vídeos empleados en el estudio deben representar escenarios lo más realistas posible. Esto se debe a que el principal objetivo es llevar a cabo un experimento de reconocimiento de acciones que son relevantes en la vida real. Es por este motivo por lo que es muy importante elegir un conjunto de entrenamiento adecuado. De este modo el conjunto de entrenamiento debe cubrir la mayor variedad de puntos de vista de la cámara, proporcionando de este modo un entrenamiento independiente del punto de vista. Además, este conjunto también debe cubrir una cantidad suficientemente grande de casos que representen las acciones que interesan para el presente estudio. Por último este conjunto de datos debe estar etiquetado, segmentado y organizado. Tras realizar una profunda búsqueda y análisis de los datasets disponibles se ha llegado a la conclusión de que los más adecuados y que mejor se ajustan a los requisitos buscados son INRIA Xmas Motion Acquisition Sequences (IXMAS) [WRB06] y Hollywood [LMSR08]. El conjunto de entrenamiento Hollywood está orientado hacia la detección de eventos incluyendo acciones significativas pero independientes unas de otras (comer, besar, conducir un coche, correr, etc.). Por el contrario, el dataset IXMAS está centrado en acciones realiza167 das en un entorno cerrado ofreciendo de este modo una descripción de las acciones posibles muy exhaustiva. Por lo tanto, las acciones ofrecidas en IXMAS pueden ser combinadas para descibir actividades simples como dar patadas, puñetazos, andar, sentarse, etc. y además proporciona representaciones completas de un conjunto de acciones realizadas de forma individual. Asimismo, por ser un dataset ampliamente utilizado, permite comparar y validar el sistema propuesto. Por consiguiente, se ha decidido emplear el dataset IXMAS para realizar la etapa de entrenamiento del sistema. Este conjunto de entrenamiento está compuesto por trece tipos de acciones realizadas por doce actores diferentes. Además, cada acción se encuentra grabada de forma simultanea por cinco cámaras diferentes (ver Figura 7.1). A continuación se muestra un listado de las acciones reconocidas: (0) Nada: No se está realizando ninguna acción. El usuario está parado. (1) Mirar reloj: El usuario realiza la acción de mirar el reloj de su muñeca. (2) Cruzarse de brazos: El usuario realiza la acción de cruzarse de brazos. (3) Rascarse la cabeza: El usuario realiza la acción de rascarse la cabeza. (4) Sentarse: El usuario realiza la acción de sentarse en el suelo. (5) Levantarse: El usuario realiza la acción de levantarse. (6) Darse la vuelta: El usuario realiza la acción de darse la vuelta sobre sí mismo. (7) Caminar: El usuario realiza la acción de caminar. (8) Saludar: El usuario realiza la acción de saludar con su mano. (9) Dar puñetazo: El usuario realiza la acción de dar puñetazos. (10) Dar patada: El usuario realiza la acción de dar patadas. (11) Señalar: El usuario realiza la acción de señalar con el dedo. (12) Coger: El usuario realiza la acción de coger algo del suelo, una mesa, etc. (13) Lanzar: El usuario realiza la acción de lanzar algo sobre su cabeza. (14) Lanzar: El usuario realiza la acción de lanzar algo de abajo hacia arriba. 7.2 Recogida de datos de prueba Como ya se anticipaba al comienzo del capítulo, se van a emplear dos datasets de acciones diferentes para evaluar el sistema: Dataset IXMAS y uno capturado mediante el dispositivo Kinect. El primero de ellos será empleado para llevar a cabo la etapa de entrenamiento o “training”, mientras que el segundo servirá como conjunto de datos para las pruebas o “testing” (véase § 6.4.2). El principal motivo de esta decisión se basa en que mediante el uso de 168 Figura 7.1: Ejemplo de IXMAS. [wbI14] dos datasets considerablemente diferentes es posible mostrar la generalidad, las capacidades y el rendimiento del sistema desarrollado en el presente proyecto. Para recoger este segundo conjunto de datos para el proceso de testing se ha empleado el módulo de captura de imágenes desarrollado en el proyecto (véase § 6.2 y § 6.3). De esta forma, ha sido posible generar un conjunto de entrenamiento propio: “KinbehrDataset”. El primer paso necesario para la creación de este dataset fue la preparación del escenario en el que iban a tener lugar las grabaciones. Como se puede apreciar en la Figura 7.2 el escenario consiste en una única habitación que dispone de los siguientes elementos: Un libro: Consiste en un libro de crucigramas con la intención de captar la atención de los actores durante la grabación y potenciar así la realización de la acción coger. Una silla: Puede ser utilizada y movida por los actores durante la grabación. De este modo se pretende animar a los actores a realizar la acción sentarse. Un saco de boxeo: Puede ser empleada por los actores durante la grabación. La forma más natural de interaccionar con él es mediante puñetazos y patadas. Una pelota: Puede ser empleada por los actores durante la grabación. La forma más natural de interaccionar con ella es botándola o lanzarla al aire o contra las paredes para así realizar la tarea de lanzar o tirar algo. Mediante la introducción de estos elementos en el escenario se pretende diseñar un dataset que sea lo más representativo posible respecto de la inmensa variabilidad de acciones de la vida real, sin perder en ningún momento de vista que debe contener la mayoría de las acciones integradas en el dataset IXMAS con el que ha sido entrenado el sistema. De esta manera se conduce a los actores a que de forma natural interaccionen con los elementos que interesan para los objetivos del sistema. Un ejemplo de ello podría ser como el actor encuentra el libro, lo recoge (acción coger) y se sienta a leerlo (acción sentarse). Otro ejemplo 169 Figura 7.2: Escenario de grabación empleado. también podría ser como el actor ve el saco de boxeo y empieza a jugar con el dándole patadas y puñetazos (acción patada y acción puñetazo). Una vez que el escenario estaba preparado se comenzó con el proceso de grabación. Para ello se convocó a quince actores de diferentes estaturas, peso y sexo para obtener la mayor variedad posible. En el Cuadro 7.1 se muestra un resumen con la información más relevante. Actor 1 Actor 2 Actor 3 Actor 4 Actor 5 Actor 6 Actor 7 Actor 8 Actor 9 Actor 10 Actor 11 Actor 12 Actor 13 Actor 14 Actor 15 Edad Sexo Peso (Kg) Altura (m) No de acciones 21 23 20 19 20 20 24 22 22 23 25 28 22 23 23 M M M H H H H H M M H H H H H 60 52 65 98 64 80 96 73 52 76 74 68 82 84 98 1.63 1.67 1.65 1.84 1.74 1.77 1.85 1.80 1.65 1.67 1.82 1.72 1.75 1.87 1.85 80 102 121 192 123 73 64 66 98 47 115 53 74 93 52 Cuadro 7.1: Información y número de acciones realizado por cada actor. Es importante mencionar que este proceso de grabación fue dividido en dos partes bien diferenciadas con objetivos diferentes. De esta forma, por cada actor se realizaban dos procesos de grabación: 170 Grabación en entorno no guiado: En este proceso de grabación no se le daba ningún tipo de instrucción al actor. De este modo, se dejaba al actor en la habitación con el lema “tienes 8 minutos para hacer lo que quieras”. Grabación en entorno guiado: En este proceso se iba solicitando al actor que realizara repetidamente las acciones que se le fueran indicando. Una de las principales motivaciones de este proceso es facilitar un conjunto de datos que pueda ser posteriormente empleado para el entrenamiento del sistema. Como resultado se obtuvieron dos paquetes de vídeos por cada actor capturados mediante el módulo de captura de imágenes. Estos paquetes están compuestos por tres tipos de vídeos cada uno: Vídeo RGB, vídeo de profundidad y vídeo de esqueleto. Posteriormente cada una de estas secuencias grabadas tuvieron que ser manualmente segmentadas y etiquetadas por acciones (véase § 6.4.2.2) mediante la herramienta elaborada en el presente proyecto (véase § 6.5). Recuérdese que la segmentación automática de vídeos en acciones independientes queda fuera del alcance y objetivos de este proyecto. Los lectores interesados en la segmentación automática de vídeos puede referirse a [RA00] [con97] [AA01] [SMS07] y [SWCS08]. Por último es importante destacar que, como los vídeos de las personas pueden considerarse datos de carácter personal, fue necesario la elaboración de un formulario de consentimiento (véase § C). De esta forma, antes de comenzar con el proceso de grabación los actores debían leer un documento que les era facilitado. En este documento se explicaba el objetivo del proyecto, el uso de dicha grabación, etc. Además se les facilitaba respuesta a todas las preguntas que les pudiere surgir acerca del documento o del proceso. Finalmente se les proporcionaba un formulario que debían rellenar y firmar si estaban de acuerdo con el contrato. Para asegurar la confidencialidad, el único momento en el que quedan relacionados lo vídeos con los datos identificativos de los actores (nombres y apellidos) es en dicho formulario. De este modo, los vídeos fueron nombrados como actor1, actor2, etc. Finalmente estos formularios fueron almacenadas en el grupo ARCO, lugar de acceso restringido, para asegurar su seguridad. 7.3 Análisis de los resultados Una vez que el dataset KinbehrDataset ha sido generado, segmentado y etiquetado por acciones, es el momento de realizar el análisis de los resultados obtenidos. No obstante, antes es necesario aclarar algunos conceptos importantes que se mencionaron anteriormente. Estos son los valores de algunos de los parámetros empleados por las herramientas stipdept (véase § 6.4.2.3.1) y bsvm-train (véase § 6.4.2.3.3). Como a priori no se conoce cuál es el valor más adecuado para el caso de estudio, se realizaron diferentes pruebas tomando diferentes valores. De este modo, se pudo determinar qué valores eran los más adecuados para estos parámetros y así poder obtener los mejores resultados posibles. 171 A continuación se expone el análisis dichos resultados. Estos muestran el porcentaje de acierto de cada actor según tipo de acción clasificados por la clase de vídeo (RGB, profundidad y esqueleto). En el Cuadro 7.2 se muestra el análisis de resultados correspondientes a los vídeos obtenidos en el proceso de grabación no guiado y en el Cuadro 7.3 los correspondientes a los vídeos obtenidos en el proceso de grabación guiado. Es importante mencionar que los guiones representan que el actor correspondiente no ha realizado una determinada acción. Por último, también se muestra el porcentaje total de acierto del actor para todas las acciones que ha realizado. En el Cuadro 7.4 se muestra un resumen del análisis de los resultados obtenidos según el tipo de acción. Estos resultados representan el porcentaje de acierto clasificados por la clase de vídeo (RGB, profundidad y esqueleto). En la Figura 7.3 se muestra un gráfico que representa el porcentaje de acierto según la clase de vídeo para cada acción, considerando los vídeos grabados en el entorno guiado y no guiado. Figura 7.3: Porcentaje de acierto de cada acción según el tipo de imagen (entorno guiado y sin guiar). En el Cuadro 7.5, el Cuadro 7.6 y el Cuadro 7.7 se muestran las matrices de confusión correspondientes a cada tipo de vídeo, RGB, profundidad y esqueleto respectivamente. En el campo de la inteligencia artificial una matriz de confusión es una herramienta de visualización que se emplea en aprendizaje supervisado. Cada columna de la matriz representa el número de predicciones de cada clase, mientras que cada fila representa a las instancias en la clase real. Uno de los beneficios de las matrices de confusión es que facilitan ver si el sistema está confundiendo dos clases. No obstante, es importante tener en cuenta que si en este tipo de matrices el número de muestras de clases diferentes cambia mucho la tasa de error del clasificador no es representativa de lo bien que realiza la tarea el clasificador. Esto quiere decir que si por ejemplo hay 1000 muestras de la clase 1 y sólo 20 de la clase 2, el clasificador puede tener fácilmente un 172 Actor 1 Actor 2 Actor 3 Actor 4 Actor 5 Actor 6 Actor 7 Actor 8 Actor 9 Actor 10 Actor 11 Actor 12 Actor 13 Actor 14 Actor 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Total RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB 0 Profundidad 0 Esqueleto 0 RGB 0 Profundidad 0 Esqueleto 0 RGB 0 Profundidad 0 Esqueleto 0 RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto - 0 - 0 0 0 - 25 25 0 66.6 0 0 50 50 0 33.3 33.3 0 50 0 0 0 0 0 33.3 0 0 0 20 0 0 0 0 33.3 0 66.6 0 0 0 0 0 0 - 50 50 0 66.6 0 50 50 0 0 66.6 33.3 50 33.3 66.6 0 50 25 0 80 60 66.6 20 20 0 50 0 100 0 0 0 100 50 50 0 - 16 0.1 12.5 26.3 0.05 12.5 12.5 0.1 9 17.4 0.1 0 0 0 0 12.5 0.06 0 0 0 0 42.8 0 0 0.1 0 16.7 0 7.7 0 25 6.7 6.6 30 10 10 15 5.5 5.5 14.3 0 0 0 0 0 58 84.2 60 50 50 44.4 31.8 59 33.3 10 70 14.3 100 66.6 100 46.2 46.1 40 50 80 90 25 41.7 40 79.3 89.7 77.8 60 75 75 65 80 75 63.2 68.4 78.9 54.1 75 47.8 38.5 73 61.5 41.6 66.6 41.7 0 0 0 0 0 0 0 0 - 40 40 50 37.5 46.9 43.8 29.4 35.2 12.5 55.7 42.6 50.9 30.3 27.5 21.7 28.6 0.06 7.1 42.8 18.7 10.5 50 25 33.3 50 11.1 11.1 50 0 0 36.2 24.1 20.7 33.3 22.2 22.2 12.5 12.5 12.5 60 40 20 35 20 30 43 60 66.6 20 60 0 50 83.3 66.6 36.1 38.3 29.3 0 33.3 0 0 100 100 100 100 100 22.2 66.6 100 0 100 100 0 0 0 0 36.4 27.3 100 0 100 - 42 41.6 0 75 62.5 42.9 21 26.3 0 15 0 0 14.2 28.6 16.7 50 25 40 26.6 28.6 7.1 60 60 25 100 60 33.3 33.3 33.3 0 0 0 0 50 50 0 50 50 25 33.3 33.3 14.3 33.3 66.6 11.1 0 0 0 0 0 0 0 0 0 0 0 0 50 0 0 50 0 0 11.1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 48 43.4 30.5 39.2 32.4 29.2 19.8 25.8 13.9 31.2 27.2 25.5 30.1 27.3 22.2 27.4 17.8 13.6 31.3 28.3 23.3 37.9 24.2 21.9 42.8 39.8 38.6 34.1 36.9 39.1 33.1 27.4 24.7 39.6 39.6 43.4 29.7 33.8 21.1 24.7 35.5 24.7 30.8 26.9 25 Cuadro 7.2: Porcentaje de acierto de cada actor (sin guiar) en cada tipo de actor según el tipo de imagen. 173 1 Acciones 1 Acciones 2 Acciones 3 Acciones 4 Acciones 5 Acciones 6 Acciones 7 Acciones 8 Acciones 9 Acciones 10 Acciones 11 RGB 0 Profundidad 0 Esqueleto 0 RGB 0 Profundidad 0 Esqueleto 0 RGB 50 Profundidad 0 Esqueleto 0 RGB 0 Profundidad 0 Esqueleto 0 RGB 0 Profundidad 0 Esqueleto 0 RGB 0 Profundidad 0 Esqueleto 0 RGB 50 Profundidad 0 Esqueleto 0 RGB 0 Profundidad 0 Esqueleto 0 RGB 0 Profundidad 0 Esqueleto 0 RGB 0 Profundidad Esqueleto RGB 50 Profundidad 0 Esqueleto 0 2 3 4 5 6 7 8 9 10 11 12 13 14 Total 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 100 50 0 100 50 0 0 0 0 0 0 0 0 50 0 50 100 0 30 50 0 0 50 0 50 50 0 50 100 0 100 0 0 50 100 50 50 50 50 100 100 100 100 100 0 0 100 50 50 100 0 100 0 0 50 100 50 50 100 0 50 33.3 0 33.3 0 0 33.3 0 0 33.3 50 0 0 33.3 0 0 25 0 0 100 0 0 0 0 0 33.3 0 0 0 0 0 0 0 0 75 75 75 100 100 100 50 75 100 100 100 100 100 100 100 100 100 100 75 100 100 100 100 100 75 100 75 50 100 100 66.6 100 66.6 0 0 0 0 0 0 0 0 0 50 0 0 0 0 0 50 0 0 0 0 0 0 0 0 0 0 0 50 0 0 0 62.5 75 87.5 42.9 33.3 0 0 0 14.3 30 30 20 0 20 0 55.5 33.3 55.6 25 0 0 33.3 33.3 33.3 71.4 57.1 57.1 25 50 50 28.6 28.6 14.3 50 60 10 50 100 70 10 50 30 66.7 83.3 83.3 33.3 100 66 25 37.5 12.5 75 75 75 0 33.3 66.6 66.6 83.3 66.6 66.6 66.6 50 0 50 50 0 0 0 0 0 50 0 0 50 50 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33.3 0 0 50 100 0 100 100 20 0 0 0 100 50 50 100 100 0 100 50 50 50 100 0 50 50 0 50 50 0 0 0 0 33.3 0 0 0 0 0 0 0 0 0 0 50 0 0 50 0 0 0 0 0 33.3 0 0 0 50 0 0 0 33.3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36.9 39.1 30.4 23.7 25.8 29 18.8 22.9 33 40 29.5 29.5 26.5 29.4 26.5 40.4 30.4 23.9 45.5 29 32.2 28.6 25.8 35.5 35 33.3 30.8 33.3 44.4 40.7 21 23.7 18.4 Cuadro 7.3: Porcentaje de acierto de cada actor (guiado) en cada tipo de actor según el tipo de imagen. 174 No ocurrencias Tipo % acierto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB Profundidad Esqueleto RGB 12 0 0 9 0 0 0 0 0 27.8 6.7 18.2 59 28.8 44.7 16.8 10 6 44.8 70.9 64.2 11.5 0 0 37.7 29.7 28 34.5 55 41.9 4.7 0 10.5 41.1 41.2 11.5 3.1 95 Profundidad Esqueleto RGB 1 6.9 0 113 Profundidad Esqueleto 0 0 Mirar reloj 25 Cruzar brazos 22 Rascar cabeza 23 Sentarse 61 Levantarse 61 Darse la vuelta 250 Caminar 361 Saludar 26 Dar puñetazo 453 Dar patada 108 Señalar 21 Coger 175 Lanzar (por encima de la cabeza) Lanzar (por debajo de la cabeza) Cuadro 7.4: Porcentaje de acierto de cada acción según el tipo de imagen (entorno guiado y sin guiar). 175 Cruzar Brazos Rascar cabeza Sentarse Levantarse Darse la vuelta Caminar Saludar Dar puñetazo Dar patada Señalar Coger Lanzar (encima) Lanzar (debajo) Mirar reloj Cruzar brazos Rascar cabeza Sentarse Levantarse Darse la vuelta Caminar Saludar Dar puñetazo Dar patada Señalar Coger Lanzar (encima) Lanzar (debajo) Mirar Reloj sesgo hacia la clase 1. Si el clasificador clasifica todas las muestras como clase 1 su precisión será del 99 %. Esto no significa que sea un buen clasificador, pues tuvo un 100 % de error en la clasificación de las muestras de la clase 2. En este caso en particular puede resultar problemático ya que la acción que contiene mas ocurrencias (acción dar puñetazo con un valor de 453) difiere bastante con respecto la menor (acción señalar con un valor de 21). 0.12 0.00 0.04 0.00 0.00 0.00 0.00 0.00 0.03 0.01 0.00 0.00 0.01 0.03 0.12 0.05 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.10 0.00 0.00 0.04 0.00 0.00 0.00 0.03 0.03 0.00 0.00 0.07 0.00 0.00 0.00 0.01 0.00 0.00 0.12 0.05 0.04 0.28 0.00 0.02 0.01 0.07 0.07 0.08 0.10 0.03 0.02 0.04 0.12 0.23 0.00 0.00 0.61 0.03 0.01 0.00 0.01 0.02 0.10 0.07 0.02 0.04 0.04 0.05 0.04 0.03 0.00 0.17 0.11 0.04 0.04 0.08 0.05 0.04 0.12 0.11 0.00 0.00 0.00 0.00 0.00 0.17 0.54 0.11 0.17 0.10 0.00 0.05 0.11 0.16 0.08 0.09 0.13 0.07 0.05 0.11 0.10 0.15 0.04 0.03 0.14 0.03 0.06 0.07 0.16 0.45 0.35 0.30 0.13 0.18 0.06 0.11 0.38 0.28 0.24 0.20 0.34 0.32 0.04 0.05 0.09 0.07 0.02 0.26 0.14 0.15 0.18 0.33 0.14 0.05 0.23 0.15 0.08 0.00 0.09 0.13 0.00 0.02 0.03 0.04 0.01 0.05 0.10 0.07 0.03 0.03 0.00 0.00 0.00 0.03 0.11 0.00 0.00 0.00 0.00 0.00 0.00 0.41 0.03 0.00 0.12 0.05 0.22 0.07 0.05 0.04 0.00 0.26 0.06 0.02 0.05 0.03 0.02 0.03 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Cruzar Brazos Rascar cabeza Sentarse Levantarse Darse la vuelta Caminar Saludar Dar puñetazo Dar patada Señalar Coger Lanzar (encima) Lanzar (debajo) Mirar reloj Cruzar brazos Rascar cabeza Sentarse Levantarse Darse la vuelta Caminar Saludar Dar puñetazo Dar patada Señalar Coger Lanzar (encima) Lanzar (debajo) Mirar Reloj Cuadro 7.5: Matriz de confusión de los vídeos RGB (entorno guiado y sin guiar). 0.00 0.00 0.00 0.00 0.02 0.01 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.05 0.00 0.00 0.07 0.00 0.02 0.00 0.00 0.09 0.06 0.00 0.02 0.03 0.06 0.00 0.00 0.00 0.00 0.27 0.02 0.00 0.04 0.03 0.03 0.00 0.05 0.02 0.06 0.00 0.00 0.00 0.02 0.05 0.04 0.04 0.09 0.04 0.04 0.00 0.07 0.02 0.04 0.71 0.83 0.74 0.31 0.16 0.36 0.74 0.35 0.16 0.11 0.79 0.09 0.25 0.19 0.00 0.00 0.00 0.02 0.02 0.09 0.11 0.00 0.05 0.02 0.00 0.00 0.06 0.08 0.00 0.00 0.00 0.02 0.04 0.09 0.01 0.04 0.29 0.14 0.00 0.06 0.18 0.23 0.10 0.11 0.11 0.34 0.05 0.35 0.09 0.35 0.27 0.54 0.21 0.26 0.31 0.28 0.14 0.06 0.11 0.09 0.02 0.02 0.00 0.13 0.03 0.02 0.00 0.06 0.09 0.04 0.00 0.00 0.00 0.09 0.38 0.00 0.00 0.00 0.00 0.00 0.00 0.38 0.02 0.01 0.00 0.00 0.05 0.05 0.00 0.00 0.00 0.00 0.04 0.04 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Cuadro 7.6: Matriz de confusión de los vídeos de profundidad (entorno guiado y sin guiar). 176 Mirar Reloj Cruzar Brazos Rascar cabeza Sentarse Levantarse Darse la vuelta Caminar Saludar Dar puñetazo Dar patada Señalar Coger Lanzar (encima) Lanzar (debajo) Mirar reloj Cruzar brazos Rascar cabeza Sentarse Levantarse Darse la vuelta Caminar Saludar Dar puñetazo Dar patada Señalar Coger Lanzar (encima) Lanzar (debajo) 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.01 0.01 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.05 0.00 0.00 0.16 0.00 0.01 0.00 0.05 0.05 0.04 0.05 0.00 0.06 0.12 0.00 0.00 0.00 0.00 0.45 0.02 0.01 0.00 0.04 0.05 0.00 0.01 0.01 0.05 0.00 0.06 0.00 0.02 0.00 0.05 0.01 0.09 0.04 0.03 0.05 0.03 0.03 0.09 0.55 0.67 0.47 0.20 0.11 0.23 0.64 0.45 0.23 0.17 0.53 0.06 0.21 0.21 0.00 0.06 0.00 0.00 0.00 0.10 0.14 0.05 0.07 0.02 0.00 0.02 0.04 0.03 0.05 0.00 0.00 0.02 0.11 0.12 0.02 0.09 0.29 0.09 0.00 0.10 0.21 0.23 0.32 0.22 0.53 0.45 0.02 0.38 0.17 0.18 0.19 0.43 0.32 0.50 0.32 0.21 0.05 0.00 0.00 0.09 0.04 0.04 0.00 0.05 0.04 0.09 0.05 0.13 0.04 0.03 0.00 0.00 0.00 0.05 0.28 0.00 0.00 0.00 0.01 0.01 0.00 0.12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.02 0.00 0.05 0.03 0.06 0.00 0.02 0.07 0.04 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Cuadro 7.7: Matriz de confusión de los vídeos de los esqueletos (entorno guiado y sin guiar). Llegados a este punto es el momento de contrastar y validar los resultados obtenidos y que se han explicado en los párrafos anteriores con sistemas similares cuyo objetivo final es también el reconocimiento de acciones. Para ello se ha tomado como referencia el estudio efectuado por Jesús Martínez Del Rincón, Jean-Christophe Nebel y María Jesús Santofimia Romero: “Common-sense reasoning for human action recognition” [MDRSN13]. En dicho estudio se presenta un nuevo método que aprovecha las capacidades de razonamiento en un sistema de visión por computador dedicado al reconocimiento de la acción humana. Para ello, proponen una metodología dividida en dos etapas. La primera de ellas está basada en los mismos principios que el presente proyecto: Bag of Words (B OW). Una vez que han obtenido los resultados proporcionados en la etapa de aprendizaje basado en el algoritmo máquina, realizan un procesamiento adicional. Este procesamiento consiste en el análisis y corrección de las estimaciones iniciales proporcionadas por B OW mediante un sistema de razonamiento común. En dicho estudio generan su propio dataset (WaRo11) para obtener los resultados mediante una cámara RGB normal. En el Cuadro 7.8 se muestra una tabla comparativa de los resultados obtenidos en dicho estudio con respecto a los obtenidos en el presente proyecto. A continuación se presenta una breve descripción de la tabla para facilitar su comprensión: La primera columna representa que el sistema [MDRSN13] ha sido entrenado con el dataset IXMAS y evaluado con WaRo11. La segunda columna representa que el sistema K IN B EH R ha sido entrenado con el dataset IXMAS y evaluado con KinbehrDataset. La fila representa que se ha empleado únicamente la etapa de B OW. 177 B OW Tra. == IXMAS & Test. == WaRo11 Tra. == IXMAS & Test. == KinbehrDataset RGB: 29.4 RGB: 32.7 Cuadro 7.8: Comparación de resultados con [MDRSN13]. Un aspecto a destacar es que los resultados obtenidos con K IN B EH R son algo mejores con respecto a los obtenidos en [MDRSN13] en la etapa de B OW. Es importante mencionar que los vídeos contenidos en el dataset KinbehrDataset son bastante más complejos de evaluar que WaRo11. Esto se debe principalmente a que los actores en KinbehrDataset se comportan de una forma más natural, como por ejemplo realizar varias acciones al mismo tiempo. Por otro lado, en el Cuadro 7.9 se puede observar que los resultados mejoran cuando el sistema es evaluado con el mismo dataset con el que ha sido entrenado. No obstante, estos resultados no son del todo realistas ya que estas circunstancias no se van a dar en un entorno real en el que sea necesario realizar un reconocimiento de acciones. Otro aspecto a destacar es que los resultados obtenidos cuando se emplea un sistema de razonamiento adicional (segunda y tercera fila donde n es el número de acciones considerado en el sistema de razonamiento) son considerablemente mejores. Por lo tanto, es muy posible que mediante la incorporación de un sistema de razonamiento en K IN B EH R se obtenga una tasa de acierto mejorada. Este aspecto será comentado en más profundidad en el capítulo Conclusiones y trabajo futuro (véase § 8). B OW B OW B OW + AIRS (n = 1) + AIRS (n = 5) Tra. & Test. == IXMAS Tra. == IXMAS & Test. == WaRo11 Tra. == IXMAS & Test. == KinbehrDataset RGB: 63.9 Profundidad: Esqueleto: RGB: RGB: - RGB: 29.4 Profundidad: Esqueleto: RGB: 35.5 RGB: 51.9 RGB: 32.7 Profundidad: 30.8 Esqueleto: 28 RGB: RGB: - Cuadro 7.9: Comparación de resultados con [MDRSN13]. Finalmente, para concluir el capítulo es importante explicar algunos de los motivos por los que la tasa de acierto no es mayor en algunos tipos de acciones. Los factores identificados más importantes son los siguientes: En los vídeos de profundidad capturados se ha comprobado que en ciertas ocasiones el middleware NiTE (véase § 6.3.1) identifica al saco de boxeo como una persona. Esto puede introducir ruido que dificulte la tarea de clasificación ya que como se aprecia en la Figura 7.4 se introducen en la escena elementos que no son personas. Este problema se ve acentuado si el saco de boxeo se encuentra en movimiento. Un problema muy similar al anterior ocurre con los vídeo de esqueleto. En la Figura 7.5 se aprecia como el middleware NiTE identifica el saco de boxeo como una persona y por lo tanto es dibujado su “correspondiente” esqueleto. 178 Figura 7.4: Problema encontrado en vídeos de profundidad. Figura 7.5: Problema encontrado en vídeos de esqueletos. El dataset IXMAS etiqueta ciertas acciones de una manera muy particular permitiendo un margen muy pequeño en algunas acciones de las secuencias de vídeos capturadas. Uno de los ejemplos más llamativos es la “acción sentarse”. En IXMAS esta acción es siempre etiquetada con un actor sentándose en el suelo, mientras que en las pruebas realizadas se ha etiquetado como “sentarse” cuando un actor se sienta en la silla proporcionada en el escenario. 179 Capítulo 8 Conclusiones y trabajo futuro E este capítulo se analiza el trabajo realizado en la elaboración de este proyecto, mostrando en qué grado han sido logrados los objetivos que fueron marcados al comienzo de su desarrollo. También se expondrán diversas propuestas de trabajo futuro que podrían mejorar y extender la funcionalidad del sistema desarrollado. N 8.1 Objetivos alcanzados En esta sección se analizarán los objetivos expuestos en el capítulo de objetivos (véase § 2), mostrando de esta manera la forma en que han sido resueltos así como el nivel de satisfacción que ha sido alcanzado con cada uno de ellos. Es importante comenzar recordando cuál era el objetivo principal del proyecto. Este consistía en el desarrollo de un sistema de reconocimiento de acciones que mediante un algoritmo de “aprendizaje máquina” (machine learning) combinara las imágenes de intensidad y profundidad obtenidas mediante un dispositivo que lo permitiera. También debía disponer de una base de conocimiento que contuviera información de alto nivel sobre diferentes tipos de acciones humanas. Llegados a este punto, es posible decir que este objetivo principal ha sido cubierto en su totalidad mediante el desarrollo de un sistema compuesto de un clasificador de máquina de vectores o Support Vector Machines (SVM) y la adopción del modelo Bag of Words (B OW). En el capítulo anterior (véase § 7) se mostraban los resultados y la precisión lograda con dicho sistema. No obstante, se debe recordar que a parte de este objetivo principal, se plantearon una serie de objetivos más específicos que describían de una forma más concisa lo que se esperaba del sistema propuesto. A continuación se muestra cómo se ha afrontado la realización estos objetivos específicos. Evaluación de mercado. Este objetivo consistía en la realización de un análisis de los diferentes dispositivos Kinect disponibles en el mercado (Kinect for Xbox 360, Kinect for Windows y Kinect de segunda generación). Además, también se pretendía decidir qué dispositivo era el más apropiado para el proyecto en base a la información recopilada. Para ello fue necesario realizar un amplio barrido y filtrado de toda la información que se encontraba disponible en la web, libros, artículos académicos, así como los proyec181 tos existentes que hacen uso de esta tecnología. El principal problema con el que hubo de enfrentarse para la consecución de este objetivo fue que la información se encontraba muy dispersa y, en algunas ocasiones, podía llegar a ser un poco contradictoria. Por último, también es importante destacar que en el momento de decidir qué dispositivo era el más apropiado se encontraron problemas presupuestarios ya que tan sólo se tenía la posibilidad de emplear el modelo Kinect for Xbox 360. Análisis de librerías disponibles. Con este objetivo se pretendía realizar un estudio acerca de las plataformas y/o librerías disponibles para el dispositivo Kinect elegido. También se pretendía identificar y analizar las posibilidades que ofrecían cada una, así como las limitaciones, ventajas y desventajas que presentaban. Para lograr la consecución de este objetivo fue necesario realizar una profunda búsqueda en diferentes medios y sintetizar toda la información encontrada para destacar la información relevante para el estudio. Una vez que toda esta información fue procesada, se decidió que la plataforma más adecuada era O PEN NI. Esto se debía principalmente a su naturaleza multiplataforma y software abierto. También es importante destacar que el hecho de permitir la incorporación de diferentes middleware la convertía en una opción mucho más atractiva. No obstante, el principal contratiempo encontrado fue que durante la elaboración del proyecto la compañía creadora de la librería fue comprada y se detuvieron todos los servicios de soporte que se ofrecían hasta el momento. Identificación y análisis de los datos recogidos por el dispositivo. Este objetivo, más técnico que los anteriores, consistía en identificar los diferentes tipos de información proporcionados por el modelo de Kinect elegido. Otra tarea a realizar era analizar cómo debían interpretarse estos flujos de información, así como su manera de manipularlos y procesarlos. De este modo, fue necesario familiarizarse con diversos conceptos relacionados con el tratamiento de imágenes. Para obtener las habilidades técnicas necesarias para trabajar con la plataforma O PEN NI y NiTE se empleó una librería de alto nivel (SimpleOpenNI) mucho más sencilla y fácil de manejar. Gracias a la utilización de esta librería se analizaron algunos conceptos importantes, como por ejemplo la forma de interpretar las imágenes de profundidad o las diferencias con respecto a las típicas imágenes RGB. Una vez que esta primera toma de contacto tuvo lugar, se procedió a llevar a cabo la esencia de este objetivo: Desarrollar el módulo de captura de imágenes empleando O PEN NI y NiTE. Aunque este objetivo ha sido alcanzado con éxito, no estuvo falto de problemas y contratiempos que tuvieron que ser resueltos (véase § 6.2 y § 6.3). Algunos de los más destacados fueron el elevado consumo de memoria o la pérdida de frames durante la captura. Identificación y análisis del conjunto de acciones a reconocer. Con este objetivo se pretendía identificar qué acciones podían ser monitorizadas y reconocidas. De este modo fue posible realizar un análisis de los patrones que caracterizan a cada una. Una vez 182 realizado este análisis, se decidió incorporar un nuevo tipo de vídeo, aparte del RGB y profundidad, que consistía en el esqueleto de los usuarios que estuvieran en escena. Este objetivo también permitió conocer aspectos que serían relevantes posteriormente en el análisis e interpretación de los resultados obtenidos en el sistema. Ejemplo de ello es que en algunas ocasiones aisladas reconocía como personas objetos de las escena. Adaptación del modelo Bag of Words. Este objetivo partía de la realización de un estudio que permitiera obtener una visión general acerca del estado del arte sobre las soluciones existentes. De este modo, fue posible identificar, analizar y, lo más importante, comprender todos los conceptos sobre el funcionamiento de un modelo basado en Bag of Words (B OW). También se llevó a cabo la adaptación de la solución proporcionada a las peculiaridades del proyecto. Una vez que todos estos aspectos estaban resueltos, fue posible la elaboración del módulo de reconocimiento de acciones que, junto con el módulo de captura de imágenes, constituiría el núcleo del sistema. Para ello fue necesario obtener diversas habilidades técnicas para la utilización de diferentes herramientas y los conceptos que tenían asociados. Uno de los más importantes fue cómo obtener puntos de interés espacio-temporales de los vídeos obtenidos mediante la herramienta stipdept1 . No obstante, no fue el único reto ya que estos puntos obtenidos debían ser procesados mediante técnicas de clustering. Aunque este objetivo fue completado con éxito, supuso todo un reto. Esto se debió principalmente a que muchos de los conceptos aplicados eran totalmente desconocidos. Desarrollo de un clasificador (SVM). Este objetivo consistía en realizar un estudio, análisis y diseño de las diferentes técnicas de clasificación existentes y que permitan el reconocimiento de patrones de las acciones que se pretender monitorizar. También fue necesario familiarizarse y comprender los conceptos asociados al funcionamiento de este tipo de clasificadores. De este modo, para la consecución de este objetivo se empleó una solución existente proporcionada por la herramienta BSVM 2 . Posteriormente, se llevaron a cabo los procesos de entrenamiento y evaluación del mismo. Este objetivo fue completado con éxito. No obstante, se encontraron nuevamente las mismas dificultades: Algunos los conceptos eran totalmente desconocidos. Organización del conjunto de sujetos del experimento. Con este objetivo se pretendía que mediante la utilización de un método científico de recogida de datos se confeccionara un conjunto de datos (ejemplos de entrenamiento o muestras) de diferentes individuos. En primer lugar es importante destacar que se decidió emplear dos conjunto de datos diferentes para la evaluación del sistema desarrollado. El primero de ellos debía ser un dataset público que permitiera entrenar de forma adecuada al sistema. Para ello se tuvo que realizar un breve estudio sobre los dataset existentes, donde se identificó que 1 2 http://www.di.ens.fr/~laptev/index.html http://www.csie.ntu.edu.tw/~cjlin/bsvm/ 183 los que mejor se adaptaban a las necesidades del proyecto eran INRIA Xmas Motion Acquisition Sequences (IXMAS) [WRB06] y Hollywood [LMSR08]. Tras realizar un análisis en profundidad de ambos, se decidió emplear el dataset IXMAS. Para el segundo de ellos se decidió crear un dataset propio (KinbehrDataset) con vídeos capturados mediante el módulo de captura de imágenes desarrollado. De esta forma, fue necesario preparar un escenario donde los actores pudieran realizar las diferentes acciones mediante la inclusión de un saco de boxeo, una pelota, etc. También es importante mencionar que se decidió realizar dos procesos de grabación bien diferenciados: Guiado y sin guiar. Mientras que en el primero el usuario realizaba las acciones que se le fueran indicando, en el segundo el actor era dejado sólo en la habitación durante ocho minutos con la única instrucción de hacer lo que quisiera. Una vez que ya se tenían todos los vídeos, fue necesario la segmentación y etiquetación de los mismos. El último paso de este objetivo consistió en poner en marcha el sistema con los diferentes dataset y analizar los resultados obtenidos. El objetivo fue logrado con éxito, aunque para ello fue necesario enfrentarse a alguna dificultad. Entre las más destacadas fue el coordinar y organizar a todos los participantes de las grabaciones; la dificultad de realizar una correcta etiquetación de los vídeos o la elaboración de un formulario adecuado que se encontrara en consonancia con la legislación vigente acerca de la protección de datos de carácter personal. Desarrollo de una interfaz gráfica. Este objetivo consistía en el desarrollo de una interfaz gráfica que permitiera integrar los diferentes módulos que habían sido desarrollados durante el proyecto. Para la consecución de este objetivo fue necesario realizar un estudio y análisis de las diferentes soluciones existentes para la implementación de esta interfaz de usuario que permitiera facilitar la utilización a los futuros usuarios del sistema. Debido a que gran parte del proyecto está escrito en el lenguaje de programación C++ y debido a la gran cantidad de funcionalidades que ofrece, Qt3 fue la herramienta elegida para desempeñar esta labor. Tras este breve análisis de los objetivos marcados al comienzo del proyecto y como conclusión final referente a estos objetivos, es posible afirmar que todos han sido alcanzados satisfactoriamente. 8.2 Trabajo futuro La realización del proyecto descrito en la presente memoria ha supuesto la creación de un sistema de reconocimiento de acciones a través de los vídeos RGB y de profundidad capturados por el dispositivo Kinect. No obstante, a pesar de cumplir con todos los objetivos marcados al comienzo del proyecto, es susceptible de diversas mejoras e incorporación de nuevas funcionalidades. A continuación se presenta un breve resumen de estas mejoras que 3 http://qt-project.org/ 184 posiblemente sean abordadas en un Trabajo Fin de Máster. El proceso de clasificación de acciones propuesta en el presente proyecto está centrado en el procesamiento de vídeo. Sin embargo, como ya se mencionaba anteriormente, el middleware NiTE proporciona información bastante precisa sobre la ubicación de las articulaciones de los usuarios que se encuentran en escena. Hasta el momento, esta información sólo ha sido aprovechada para generar un nuevo tipo de secuencias de vídeo: Vídeo de esqueleto. No obstante, al igual que se ha propuesto un clasificador basado en el procesamiento de vídeo, sería posible desarrollar otro clasificador que procesara esta información. Es por ello por lo que se ha querido dejar preparado el módulo de captura de imágenes para la inclusión de esta nueva funcionalidad mediante el almacenamiento de estos datos en ficheros XML (véase § 6.3.2.3). En el análisis de los resultados obtenidos (véase § 7) se mencionaban algunas de las causas por la que en algunas situaciones el nivel de precisión no era mayor. Una de ellas era debido a que la información proporcionada por el algoritmo NiTE daba lugar, en situaciones concretas, a confusión. Se explicaba como ejemplo de esto lo que ocurría en algunas ocasiones con el saco de boxeo empleado en la recogida de datos, donde era reconocido como si fuera una persona. Aunque la licencia bajo la que es distribuida NiTE no permite su modificación, si sería posible desarrollar alguna solución que analizara los datos proporcionados por NiTE y de este modo eliminar este tipo de información incorrecta. En el capítulo de resultados (véase § 7) se anticipaba que, aunque no era objetivo del presente proyecto, el etiquetado y segmentación automática de vídeos podría facilitar en gran medida el trabajo necesario para el funcionamiento de un sistema de reconocimiento de acciones. Es por ello por lo que se considera interesante como mejora al sistema presentado. Entrenar el sistema con datos obtenidos mediante Kinect, lo que mejoraría sensiblemente la tasa de reconocimiento. Como ya se anticipaba en el capítulo de resultados (véase § 7), el nivel de precisión proporcionada por K IN B EH R puede ser mejorado mediante la inclusión de una nueva etapa en el proceso de reconocimiento. Esta etapa consiste en proporcionar al sistema la capacidad de razonar los resultados obtenidos en la etapa de clasificación. De este modo, se podría mejorar considerablemente la tasa de acierto. Un ejemplo muy claro de ello podría ser que si por ejemplo el clasificador identifica una determinada acción como levantarse y el actor no se ha sentado en ningún momento, debería descartar este resultado. Hoy en día los dispositivos móviles incorporan una gran variedad de sensores (acelerómetros, geolocalización, etc.) que proporcionan información de forma continua: 185 Orientación, altura, posición etc. Además, en este último año se están presentando un nuevo tipo de dispositivo que es posible que revolucione este campo y que en próximos años mucha gente podría ir equipado con uno: Los dispositivos “wearables”. Este tipo de información puede resultar muy interesante en la labor de reconocimiento de acciones, proporcionando por ejemplo el ritmo cardiaco de una persona en un instante determinado. Es por este motivo por el que se cree que la incorporación de la información facilitada por estos sensores al sistema puede resultar realmente interesante en la tarea de reconocimiento de acciones. 186 Capítulo 9 Conclusions and future work This chapter describes the accomplished work during this final year project. To this end, the objectives stated at the beginning of this document are listed and checked for verification. Finally, future work are also stated in order to outline future system improvements and functionality extensions. 9.1 Achieved objectives This section analyses those objectives that were stated in chapter 3, therefore showing the way how these have been tackled and achieved. First of all, it is important recall that the main objective of this project was to develop a system for human action recognition. To this end, this project has followed a machine learning approach based on the combination of depth and intensity images used as inputs to the system. This machine learning system should also count on high level information about different types of human actions. At moment in time, it can be said that this objective has been fully achieved through the implementation of a system combining the use of a Support Vector Machines (SVM) and a Bag of Words (B OW) model. Previous chapter shows details about the system performance and accuracy achieved by this implementation. However, it should be noted that apart from the main goal, more specific goals were also stated describing more concrete system results. Next, a description of how these goals have been tackled is provided. Market analysis. This objective was intended to carry out a market analysis about different Kinect devices currently available (Kinect for Xbox 360, Kinect for Windows and Kinect second generation). Moreover, this analysis was also intended to evaluate the more appropriate device considering the project requirements. In order to accomplish this goal, a thorough analysis of the information available in the Internet, books, academic papers, and stated-of-the-art project using this technology was carried out. The main problem that was faced was the information dispersion as well as their lack of accuracy. Finally, it has to be noted that apart from technological issues, budget considerations had to also be considered. Based on these requirements, Kinect for Xbox 360 was finally chosen. 187 Analysis of available libraries. This objective was intended to analyse existing platforms and/or libraries available for the chosen Kinect device. Moreover, this objective also aimed at identifying and analysing the offered functionalites along with their strengths and weaknesses. Based on the information retrieved from this study, O PEN NI was chosen. The main reasons grounding this selection are that O PEN NI is multiplatform and open source. Also, O PEN NI supports the integration for different middleware systems. In this sense, the main obstacle that had to be overcome was the fact that the company providing the library was bought and discontinue the support services. Identification and analysis of the device collected data. This objective was intended to carry out a more technical work consisting in the identification of the different types of information provided by Kinect. An additional task was to analyse how the different information flows had to be interpreted, manipulated and processed. This task involved acquiring a solid background for image manipulation. SimpleOpenNI was used to simplify how O PEN NI and NiTE were used. This library was an excellent tool to start working with new concepts such as RGB or O PEN NI and NiTE depth images. Afterwards, the module for image capture using O PEN NI and NiTE was developed. Despite having fulfilled this goal, some troubles were experienced though successfully handled (please refer to § 6.2 and § 6.3). Among the most important ones we can mention the high memory usage or frame lost during image recording. Identification and analysis of the set of actions to be considered. This objective was intended to identify the actions that were going to be monitored and therefore recognised. After having carried out this analysis we decided to include a new type of video recordings, apart from the RGB and depth ones, as it was the actor skeleton recordings. This object was also an enabling one for later stages such as the system result analysis and interpretation. For example, we realised that some objects in the scene were considered as humans by our system. Adapting the Bag of Words Model. This objective started from the analysis of the stateof-the-art for recognising systems intended to select the most appropriate one in terms of efficiency and accuracy. Therefore, Bag of Words (B OW) model was selected and implemented in our system taking into account the feature of the project. Once these issues were handled, a module for action recognition was developed, along with an additional module for image capture. Different skills and tools were used to this end, among the most important ones we can highlight obtaining the spatio-temporal points of interest of videos using the stipdept1 . However, this was not the only challenge since a clustering process has to be undertaken afterwards. An (SVM) classifier development. This objective involves the study, analysis, and final implementation of one of the available classification techniques. This module implements 1 http://www.di.ens.fr/~laptev/index.html 188 a pattern recognition approach to support the human action monitoring and recognition. In order to accomplish this goal several approaches were studied, although BSVM 2 was finally chosen to be implemented. Finally, the system was trained and tested. Selecting and organising the set of experimental subjects. This objective is intended to provide a dataset recorded complying with a scientific methodology in order to be used for testing and evaluation purposes. Recall that different datasets were used for training and testing the system. The training system should meet several requirements such as being a public a basic dataset so that the system could be trained with basic actions. A thorough revision of the state-of-the-art was carried out in order to identify those datasets and select the one complying the system requirements. INRIA Xmas Motion Acquisition Sequences (IXMAS) [WRB06] and Hollywood [LMSR08] datasets were the most appropriate ones, being IXMAS the one chosen for the purpose of training the system. Afterwards, the system evaluation or testing was carried out using a self-designed dataset known as KinbehrDataset recorded using the module implemented in this project for image capture. To this end we had to prepare an appropriate context in which actors could naturally perform the actions the system had been trained with. Also, for future work, actors were also recording performing actions in a guided manner attending to provided commands. On the other hand, the unguided performance of actors were only based on the sole command of being themselves and staying in the room for 8 minutes. After having recorded all the videos, a process of segmentation and labelling was carried out. Finally, the system had to be tested using these videos and accuracy results were collected based on the ground truth information provided during the segmentation and labelling process. Among the main difficulties faced during the accomplishment of the objective we can mention the coordination and organisation of the volunteers participating in this study; also labelling and segmenting videos was tedious although simplified by the supported tool designed during this project. Finally, it has to be highlighted that the video recording task complies with the Spanish Law for personal data protection. Developing a graphical user interface. Due to the fact that different modules were implemented during this project, there was a risk for potential user to find the system difficult to use. In order to face this problem, it was decided to implement a graphical user interface to abstract the user from having to deal with isolated modules. This interface makes transparent the way how potential users can run the different modules as though they were one. Taking into account that most of the project was written in C++, and due to many features of Qt3 we selected this tool for implementing the graphical user interface. 2 3 http://www.csie.ntu.edu.tw/~cjlin/bsvm/ http://qt-project.org/ 189 It can be therefore concluded that all the objectives stated during the early stage of the project have been successfully addressed. 9.2 Future work The project described in this document have consisted in the implementation of a system for human action recognition based on the video analysis of RGB and depth sequences recorded using the Kinect device. However, despite having met all the objectives initially stated for this project, several improvements could be carried out in order to extend the system functionality. A list of some of these suggestions is provided underneath and might be tackled during my Master dissertation. This project has focused on the use of video sequences, however, the NiTE middleware provides a functionality to obtain precise information about the human skeleton. Articulation points are provided by this middleware. Despite having been recorded in the KinbehrDataset this information has not been exploited at all. However, the system is already prepared form capturing these type of images as well as for obtaining the articulation points in an XML file (please refer to § 6.3.2.3). During the evaluation and system analysis presented in the result chapter (please refer to § 7) we have identified several causes that lead to wrong recognition. One of them is due to the fact that several objects are considered to be humans, for instance it was quite common for the boxing bag to be considered as a human whenever it was bouncing. A possible solution to this issue could consists in the analysis of the data provided by the NiTE middleware in order to remove this incorrect information. Please note that modifying the NiTE middleware is not an option since the library license does not permit modifications. During the result chapter (please refer to § 7) we already pointed out that the automatic segmentation and label of videos were totally out of the scope of the project. However, efforts could be dedicated to this task in order to be totally autonomous during the training and recognising stage. So far, the system has been trained with RGB videos. However, it would be desirable to train and test the system using only Kinect videos. As it was foreseen during the result chapters (please refer to § 7) the accuracy level provided by K IN B EH R can be improved by including during the recognising stage an upper supervision layer in which reasoning tasks could be carried out in order to determine whether the recognised action makes sense in the supervised context. For example, if the classifier concludes that the actions taking place are the one of standing up the reasoning system could verify that the actor has previously sat. Finally, the majority of the mobile phones that can be found in the market already 190 include a great variety of sensors (ranging from accelerometers, geolocalizers, etc.). These sensors can be used to enhanced the recognition system. Moreover, wearable devices could also be of a great help in this regard. These devices could provide useful information for action recognition such as cardiac rhythm. Combining information from different sources could improve accuracy rates for action recognition. 191 ANEXOS 193 Anexo A Listados de los ejemplos con Processing A.1 Ejemplo 1 1 2 import SimpleOpenNI .∗; SimpleOpenNI kinect ; 4 5 void setup () { size (640∗2 , 480) ; kinect = new SimpleOpenNI ( this ) ; 6 7 kinect . enableDepth () ; kinect . enableRGB () ; 9 10 11 } 13 14 15 void draw () { kinect . update () ; PImage depthImage = kinect . depthImage () ; PImage rgbImage = kinect . rgbImage () ; 17 18 image ( depthImage , 0 , 0) ; image ( rgbImage , 640 , 0) ; 20 21 22 } 24 25 26 27 void mousePressed () { color c = get ( mouseX , mouseY ) ; println ( " r : " + red ( c ) + " g : " + green ( c ) + " b : " + blue ( c ) ) ; } Listado A.1: «Ejemplo 1» [Bor12] 195 A.2 Ejemplo 2 1 2 import SimpleOpenNI .∗; SimpleOpenNI kinect ; 4 5 void setup () { size (640 , 480) ; kinect = new SimpleOpenNI ( this ) ; kinect . enableDepth () ; } 6 7 8 9 11 12 13 void draw () { kinect . update () ; PImage depthImage = kinect . depthImage () ; image ( depthImage , 0 , 0) ; 15 16 17 } 19 20 21 void mousePressed () { int[] depthValues = kinect . depthMap () ; int clickPosition = mouseX + ( mouseY ∗ 640) ; int millimeters = depthValues [ clickPosition ]; float meters = millimeters /1000; 23 24 26 27 println ( " milimetros :: " + millimeters + " metros : " + meters ) ; } Listado A.2: «Ejemplo 2» [Bor12] 196 A.3 Primer ejemplo de nube de puntos 1 2 3 import processing . opengl .∗; import SimpleOpenNI .∗; SimpleOpenNI kinect ; 5 void setup () { size (1024 , 768 , OPENGL ) ; kinect = new SimpleOpenNI ( this ) ; kinect . enableDepth () ; } 6 7 8 9 11 12 void draw () { background (0) ; 14 kinect . update () ; 16 17 translate ( width /2 , height /2 , −1000); rotateX ( radians (180) ) ; 20 stroke (255) ; 22 23 PVector [] depthPoints = kinect . depthM apReal World () ; for(int i = 0; i < depthPoints . length ; i ++) { PVector currentPoint = depthPoints [ i ]; point ( currentPoint .x , currentPoint .y , currentPoint . z ) ; } 24 25 26 27 } Listado A.3: «Primer ejemplo Nube de puntos» [Bor12] 197 A.4 Primer ejemplo de nube de puntos con movimiento 1 2 import processing . opengl .∗; import SimpleOpenNI .∗; 4 SimpleOpenNI kinect ; 7 float rotation = 0; 12 13 void setup () { size (1024 , 768 , OPENGL ) ; kinect = new SimpleOpenNI ( this ) ; kinect . enableDepth () ; } 15 16 17 void draw () { background (0) ; kinect . update () ; 9 10 11 19 20 translate ( width /2 , height /2 , −1000); rotateX ( radians (180) ) ; 22 translate (0 , 0 , 1000) ; 24 25 rotateY ( radians ( rotation ) ) ; rotation ++; 27 stroke (255) ; 29 PVector [] depthPoints = kinect . depthM apReal World () ; 31 32 33 34 35 for (int i = 0; i < depthPoints . length ; i +=10) { PVector currentPoint = depthPoints [ i ]; point ( currentPoint .x , currentPoint .y , currentPoint . z ) ; } } Listado A.4: «Primer ejemplo Nube de puntos con movimiento» [Bor12] 198 A.5 Primer ejemplo de nube de puntos a color 1 2 import processing . opengl .∗; import SimpleOpenNI .∗; 4 5 SimpleOpenNI kinect ; float rotation = 0; 12 void setup () { size (1024 , 768 , OPENGL ) ; kinect = new SimpleOpenNI ( this ) ; kinect . enableDepth () ; kinect . enableRGB () ; kinect . a l t e r n a t i v e V i e w P o i n t D e p t h T o I m a g e () ; 14 } 16 17 void draw () { background (0) ; kinect . update () ; PImage rgbImage = kinect . rgbImage () ; 7 8 9 10 11 18 19 translate ( width /2 , height /2 , −250); rotateX ( radians (180) ) ; translate (0 , 0 , 1000) ; rotateY ( radians ( rotation ) ) ; rotation ++; 21 22 23 24 25 PVector [] depthPoints = kinect . depthM apReal World () ; for (int i = 0; i < depthPoints . length ; i +=1) { PVector currentPoint = depthPoints [ i ]; stroke ( rgbImage . pixels [ i ]) ; point ( currentPoint .x , currentPoint .y , currentPoint . z ) ; } 27 28 29 30 31 32 33 } Listado A.5: «Primer ejemplo Nube de puntos a color» [Bor12] 199 A.6 Dibujando con Kinect 1 2 import SimpleOpenNI .∗; SimpleOpenNI kinect ; 4 5 6 int closestValue ; int closestX ; int closestY ; 8 float lastX ; float lastY ; 9 15 void setup () { size (640 , 480) ; kinect = new SimpleOpenNI ( this ) ; kinect . enableDepth () ; 17 18 } 11 12 13 14 20 21 22 background (0) ; void draw () { closestValue = 8000; 24 kinect . update () ; 26 int[] depthValues = kinect . depthMap () ; 28 29 for(int y = 0; y < 480; y ++) { for(int x = 0; x < 640; x ++) { 31 int reversedX = 640−x−1; 33 34 int i = reversedX + y ∗ 640; int cur rentDe pthVal ue = depthValues [ i ]; 36 if( curre ntDept hValue > 610 && curr entDep thVal ue < 1525 && cur rentDe pthVal ue < closestValue ) { closestValue = c urrent DepthV alue ; closestX = x ; closestY = y ; 38 39 40 41 42 43 } } } 45 46 float interpolatedX = lerp ( lastX , closestX , 0.3 f ) ; float interpolatedY = lerp ( lastY , closestY , 0.3 f ) ; 48 stroke (255 ,0 ,0) ; 50 strokeWeight (3) ; 52 53 54 line ( lastX , lastY , interpolatedX , interpolatedY ) ; lastX = interpolatedX ; lastY = interpolatedY ; 200 56 } 58 59 60 void mousePressed () { save ( " drawing . png " ) ; background (0) ; } 61 Listado A.6: «Dibujando con Kinect» [Bor12] 201 A.7 Álbum de fotos 1 2 import SimpleOpenNI .∗; SimpleOpenNI kinect ; 4 5 6 int closestValue ; int closestX ; int closestY ; 8 9 float lastX ; float lastY ; 11 12 13 14 15 17 18 19 20 21 23 24 25 26 27 29 30 31 32 34 35 36 37 38 float image1X ; float image1Y ; float image1scale ; int image1width = 100; int image1height = 100; float image2X ; float image2Y ; float image2scale ; int image2width = 100; int image2height = 100; float image3X ; float image3Y ; float image3scale ; int image3width = 100; int image3height = 100; int currentImage = 1; PImage image1 ; PImage image2 ; PImage image3 ; void setup () { size (640∗2 , 480) ; kinect = new SimpleOpenNI ( this ) ; kinect . enableDepth () ; image1 = loadImage ( " image1 . jpg " ) ; image2 = loadImage ( " image2 . jpg " ) ; image3 = loadImage ( " image3 . jpg " ) ; 40 41 42 43 } 45 46 void draw () { background (0) ; 48 closestValue = 8000; 50 kinect . update () ; 52 int[] depthValues = kinect . depthMap () ; 54 for(int y = 0; y < 480; y ++) { for(int x = 0; x < 640; x ++) { 55 202 56 57 58 int reversedX = 640−x−1; int i = reversedX + y ∗ 640; int cur rentDe pthVal ue = depthValues [ i ]; 60 if( curre ntDept hValue > 610 && curr entDep thVal ue < 1525 && cur rentDe pthVal ue < closestValue ) { closestValue = c urrent Depth Value ; closestX = x ; closestY = y ; } 61 62 63 64 65 66 } 68 69 float interpolatedX = lerp ( lastX , closestX , 0.3) ; float interpolatedY = lerp ( lastY , closestY , 0.3) ; 71 72 switch( currentImage ) { case 1: image1X = interpolatedX ; image1Y = interpolatedY ; } 73 74 image1scale = map ( closestValue , 610 ,1525 , 0 , 4) ; break; case 2: image2X = interpolatedX ; image2Y = interpolatedY ; image2scale = map ( closestValue , 610 ,1525 , 0 , 4) ; break; case 3: image3X = interpolatedX ; image3Y = interpolatedY ; image3scale = map ( closestValue , 610 ,1525 , 0 , 4) ; break; 76 77 78 79 80 81 82 83 84 85 86 87 88 } image ( image1 , image1X , image1Y , image1width ∗ image1scale , image1height ∗ image1scale ) ; image ( image2 , image2X , image2Y , image2width ∗ image2scale , image2height ∗ image2scale ) ; image ( image3 , image3X , image3Y , image3width ∗ image3scale , image3height ∗ image3scale ) ; 90 91 92 lastX = interpolatedX ; lastY = interpolatedY ; 94 95 97 98 100 101 102 103 104 105 106 image ( kinect . depthImage () , 640 , 0) ; } void mousePressed () { currentImage ++; if( currentImage > 3) { currentImage = 1; } println ( currentImage ) ; } Listado A.7: «Álbum de fotos» [Bor12] 203 A.8 Batería musical 1 2 3 4 5 6 7 8 9 12 13 14 15 16 17 class Hotpoint { PVector center ; color fillColor ; color strokeColor ; int size ; int pointsIncluded ; int maxPoints ; boolean wasJustHit ; int threshold ; Hotpoint (float centerX , float centerY , float centerZ , int boxSize ) { center = new PVector ( centerX , centerY , centerZ ) ; size = boxSize ; pointsIncluded = 0; maxPoints = 1000; threshold = 0; fillColor = strokeColor = color ( random (255) , random (255) , random (255) ) ; 19 20 } 22 23 24 void setThreshold ( int newThreshold ) { threshold = newThreshold ; } 26 27 28 void setMaxPoints (int newMaxPoints ) { maxPoints = newMaxPoints ; } 30 31 32 void setColor (float red , float blue , float green ) { fillColor = strokeColor = color ( red , blue , green ) ; } 34 35 boolean check ( PVector point ) { boolean result = false ; if ( point . x > center . x − size /2 && point . x < center . x + size /2) { if ( point . y > center . y − size /2 && point . y < center . y + size /2) { if ( point . z > center . z − size /2 && point . z < center . z + size /2) { result = true ; pointsIncluded ++; } } } 37 38 39 40 41 42 43 44 return result ; 46 47 } 49 50 51 void draw () { pushMatrix () ; translate ( center .x , center .y , center . z ) ; 204 fill ( red ( fillColor ) , blue ( fillColor ) , green ( fillColor ) , 255 ∗ percentIncluded () ) ; stroke ( red ( strokeColor ) , blue ( strokeColor ) , green ( strokeColor ) , 255) ; box ( size ) ; popMatrix () ; 53 54 55 56 57 } 59 60 61 float percentIncluded () { return map ( pointsIncluded , 0 , maxPoints , 0 , 1) ; } 64 65 66 boolean currentlyHit () { return ( pointsIncluded > threshold ) ; } 69 70 71 boolean isHit () { return currentlyHit () && ! wasJustHit ; } 73 74 void clear () { wasJustHit = currentlyHit () ; pointsIncluded = 0; } 75 76 77 } Listado A.8: Clase Hotpoint de la aplicación «Batería musical» [Bor12] 2 3 import processing . opengl .∗; import SimpleOpenNI .∗; import ddf . minim .∗; 5 SimpleOpenNI kinect ; 7 float rotation = 0; 1 9 10 11 Minim minim ; AudioPlayer kick ; AudioPlayer snare ; 13 14 Hotpoint snareTrigger ; Hotpoint kickTrigger ; 16 float s = 1; 18 void setup () { size (1024 , 768 , OPENGL ) ; kinect = new SimpleOpenNI ( this ) ; kinect . enableDepth () ; 19 20 21 25 minim = new Minim ( this ) ; snare = minim . loadFile ( " hat . wav " ) ; kick = minim . loadFile ( " kick . wav " ) ; 27 snareTrigger = new Hotpoint (200 , −400, 700 , 250) ; 23 24 205 kickTrigger = new Hotpoint (−200, −400, 700 , 250) ; 28 30 } 32 33 void draw () { background (0) ; kinect . update () ; 34 36 37 translate ( width /2 , height /2 , −1000); rotateX ( radians (180) ) ; 39 40 translate (0 , 0 , 1400) ; rotateY ( radians ( map ( mouseX , 0 , width , −180, 180) ) ) ; 42 43 translate (0 , 0 , s ∗ −1000) ; scale ( s ) ; 46 stroke (255) ; 48 PVector [] depthPoints = kinect . depthM apReal World () ; 50 51 for (int i = 0; i < depthPoints . length ; i +=10) { PVector currentPoint = depthPoints [ i ]; snareTrigger . check ( currentPoint ) ; kickTrigger . check ( currentPoint ) ; 53 54 point ( currentPoint .x , currentPoint .y , currentPoint . z ) ; 56 57 } 59 println ( snareTrigger . pointsIncluded ) ; 61 62 63 if( snareTrigger . isHit () ) { snare . play () ; } 65 66 67 68 if(! snare . isPlaying () ) { snare . rewind () ; snare . pause () ; } 70 71 72 if ( kickTrigger . isHit () ) { kick . play () ; } 74 75 76 77 if(! kick . isPlaying () ) { kick . rewind () ; kick . pause () ; } 79 80 snareTrigger . draw () ; snareTrigger . clear () ; 82 83 84 kickTrigger . draw () ; kickTrigger . clear () ; } 206 86 87 88 89 void stop () { kick . close () ; snare . close () ; minim . stop () ; super . stop () ; 91 92 93 95 96 97 98 99 100 101 102 } void keyPressed () { if ( keyCode == 38) { s = s + 0.01; } if ( keyCode == 40) { s = s − 0.01; } } Listado A.9: Clase principal de la aplicación «Batería musical» [Bor12] 207 Anexo B Módulo de captura de imágenes B.1 Diseño definitivo B.1.1 Modelo de clases definitivo Figura B.1: Diagrama de clases. 209 B.1.2 Estructura de directorio definitivo Figura B.2: Estructura de directorios. 210 B.1.3 Modelo de flujo de la ejecución Figura B.3: Modelo de flujo de la ejecución concurrente. 211 Anexo C Formulario de consentimiento En el siguiente anexo se presenta el formulario de consentimiento que fue empleado para recoger el consentimiento de los actores en la realización de la recogida de datos, que posteriormente fueron utilizados para efectuar las pruebas del sistema desarrollado (véase § 7). Se encuentra dividido en dos partes: Información acerca del estudio y condiciones que se estarían aceptando al dar el consentimiento. • Información general. • Sobre el estudio. Formulario de aceptación. 213 Escuela Superior de Informática de Ciudad Real ÉTICA DE LA INVESTIGACIÓN: FORMULARIO DE CONSENTIMIENTO DE LA MUESTRA Título del Proyecto: KinBehR (KINect for human BEHaviour Recognition) Nombre del investigador: Rubén Cantarero Navarro. Dirección de contacto del investigador: Ruben.Cantarero@alu.uclm.es Nombre del director del proyecto: María José Santofimia Romero. Dirección de contacto del director del proyecto: MariaJose.Santofimia@uclm.es SECCIÓN I: Información general 1. Le estamos pidiendo que participe en un estudio. 2. Usted no tiene que participar en el estudio. 3. Si dice que sí, puede dejar de participar en el estudio en cualquier momento. 4. Por favor tome todo el tiempo que necesite para decidir. SECCIÓN II: Sobre el estudio 1. ¿Para qué firma este documento?: Lo firma para poder participar en el estudio. 2. ¿Por qué se está haciendo este estudio de investigación?. Se trata de un estudio de investigación que pretende desarrollar un sistema que combine el análisis de imágenes de intensidad y profundidad con una base de conocimiento donde se contenga información de alto nivel sobre acciones humanas. Para ello, será necesario generar un dataset en el que se pueda asegurar que las personas están realizando las acciones con las que se ha entrenado el sistema pero de una manera racional, es decir, motivada con un objetivo concreto. Por lo tanto, también será objetivo de este proyecto la generación de dicho dataset a partir de la grabación y etiquetado de escenarios concretos, donde se realice al menos un número relevante de las acciones con las que el sistema haya sido entrenado. Dichas acciones dependerán de las acciones disponibles en los datasets públicos ya que, utilizando un dataset para entrenar el sistema distinto del utilizado para su evaluación, se asegurará la validez del sistema propuesto. 3. ¿Qué pasa si digo “sí, quiero participar en el estudio”?. si dice que sí: a) Realizaremos una grabación de vídeo mediante un dispositivo Kinect. b) Le daremos un formulario con preguntas para que usted conteste. c) Si quiere, podemos leerle las preguntas en voz alta y escribir sus respuestas en el formulario. d) Estas preguntas no tienen respuestas correctas o incorrectas. Puede saltar cualquier pregunta si no quiere contestarla. 4. ¿Cuánto tiempo tomará el estudio?. El estudio tomará alrededor de veinte minutos de su Escuela Superior de Informática de Ciudad Real tiempo. 5. ¿Qué pasa si digo “no quiero participar en el estudio”?. Nadie le tratará de manera diferente. A usted no se le penalizará. Aunque no recibirá el beneficio de estar en el estudio, no perderá otro beneficio. 6. ¿Qué pasa si digo que sí, pero cambio de opinión más tarde?. Usted puede dejar de participar en el estudio en cualquier momento. A usted no se le penalizará. Aunque no recibirá el beneficio de estar en el estudio, no perderá otro beneficio. 7. ¿Quién verá mis respuestas?. Las únicas personas autorizadas para ver sus respuestas son las que trabajan en el estudio y las que se aseguran de que éste se realice de ,manera correcta. Sus respuestas a la encuesta, su información, y una copia firmada de este documento se mantendrá bajo llave en nuestros archivos. Cuando compartamos los resultados del estudio, no incluiremos su nombre. Haremos todo lo posible para que nadie fuera del estudio sepa que usted participó en él. 8. ¿Quién verá mis grabaciones de vídeo?. Las únicas personas autorizadas para ver sus grabaciones de vídeo son las que trabajan en el estudio y las que se aseguran de que éste se realice de ,manera correcta. Estos ficheros se mantendrán bajo llave en nuestros archivos. Cuando compartamos los resultados del estudio, no incluiremos su nombre. Haremos todo lo posible para que nadie fuera del estudio sepa que usted participó en él. 9. ¿Cómo se usará y compartirá esta información?. a) Usaremos su información y su grabación sólo para el estudio que se describe en este documento. b) Podemos compartir su malformación con otros miembros de la comunidad investigadora. c) Haremos todo lo posible para asegurarnos de que su información permanmezca privada. Sin embargo, si compartimos información con personas que no estén obligadas a cumplir con la Regla de Privacidad, la información dejará de estar protegida por esta Regla de Privacidad. Díganos si tiene alguna duda al respecto. 10. ¿Por cuanto tiempo se usará mi información y mi grabación?. Durante la duración del proyecto. No usaremos ni compartiremos su información una vez terminado el estudio. 11.¿Me costará algo participar en el estudio?. No. 12. Participar en el estudio, ¿me ayudará de alguna manera?. Participar en este estudio no le ayudará, pero podría ayudar al desarrollo y avance en el I+D+I. 13. 14. ¿Me pagarán por mi tiempo?. No. ¿Qué debo hacer si tengo preguntas?. Por favor, contacte con los miembros del proyecto, sí: a) Tiene alguna pregunta sobre el estudio. b) Tiene preguntas sobre sus derechos. c) Cree que se ha lesionado de alguna manera por participar en este estudio. Escuela Superior de Informática de Ciudad Real 15. ¿Se hacen cargo los miembros del proyecto en caso de que me produzca algún daño?. No. 16. ¿Tengo que firmar este documento?. No. Fírmelo solamente si desea participar en el estudio. 17. ¿Qué debo hacer si quiero participar en el estudio?. Tiene que firmar este documento. Le entregaremos una copia. Al participar en este documento esta diciendo que: a) Está de acuerdo con participar en el estudio. b) Le hemos explicado la información que contiene este documento y hemos contestado todas sus preguntas. Escuela Superior de Informática de Ciudad Real ÉTICA DE LA INVESTIGACIÓN: FORMULARIO DE CONSENTIMIENTO DE LA MUESTRA Título del Proyecto: KinBehR (KINect for human BEHaviour Recognition) Nombre del investigador: Rubén Cantarero Navarro. Dirección de contacto del investigador: Ruben.Cantarero@alu.uclm.es Nombre del director del proyecto: María José Santofimia Romero. Dirección de contacto del director del proyecto: MariaJose.Santofimia@uclm.es A cumplimentar por el participante 1. Sexo: Hombre / Mujer 2. Edad: …...... 3. Altura: …..... 4. Peso: …..... Condiciones de aceptación a) Confirmo que he leído y entendido la hoja de información para el estudio anterior y he tenido la oportunidad de hacer preguntas. b) Entiendo que mi participación es voluntaria y que soy libre de retirarme en cualquier momento, sin dar razón. c) Estoy de acuerdo en participar en el estudio anterior. d) Estoy de acuerdo en que la entrevista este siendo grabada en vídeo. e) Estoy de acuerdo en el uso de comillas anónimas en las publicaciones Escuela Superior de Informática de Ciudad Real A cumplimentar por el investigador 1. Nombre de actor: ................................................................................................................................... 2. Hora de comienzo de la grabación: …................................................................................................. 3. Hora de finalización de la grabación: ….............................................................................................. 4. ¿El participante lleva gafas durante la grabación?: Sí / No 5. ¿Que ropa lleva el participante durante la prueba?: …..................................................................... ….............................................................................................................................................................. .................................................................................................................................................................. .................................................................................................................................................................. .................................................................................................................................................................. 6. Observaciones: ...................................................................................................................................... ….............................................................................................................................................................. .................................................................................................................................................................. .................................................................................................................................................................. .................................................................................................................................................................. 7. Incidencias: ............................................................................................................................................ ….............................................................................................................................................................. .................................................................................................................................................................. .................................................................................................................................................................. .................................................................................................................................................................. Nombre del Participante Fecha Firma Nombre del Investigador Fecha Firma Anexo D Conclusión personal Con la realización del TFG me ha sido posible afianzar y ampliar muchos de los conocimientos adquiridos durante estos últimos cuatro años. Esto se debe a que, gracias a este proyecto, he tenido una oportunidad inmejorable para poner en práctica una gran parte de los conocimientos aprendidos durante estos años. En mi opinión, esto representa un paso crucial en la formación de un ingeniero, ya que no sólo se pone de manifiesto los conocimientos y habilidades de las que dispone, sino que también tiene la oportunidad de mostrar su capacidad de adquirir nuevos conocimientos para resolver un problema o enfrentarse a las dificultades que puedan surgir durante un proyecto de ciertas dimensiones. Gracias a este proyecto se han adquirido nuevos conocimientos que o bien por la elección de asignaturas o por cualquier otro motivo no se habían adquirido y desarrollado durante la carrera. Entre estos conocimientos cabe destacar el aprendizaje y puesta en práctica de una nueva metodología de desarrollo, con todo lo que esto supone. Además, se han adquirido conocimientos que a la larga serán muy valiosos en mi vida profesional. Ejemplo de ellos pueden ser el aprendizaje del lenguaje C++, PERL, o el trabajar con una disciplina de la informática prácticamente nueva para mi: la visión por computador. Todo esto ha dado lugar a una serie de retos que se han tenido que ir salvando a lo largo del proyecto. Uno de los más duros ha sido enfrentarse a materias totalmente nuevas para mí, donde la mayoría del trabajo realizado consiste en la investigación y aplicación de nuevos métodos para la resolución de problemas que están en pleno auge, como es el reconocimiento de acciones. Otro reto especialmente duro ha sido la elaboración de la presente memoria, ya que es la primera vez que he tenido que afrontar la elaboración de una documentación tan rigurosa donde toda palabra y referencia debe estar justificada. Por último, destacar que con la creación de K IN B EH R no se pretende proporcionar una solución definitiva a un problema tan importante como el reconocimiento de acciones. Simplemente se ha pretendido mostrar una posible forma en la que este complicado problema puede ser solucionado, dando un paso más hacia la solución del problema del reconocimiento de acciones humanas. 219 Referencias [AA01] Anjum Ali y J. K. Aggarwal. Segmentation and Recognition of Continuous Human Activity. En IEEE Workshop on Detection and Recognition of Events in Video, páginas 28–, 2001. [AGO+ 12] Davide Anguita, Alessandro Ghio, Luca Oneto, Xavier Parra, y Jorge L. Reyes-Ortiz. Human Activity Recognition on Smartphones Using a Multiclass Hardware-friendly Support Vector Machine. En Proceedings of the 4th International Conference on Ambient Assisted Living and Home Care, IWAAL’12, páginas 216–223. Springer-Verlag, 2012. [AL08] Mohiuddin Ahmad y Seong-Whan Lee. Human Action Recognition Using Shape and CLG-motion Flow from Multi-view Image Sequences. Pattern Recogn., 41(7):2237–2252, 2008. [ann14] ANN: A Library for Approximate Nearest Neighbor Searching. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.cs.umd.edu/ ~mount/ANN/. [ASRW02] Pekka Abrahamsson, Outi Salo, Jussi Ronkainen, y Juhani Warsta. Agile software development methods - Review and analysis, 2002. [BFB94] J. L. Barron, D. J. Fleet, y S. S. Beauchemin. Performance of Optical Flow Techniques. Int. J. Comput. Vision, 12(1):43–77, 1994. [Bor12] Greg Borenstein. Making Things See: 3D vision with Kinect, Processing, Arduino, and MakerBot. O’Reilly Media, 2012. [bsv14] BSVM. Website, 2014. Última consulta: 17 Marzo 2014. url: http:// www.csie.ntu.edu.tw/~cjlin/bsvm/. [Cat12] David Catuhe. Programming with the Kinect for Windows Software Development Kit. Developer reference. Microsoft Press, 2012. [CDF+ 04] Gabriella Csurka, Christopher R. Dance, Lixin Fan, Jutta Willamowski, y Cédric Bray. Visual categorization with bags of keypoints. En In Workshop on Statistical Learning in Computer Vision, ECCV, páginas 1–22, 2004. 221 [con97] Learning Parameterized Models of Image Motion. En Proceedings of the 1997 Conference on Computer Vision and Pattern Recognition (CVPR ’97), CVPR ’97, páginas 561–567. IEEE Computer Society, 1997. [CSTL02] Nello Cristianini, John Shawe-Taylor, y Huma Lodhi. Latent Semantic Kernels. J. Intell. Inf. Syst., 18(2-3):127–152, 2002. [Dav12] Andrew Davison. Kinect Open Source Programming Secrets : Hacking the Kinect with OpenNI, NITE, and Java: Hacking the Kinect with OpenNI, NITE, and Java. Mcgraw-hill, 2012. [dia14] Apps/Dia - GNOME Wiki! Website, 2014. Última consulta: 17 Marzo 2014. url: https://wiki.gnome.org/Apps/Dia/. [ema14] GENU Operating Sytem. GNU Emacs. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.gnu.org/software/emacs/. [Fal13] Soroush Falahati. OpenNI Cookbook. Packt Publishing, 2013. [FCTL10] Chin-Hsien Fang, Ju-Chin Chen, Chien-Chung Tseng, y Jenn-JierJames Lien. Human Action Recognition Using Spatio-temporal Classification. En Hongbin Zha, Rin-ichiro Taniguchi, y Stephen Maybank, editors, Computer Vision – ACCV 2009, volume 5995 of Lecture Notes in Computer Science, páginas 98–109. Springer Berlin Heidelberg, 2010. [ffm14] FFmpeg. Website, 2014. Última consulta: 17 Marzo 2014. url: http:// www.ffmpeg.org/. [FG87] M. A. Föstner y E. Gülch. A Fast Operator for Detection and Precise Location of Distinct Points, Corners and Centers of Circular Features. En ISPRS Intercommission Workshop, Interlaken, Switzerland, 1987. [FK03] Randima Fernando y Mark J. Kilgard. The Cg Tutorial: The Definitive Guide to Programmable Real-Time Graphics. Addison-Wesley Longman Publishing Co., Inc., 2003. [gcc14] Free Software Foundation. Using GCC: The GNU Compiler Collection, 2010. Website, 2014. Última consulta: 17 Marzo 2014. url: http://gcc. gnu.org/onlinedocs/gcc/. [gim14] GIMP - The GNU Image Manipulation Program. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.gimp.org/. 222 [glu14] GLUT - The OpenGL Utility Toolkit. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.opengl.org/resources/libraries/ glut/. [HL02a] Chih-Wei Hsu y Chih-Jen Lin. A Comparison of Methods for Multiclass Support Vector Machines. Trans. Neur. Netw., 13(2):415–425, 2002. [HL02b] Chih-Wei Hsu y Chih-Jen Lin. A Simple Decomposition Method for Support Vector Machines. Mach. Learn., 46(1-3):291–314, 2002. [HS88] Chris Harris y Mike Stephens. A combined corner and edge detector. En In Proc. of Fourth Alvey Vision Conference, páginas 147–151, 1988. [HVC00] Daniela Hall, Vincent Colin de Verdière, y James L. Crowley. Object Recognition Using Coloured Receptive Fields. En Proceedings of the 6th European Conference on Computer Vision-Part I, ECCV ’00, páginas 164– 177. Springer-Verlag, 2000. [IB98] Michael Isard y Andrew Blake. CONDENSATION&Mdash;Conditional Density Propagation for Visual Tracking. Int. J. Comput. Vision, 29(1):5– 28, 1998. [Jan12] Abhijit Jana. Kinect for Windows SDK Programming Guide. Community experience distilled. Packt Publishing, Limited, 2012. [Joa98a] Thorsten Joachims. Text Categorization with Suport Vector Machines: Learning with Many Relevant Features. En Proceedings of the 10th European Conference on Machine Learning, ECML ’98, páginas 137–142, London, UK, UK, 1998. Springer-Verlag. [Joa98b] Thorsten Joachims. Text Categorization with Support Vector Machines: Learning with Many Relevant Features, 1998. [KB10] Mohamed-Bécha Kaâniche y François Bremond. Gesture Recognition by Learning Local Motion Signatures. En CVPR 2010 : IEEE Conference on Computer Vision and Pattern Recognition, San Franscico, CA, United States, 2010. IEEE Computer Society Press. [KBC+ 12] Jeff Kramer, Nicolas Burrus, Daniel Herrera C., Florian Echtler, y Matt Parker. Hacking the Kinect. Apress, edición 1st, 2012. [KHP11] Sean Kean, Jonathan Hall, y Phoenix Perry. Meet the Kinect: An Introduction to Programming Natural User Interfaces. Apressus Series. Apress, 2011. 223 [Kil96] Mark J. Kilgard. OpenGL Programming for the X Window System. Addison Wesley Longman Publishing Co., Inc., 1996. [KJG+ 11] H. Kuehne, H. Jhuang, E. Garrote, T. Poggio, y T. Serre. HMDB: A Large Video Database for Human Motion Recognition. En Proceedings of the 2011 International Conference on Computer Vision, ICCV ’11, páginas 2556–2563. IEEE Computer Society, 2011. [KMN+ 02] Tapas Kanungo, David M. Mount, Nathan S. Netanyahu, Christine D. Piatko, Ruth Silverman, y Angela Y. Wu. An Efficient k-Means Clustering Algorithm: Analysis and Implementation. IEEE Trans. Pattern Anal. Mach. Intell., 24(7):881–892, 2002. [Lap05] Ivan Laptev. On Space-Time Interest Points. Int. J. Comput. Vision, 64(23):107–123, 2005. [LAS08] Jingen Liu, Saad Ali, y Mubarak Shah. Recognizing human actions using multiple features. 2013 IEEE Conference on Computer Vision and Pattern Recognition, 0:1–8, 2008. [LMN10] MichałLewandowski, Dimitrios Makris, y Jean-Christophe Nebel. View and Style-independent Action Manifolds for Human Activity Recognition. En Proceedings of the 11th European Conference on Computer Vision: Part VI, ECCV’10, páginas 547–560. Springer-Verlag, 2010. [LMSR08] Ivan Laptev, Marcin Marszalek, Cordelia Schmid, y Benjamin Rozenfeld. Learning realistic human actions from movies. 2013 IEEE Conference on Computer Vision and Pattern Recognition, 0:1–8, 2008. [Low99] David Lowe. Object Recognition from Local Scale-Invariant Features. En Proceedings of the International Conference on Computer Vision-Volume 2 - Volume 2, ICCV ’99, páginas 1150–. IEEE Computer Society, 1999. [LP07] Ivan Laptev y Patrick Pérez. Retrieving actions in movies. En IEEE 11th International Conference on Computer Vision, ICCV 2007, Rio de Janeiro, Brazil, October 14-20, 2007, páginas 1–8. IEEE, 2007. [LSST+ 02] Huma Lodhi, Craig Saunders, John Shawe-Taylor, Nello Cristianini, y Chris Watkins. Text Classification Using String Kernels. J. Mach. Learn. Res., 2:419–444, 2002. [Mar03] Robert Cecil Martin. Agile Software Development: Principles, Patterns, and Practices. Prentice Hall PTR, 2003. 224 [MCOUHJ+ 09] Francisco Martinez-Contreras, Carlos Orrite-Urunuela, Elias HerreroJaraba, Hossein Ragheb, y Sergio A. Velastin. Recognizing Human Actions Using Silhouette-based HMM. 2013 10th IEEE International Conference on Advanced Video and Signal Based Surveillance, 0:43–48, 2009. [MDD10] Nils Brede Moe, Torgeir Dingsøyr, y Tore Dybå. A Teamwork Model for Understanding an Agile Team: A Case Study of a Scrum Project. Inf. Softw. Technol., 52(5):480–491, 2010. [MDRSN13] Jesús Martínez Del Rincón, Maria J. Santofimia, y Jean-Christophe Nebel. Common-sense Reasoning for Human Action Recognition. Pattern Recogn. Lett., 34(15):1849–1860, 2013. [mer14] Mercurial: Work easier, Work faster, 2014. Website, 2014. Última consulta: 17 Marzo 2014. url: http://mercurial.selenic.com/. [Mil12] Rob Miles. Learn the Kinect API. Microsoft Press Series. Microsoft Press, 2012. [NLT+ 11] Jean-Christophe Nebel, MichałLewandowski, Jérôme Thévenon, Francisco Martínez, y Sergio Velastin. Are Current Monocular Computer Vision Systems for Human Action Recognition Suitable for Visual Surveillance Applications? En Proceedings of the 7th International Conference on Advances in Visual Computing - Volume Part II, ISVC’11, páginas 290–299. Springer-Verlag, 2011. [ope14] OpenCV. Website, 2014. Última consulta: 17 Marzo 2014. url: http:// opencv.org/. [pro14] Processing 2. Website, 2014. Última consulta: 17 Marzo 2014. url: http: //processing.org/. [qt14] Qt Project. Website, 2014. Última consulta: 17 Marzo 2014. url: http:// qt-project.org/. [RA00] Yong Rui y P. Anandan. Segmenting Visual Actions Based on SpatioTemporal Motion Patterns. En CVPR, páginas 1111–1118. IEEE Computer Society, 2000. [SB95] S. m. Smith y J. m. Brady. ASSET-2: Real-Time Motion Segmentation and Shape Tracking. IEEE Trans. Pattern Anal. Mach. Intell., 17(8):814–820, 1995. [SB01] Ken Schwaber y Mike Beedle. Agile Software Development with Scrum. Prentice Hall PTR, edición 1st, 2001. 225 [SB11] Ivan Sipiran y Benjamin Bustos. Harris 3D: A Robust Extension of the Harris Operator for Interest Point Detection on 3D Meshes. Vis. Comput., 27(11):963–976, 2011. [sim14] OpenNI library for Processing. Website, 2014. Última consulta: 17 Marzo 2014. url: http://code.google.com/p/simple-openni/. [SM97] Cordelia Schmid y Roger Mohr. Local Grayvalue Invariants for Image Retrieval. IEEE Trans. Pattern Anal. Mach. Intell., 19(5):530–535, 1997. [SMB00] Cordelia Schmid, Roger Mohr, y Christian Bauckhage. Evaluation of Interest Point Detectors. Int. J. Comput. Vision, 37(2):151–172, 2000. [SMS04] Richard M. Stallman, Roland McGrath, y Paul D. Smith. GNU Make: A Program for Directing Recompilation, for Version 3.81. Free Software Foundation, 2004. [SMS07] Masamichi Shimosaka, Taketoshi Mori, y Tomomasa Sato. Robust Action Recognition and Segmentation with Multi-Task Conditional Random Fields. En ICRA, páginas 3780–3786. IEEE, 2007. [sti14] Space-Time Interest Points. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.di.ens.fr/~laptev/interestpoints.html. [Str00] Bjarne Stroustrup. The C++ Programming Language. Addison-Wesley Longman Publishing Co., Inc., edición 3rd, 2000. [SWCS08] Qinfeng Shi, Li Wang, Li Cheng, y Alexander J. Smola. Discriminative human action segmentation and recognition using semi-Markov model. En CVPR. IEEE Computer Society, 2008. [Tal13] Nicola Louise Cecilia Talbot. Using LaTeX to Write a PhD Thesis. Dickimaw Books, 2013. [TK02] Simon Tong y Daphne Koller. Support Vector Machine Active Learning with Applications to Text Classification. J. Mach. Learn. Res., 2:45–66, 2002. [TV98] Emanuele Trucco y Alessandro Verri. Introductory Techniques for 3-D Computer Vision. Prentice Hall PTR, 1998. [VBC10] Roberto Vezzani, Davide Baltieri, y Rita Cucchiara. HMM Based Action Recognition with Projection Histogram Features. En Proceedings of the 20th International Conference on Recognizing Patterns in Signals, Speech, Images, and Videos, ICPR’10, páginas 286–293. Springer-Verlag, 2010. 226 [WA12] Jarrett Webb y James Ashley. Beginning Kinect Programming with the Microsoft Kinect SDK. Apressus Series. Apress, 2012. [wbI14] IXMAS: 4d-repository :: Public. Website, 2014. Última consulta: 17 Marzo 2014. url: http://4drepository.inrialpes.fr/public/viewgroup/ 6. [WBR07] Daniel Weinland, Edmond Boyer, y Remi Ronfard. Action Recognition from Arbitrary Views using 3D Exemplars. En ICCV 2007 - 11th IEEE International Conference on Computer Vision, páginas 1–7, Rio de Janeiro, Brésil, 2007. IEEE. [wbT14a] TEDCAS: Interfaces de interacción natural para la salud. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.tedcas.com/es. [wbT14b] Teo Park, media artist. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.teopark.com/. [wbU14] Ubi Interactive. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.ubi-interactive.com/. [wbV14] Virtualrehab: Virtual Rehabilitation System. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.virtualrehab.info/es/. [web14a] 3D Mesh Generation with KScan3D software and Kinect. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.kscan3d.com/. [web14b] 3D Virtual fitting dressing room/mirror. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.fitnect.hu. [web14c] Android hardware/software design using virtual prototypes Part 3: Integrating Android’s HAL. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.embedded. com/design/prototyping-and-development/4401419/ Android-hardware-software-design-using-virtual-/ prototypes---Part-3--Integrating-Android-s-HAL. [web14d] ASUS: Xtion PRO. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.asus.com/Multimedia/Xtion PRO/. [web14e] Data Center Software User Manual. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.totalphase.com/support/articles/ 200424386-Data-Center-Software-User-Manual. 227 [web14f] Johnny Lee: Free or cheap Wii Remote hacks. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.ted.com/talks/ johnny lee demos wii remote hacks. [web14g] Jumpido: Educational games for Kinect. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.jumpido.com/en. [web14h] Kinect 3D Hand Tracking. Website, 2014. Última consulta: 17 Marzo 2014. url: http://cvrlcode.ics.forth.gr/handtracking/. [web14i] Kinect Educational App: River Crossing by Kinems. site, 2014. Última consulta: 17 Marzo 2014. http://www.kinecteducation.com/blog/2013/02/12/ kinect-educational-app-river-crossing-by-kinems/. [web14j] Kinect for Windows SDK. Website, 2014. Última consulta: 17 Marzo 2014. url: http://msdn.microsoft.com/en-us/library/hh855347.aspx. [web14k] Kinect for Windows: Voice, Movement and Gesture Recognition Technology. Website, 2014. Última consulta: 17 Marzo 2014. url: http:// www.microsoft.com/en-us/kinectforwindows/. [web14l] Kinect Math: Kinesthetic Learning Experience. Website, 2014. Última consulta: 17 Marzo 2014. url: http://kinectmath.org/. [web14m] kinect-mssdk-openni-bridge: Experimental module to connect Kinect SDK to OpenNI. Website, 2014. Última consulta: 17 Marzo 2014. url: http:// code.google.com/p/kinect-mssdk-openni-bridge/. [web14n] Kinect para Xbox 360. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.xbox.com/es-ES/Kinect. [web14o] KinectEDucation. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.kinecteducation.com/. [web14p] Mando de movimiento PlayStation Move. Website, 2014. Última consulta: 17 Marzo 2014. url: http://es.playstation.com/psmove/. [web14q] Media Lab Students Hack Kinect for Cooler Videoconferencing. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.media.mit.edu/news/external-links/ media-lab-students-hack-kinect-cooler-videoconferencing. 228 Weburl: [web14r] Microsoft Research: Kinect Sign Language Translator expands communication possibilities. Website, 2014. Última consulta: 17 Marzo 2014. url: http://research.microsoft.com/en-us/collaboration/ stories/kinect-sign-language-translator.aspx. [web14s] Minority Report (2002) - IMDb. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.imdb.com/title/tt0181689/. [web14t] Nintendo: Wii. Website, 2014. Última consulta: 17 Marzo 2014. url: https://www.nintendo.es/Wii/Wii-94559.html. [web14u] OpenNI: Open Natural Interaction. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.openni.org/. [web14v] Processing 2: Language Reference (API). Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.processing.org/reference/. [web14w] Project NAVI, a Kinect Hack That Helps Visually Impaired Navigate Indoors. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.medgadget.com/2011/03/ project navi a kinect hack that helps visually impaired/ navigate indoors.html. [web14x] Real-Time Princess Leia Holography Via Kinect Hack. Website, 2014. Última consulta: 17 Marzo 2014. url: http: //www.media.mit.edu/news/external-links/2011/01/ real-time-princess-leia-holography-kinect-hack. [web14y] SigmaNIL. Website, 2014. Última consulta: 17 Marzo 2014. url: http:// www.sigmanil.com/. [web14z] System Development Approaches: Solutionext. Website, 2014. Última consulta: 17 Marzo 2014. url: http://www.solutionext.co.uk/?p=133. [WRB06] Daniel Weinland, Remi Ronfard, y Edmond Boyer. Free Viewpoint Action Recognition Using Motion History Volumes. Comput. Vis. Image Underst., 104(2):249–257, 2006. [WS08] Liang Wang y David Suter. Visual Learning and Recognition of Sequential Data Manifolds with Applications to Human Movement Analysis. Comput. Vis. Image Underst., 110(2):153–172, 2008. [XZSS12] Wenyao Xu, Mi Zhang, Alexander A. Sawchuk, y Majid Sarrafzadeh. Corecognition of Human Activity and Sensor Location via Compressed Sensing in Wearable Body Sensor Networks. En Proceedings of the 2012 Ninth 229 International Conference on Wearable and Implantable Body Sensor Networks, BSN ’12, páginas 124–129. IEEE Computer Society, 2012. [YKS08] Pingkun Yan, Saad M. Khan, y Mubarak Shah. Learning 4D action feature models for arbitrary view action recognition. 2013 IEEE Conference on Computer Vision and Pattern Recognition, 0:1–7, 2008. [ZRZ02] Lei Zhu, Al Bing Rao, y Aldong Zhang. Theory of Keyblock-based Image Retrieval. ACM Trans. Inf. Syst., 20(2):224–257, 2002. 230 Este documento fue editado y tipografiado con LATEX empleando la clase esi-tfg que se puede encontrar en: https://bitbucket.org/arco group/esi-tfg [Respeta esta atribución al autor] 231