lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web...

151
PROYECTO FIN DE CARRERA Título del proyecto DISEÑO E IMPLEMENTACIÓN DE UNA APLICACIÓN PARA EL PROCESAMIENTO DE DATOS DE UN DISPOSITIVO KINECT SEGÚN EL MÉTODO FACS PARA ETIQUETADO AFECTIVO Autor: D. DAVID REVILLA MUÑOZ Tutor: D. JUAN MANUEL MONTERO MARTÍNEZ Departamento de Ingeniería de Electrónica MIEMBROS DEL TRIBUNAL: Presidente: D. Vocal: D. Secretario: D. Suplente: D.

Transcript of lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web...

Page 1: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

PROYECTO FIN DE CARRERA

Título del proyecto

DISEÑO E IMPLEMENTACIÓN DE UNA APLICACIÓN PARA

EL PROCESAMIENTO DE DATOS DE UN DISPOSITIVO

KINECT SEGÚN EL MÉTODO FACS PARA ETIQUETADO

AFECTIVO

Autor: D. DAVID REVILLA MUÑOZ

Tutor: D. JUAN MANUEL MONTERO MARTÍNEZ

Departamento de Ingeniería de Electrónica

MIEMBROS DEL TRIBUNAL:

Presidente: D.

Vocal: D.

Secretario: D.

Suplente: D.

Fecha de lectura: Madrid, a de de 2016

Calificación:

Page 2: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

DEPARTAMENTO DE INGENIERÍA DE ELECTRÓNICA

DISEÑO E IMPLEMENTACIÓN DE UNA

APLICACIÓN PARA EL PROCESAMIENTO DE

DATOS DE UN DISPOSITIVO KINECT SEGÚN EL

MÉTODO FACS PARA ETIQUETADO AFECTIVO

DAVID REVILLA MUÑOZ

MARZO 2016

Page 3: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Resumen La formación hoy en día se ha convertido en algo fundamental. Hasta hace poco

tiempo era suficiente una educación básica para acceder a puestos de trabajo, y la propia empresa formaba a sus empleados según se producían avances. Sin embargo, a día de hoy los avances tecnológicos son mucho más continuos, y en consecuencia el modelo de enseñanza debía evolucionar también, apareciendo el e-learning .

Los primeros cursos de e-learning estaban enfocados a empleados que debían adaptarse a los cambios de su puesto de trabajo; para una empresa resulta muy costoso desplazar a sus trabajadores a un centro de formación, además del trastorno de prescindir de esas personas durante el curso. Gracias al e-learning, el empleado podía aprovechar el tiempo que tuviera menos trabajo y progresar con la formación a su propio ritmo.

Al principio eran cursos basados en una aplicación multimedia grabada en un CDROM/DVD, ya que las conexiones de Internet no permitían descargar contenidos como ahora lo permiten las redes actuales (ADSL, fibra óptica). Hoy en día asociamos el e-learning a páginas web on-line con fotos, vídeos-audio, texto interactivo, etc. Todo dinámico y con posibilidad incluso de chat (o videoconferencia) con un profesor. Además, el e-learning ya no es exclusivo de empresas con temarios avanzados, hay cursos de múltiples temas y para todas las edades. Sin embargo, esta formación a distancia tiene un inconveniente: la información principalmente fluye en un solo sentido, desde Internet hacia el alumno, ya que la mayoría son sesiones grabadas; y en los casos que son sesiones en directo, el profesor sólo percibe una mínima parte del estado y comprensión de los alumnos en el caso de que éstos hagan alguna pregunta.

En este contexto, este Proyecto Fin de Carrera (PFC) se ha planteado como una colaboración entre los grupos de investigación GTH (Grupo de Tecnologías de Habla) de la ETSI Telecomunicación de la UPM y aDeNu de la ETSI Informática de la UNED en relación al proyecto MAMIPEC [1] cuyo principal objetivo es adaptar el proceso de aprendizaje al entorno y reacciones emocionales del alumno. El PFC que se desea realizar pretende aportar al proyecto MAMIPEC la posibilidad de reconocer (i.e. mediante detección y etiquetado) el estado emocional del alumno. Para ello, se capturarán las expresiones faciales con una Kinect para Windows, y se analizarán y procesarán según el método FACS [2] para intentar obtener las distintas reacciones del alumno, permitiendo además que un experto pueda etiquetar de forma manual características afectivas en las imágenes recogidas que sirvan para mejorar la detección realizada.

El equipo Kinect devuelve una serie de puntos 3D que son vértices de triángulos que cubrirían la superficie facial del usuario monitorizado. Este conjunto de polígonos serían la representación gráfica expuesta en CANDIDE-3 [3], un método usado en la generación de caras 3D por ordenador. También de acuerdo a CANDIDE-3, Kinect da información de ciertas AU para el modelado emocional gráfico del usuario.

En el proyecto se estudia la posibilidad de usar los datos reportados de CANDIDE-3 (puntos/triángulos 3D y AU) para su conversión y correspondiente etiquetado FACS, o si se debe recurrir directamente a los puntos monitorizados y calcular manualmente las AU.

Palabras Clave

Kinect, FACS, CANDIDE-3, MAMIPEC, etiquetado, emocional

i

Page 4: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

AgradecimientosQuiero dar las gracias a todos los que me han apoyado en este proyecto,

especialmente a mi mujer Isabel por toda su paciencia, a mi familia, amigos y a los profesores que me han asesorado, Juan Manuel Montero y Olga Santos.

ii

Page 5: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

GlosarioaDeNu Adaptación Dinámica de Sistemas de Educación eN-línea para

el modelado del Usuario

API Application Programming Interface son las funciones, protocolos y herramientas proporcionadas por un software determinado para su utilización en la creación de una aplicación

AU Action Unit / Unidad de acción

Binding Término de difícil definición: en general se trata de asociar dos propiedades de manera que influyan entre ellas de forma automática (en compilación o en tiempo de ejecución se resuelve esa conexión): por ejemplo, el control deslizante del altavoz de Windows en realidad está modificando el valor de la propiedad volumen que será una variable de tipo entero

FACS Facial Action Coding System / Sistema de Codificación de las Acciones Faciales

FP Feature Points son los puntos clave sobre los que se basa la malla 3D representativa del rostro

FPS Frames Per Second es el indicativo de video de cuantas imágenes por segundo se muestran en pantalla de forma sucesiva

GUI Graphical User Interface, interfaz gráfico de usuarios, se refiere a la representación gráfica que hacen los programas para presentar información e interactuar con el usuario

IDE Integrated Development Enviroment, entorno de desarrollo integrado

MAMIPEC Multimodal approaches for Affective Modeling in Inclusive Personalized Educational scenarios in intelligent Contexts / Enfoques Multimodales para el Modelado de Aspectos Emocionales en Escenarios de Educación Personalizados e Inclusivos en Contextos Inteligente

RDSI Red Digital de Servicios Integrados

SDK Software Development Kit / Kit de Desarrollo de Software

SU Shape Unit / Unidad de forma

WPF Windows Presentation Foundation, conjunto de herramientas de C# para crear un programa GUI

iii

Page 6: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Wrapper Función que pone a disposición otra función interna del entorno de desarrollo, pero ajustando los parámetros correctos, intentado evitar fallos del programador, pero a la vez limitando la flexibilidad de la función interna

XAML eXtensible Application Markup Language, variación de Microsoft de XML para la definición de un GUI

iv

Page 7: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

ÍndiceResumen................................................................................................................................i

Agradecimientos..................................................................................................................ii

Glosario...............................................................................................................................iii

Índice....................................................................................................................................v

Índice de ilustraciones.......................................................................................................vii

Índice de código..................................................................................................................ix

Introducción.........................................................................................................................1

Motivación del proyecto..................................................................................................1

Objetivos y enfoque.........................................................................................................3

Metodología y Fases de Trabajo......................................................................................5

Herramientas y recursos utilizados......................................................................................6

Microsoft Visual Studio...................................................................................................7

Lenguaje de programación C# y WPF.............................................................................8

Kinect for Windows SDK y Developer Toolkit.............................................................19

Kinect for Windows Runtime........................................................................................20

Arquitectura de la aplicación.............................................................................................21

Introducción...................................................................................................................21

Análisis del dispositivo Kinect......................................................................................22

Programa cliente............................................................................................................28

Programa servidor..........................................................................................................32

Modelo de conocimiento de la aplicación..........................................................................37

Aplicación cliente..........................................................................................................37

Ventana visualización Kinect.....................................................................................38

Control de seguimiento facial....................................................................................41

Recogida de datos......................................................................................................43

Envío de información al servidor...............................................................................45

Aplicación servidor........................................................................................................47

Ventana principal del servidor...................................................................................50

Ventana de edición de usuarios..................................................................................53

Ventana de edición de reglas.....................................................................................55

v

Page 8: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Ventana de análisis de usuario...................................................................................57

Manuales de uso.................................................................................................................60

Programa cliente............................................................................................................60

Programa servidor..........................................................................................................65

Conclusiones......................................................................................................................72

Futuras líneas/trabajos........................................................................................................74

Presupuesto de ejecución material.....................................................................................77

Relación de salarios.......................................................................................................77

Relación de obligaciones sociales..................................................................................77

Relación de salarios efectivos totales.............................................................................78

Coste de la mano de obra...............................................................................................78

Coste total de materiales................................................................................................78

Importe total del presupuesto de ejecución material......................................................79

Importe de ejecución por contrata..................................................................................79

Honorarios Facultativos.................................................................................................80

Importe Total del Proyecto............................................................................................80

Pliego de condiciones.........................................................................................................81

Condiciones generales....................................................................................................81

Condiciones generales a todos los programas................................................................82

Condiciones generales a la prueba.................................................................................82

Recursos materiales........................................................................................................83

Recursos lógicos............................................................................................................83

Anexo – Listados de código...............................................................................................84

Función GetShapePoints().............................................................................................84

Función GetShapeUnits(out bool hasSuConverged).....................................................85

Funciones de envío asíncronas de CSASocketClient.cs................................................86

Ventana principal del servidor.......................................................................................89

Bibliografía......................................................................................................................105

vi

Page 9: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Índice de ilustracionesIlustración 1. Arquitectura de la plataforma .NET...............................................................8

Ilustración 2. Diagrama casos de uso.................................................................................21

Ilustración 3. Face Tracking Basics-WPF vs. Face Tracking Visualization......................22

Ilustración 4. Medidas de AU Kinect.................................................................................24

Ilustración 5. Medidas de distancias..................................................................................25

Ilustración 6. Programa cliente, diagrama clases principal................................................37

Ilustración 7. Programa cliente, diagrama clases KinectWindow.....................................38

Ilustración 8. KinectWindow, elementos visualizadores (1/2)..........................................38

Ilustración 9. KinectWindow, elementos visualizadores (2/2)..........................................38

Ilustración 10. KinectSensorManager en KinectControl...................................................40

Ilustración 11. Programa cliente, seguimiento facial.........................................................41

Ilustración 12. Programa cliente, conexión asíncrona.......................................................45

Ilustración 13. Programa servidor, diagrama de clases......................................................47

Ilustración 14. Programa servidor, interacción Clase principal y Servidor.......................48

Ilustración 15. Programa servidor, estructura ventana principal.......................................50

Ilustración 16. Programa servidor, estructura interna del servidor....................................52

Ilustración 17. Programa servidor, edición de usuarios.....................................................53

Ilustración 18. Programa servidor, edición de reglas.........................................................55

Ilustración 19. Programa servidor, análisis emocional......................................................57

Ilustración 20. Pantalla inicial cliente................................................................................60

Ilustración 21. Petición de identificación de usuario.........................................................61

Ilustración 22. Selección formato video............................................................................61

Ilustración 23. Ajustes de exposición................................................................................62

Ilustración 24. Ajustes de color..........................................................................................62

Ilustración 25. Ajustes de cámara de profundidad.............................................................62

Ilustración 26. Selección de modo de seguimiento............................................................63

Ilustración 27. Ajuste de inclinación..................................................................................63

Ilustración 28. Acelerómetro..............................................................................................63

Ilustración 29. Selección de modo funciomiento...............................................................64

Ilustración 30. Selección de puntos mostrados..................................................................64

vii

Page 10: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Ilustración 31. Servidor, primera ejecución.......................................................................65

Ilustración 32. Edición de reglas inicial.............................................................................65

Ilustración 33. Definición de una regla..............................................................................67

Ilustración 34. Edición de usuarios inicial.........................................................................68

Ilustración 35. Primer usuario de pruebas..........................................................................68

Ilustración 36. Ventana principal con usuario creado........................................................69

Ilustración 37. Ventana de análisis....................................................................................69

Ilustración 38. Detección de regla y etiquetado.................................................................70

viii

Page 11: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Índice de códigoCódigo 1. Primer programa en C#.......................................................................................9

Código 2. Primer programa mejorado................................................................................10

Código 3. Ejemplo foreach................................................................................................11

Código 4. Paso de parámetros de salida.............................................................................12

Código 5. Primer programa WPF......................................................................................14

Código 6. Salida primer programa WPF............................................................................14

Código 7. Ejemplos de botón.............................................................................................15

Código 8. Ejemplo de evento.............................................................................................16

Código 9. Ejemplo de enlace de datos Binding.................................................................17

Código 10. Extraido de Frace Tracking Visualization.......................................................23

Código 11. Representación de usuarios.............................................................................51

Código 12. Programa servidor, detalle del control de usuarios.........................................54

Código 13. Programa servidor, selector de puntos............................................................56

Código 14. Programa servidor, visualizadores..................................................................59

Código 15. Obtención de puntos muestreados 2D.............................................................85

Código 16. Obtención de rasgos faciales y estado de seguimiento...................................85

Código 17. Conexión cliente Asíncrona............................................................................88

Código 18. XAML de la ventana principal del servidor....................................................92

Código 19. Código C# de la ventana principal del servidor............................................104

ix

Page 12: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

IntroducciónMotivación del proyectoHace años se desarrollaron plataformas de video presencia para

entornos profesionales con las que poder celebrar reuniones a distancia con servicios de voz y video. Basados en tecnología RDSI y con una electrónica que impedía tener cámaras y pantallas manejables y a precios asequibles, no llegó a una implantación tan general como se esperaba.

Con la expansión de la tecnología TCP/IP y el acceso del público general a Internet el cambio fue significativo: cualquiera podía disponer de una webcam y entablar una videoconferencia. Surgieron aplicaciones como Microsoft Messenger que permitía chat por texto y también ver y oír a otra persona en otro lugar.

Sin embargo, fue necesario otro nuevo avance, el acceso a Internet de banda ancha (ADSL y fibra) para el público general y las empresas, el que permitió la aparición de un nuevo servicio relacionado con la videoconferencia: la formación online a distancia. Un profesor puede enviar a sus alumnos video en tiempo real, presentaciones incluso ejercicios, sin necesidad de estar en la misma aula. Sin embargo, el profesor no lo tiene fácil para supervisar a sus alumnos, ya que no se tiene la misma percepción sin estar todos en la misma aula. También existe la formación off line, en las que el alumno accede a contenido ya grabado en cualquier momento y no se le monitoriza. En estos casos ya es imposible saber si el alumno presta la atención adecuada, si se aburre… y en general las emociones que pueda expresar ante el temario, los ejercicios, etc.

El método básico que se sigue hasta ahora son encuestas a los alumnos, que rellenarán con más o menos rigor. Un método más avanzado consiste en que el alumno sea grabado durante la sesión de formación; este video es analizado más adelante por un experto que puede sacar conclusiones más adecuadas. Este método es mucho más preciso, pero mucho más tedioso. De nuevo los avances en tecnología permiten facilitar esta labor: los procesadores más potentes permiten analizar imágenes en tiempo real y llegar a identificar partes del cuerpo humano, incluso gestos faciales. En este sentido aparece primero en el mundo de los videojuegos junto con la consola Microsoft Xbox 360 un nuevo “mando” que permite interactuar con los juegos en tiempo real usando solamente nuestro cuerpo, brazos y piernas. Este “mando” es en realidad un conjunto de una cámara de color, una cámara de profundidad, un emisor de infrarrojos y una serie de

1

Page 13: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

micrófonos, y se conoce como Kinect. Muchos vieron en este equipo no sólo un “mando” para juegos, sino también para interactuar con un PC a distancia.

Kinect es capaz de registrar la posición de un cuerpo humano junto con sus extremidades (piernas y brazos) y su cabeza; el dispositivo Kinect proporciona una serie de puntos del rostro detectado y unos eventos (AU) relativos al movimiento de ciertas partes, como pueden ser las cejas y los labios. Estos eventos están relacionados con el método CANDIDE-3, una máscara facial parametrizada desarrollada para la codificación de las caras humanas. Debido al relativamente bajo número de datos necesarios, permite una rápida reconstrucción con poca capacidad computacional. CANDIDE-3 está enfocado principalmente a la representación gráfica (video MPEG-4) de la cara y su expresión a través de las AUs [4].

La posibilidad de usar una Kinect en el marco del proyecto MAMIPEC, permitiría un avance más debido al etiquetado emotivo automatizado, pudiendo en un futuro adaptar los contenidos también automáticamente en función de dicho etiquetado.

2

Page 14: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Objetivos y enfoqueEl propósito final del proyecto será ayudar al experto en el etiquetado

emocional FACS, utilizando una Kinect para grabar las reacciones al alumno ante los temas y cuestiones que se le planteen en una sesión de formación a distancia, y creando una serie de reglas que automaticen el proceso.

El concepto de AU fue descrito hace más de 40 años por el investigador sueco Carl-Herman Hjortsjö, y ampliado más tarde por Paul Ekman y Wallace V. Friesen en el Centro Médico de la Universidad de California bajo el nombre de FACS. Estos investigadores observaron los movimientos musculares faciales ante diversas reacciones emocionales y les asignaron unas AU, que son indicadores de cambios frente al estado neutro del individuo en reposo. Estos gestos faciales son universales, y en mayor o menos manera, realizados por todo el mundo: por ejemplo, la AU que indica que un individuo es feliz estará basada, entre otras, en la sonrisa, que equivale a la separación de la comisura de los labios (respecto al estado de neutro o de reposo) estando los labios juntos; una AU que represente la expresión de sorpresa, provendrá de la detección de la apertura máxima de los ojos.

Sin embargo, la funcionalidad proporcionada por Kinect no aplica el método FACS a la imagen detectada. Esta funcionalidad sería muy interesante para facilitar la identificación de cambios en el estado emocional del estudiante que se pretende realizar en el proyecto MAMIPEC. Por otro lado, en los procesos de detección emocional suele ser útil contar con la caracterización realizada por expertos para complementar la detección y clasificación automática.

Se aprovecha la Kinect para grabar al alumno (con la cámara en color que utilizamos como una Webcam) y obtener sus parámetros correspondientes (gracias a la monitorización de los puntos faciales). A continuación, un experto determinará que parámetros necesita y definirá unas reglas en base a los cambios en dichos parámetros que se traducirán en una emoción. Estas reglas las definirá utilizando como referencia el método FACS para etiquetado afectivo. De esta manera, se puede automatizar el análisis de las emociones del alumno y modificar los métodos de enseñanza de modo que sean más atractivos y efectivos para el alumno.

En el proyecto por tanto se analizarán todos los datos que devuelve Kinect y cuál es la mejor manera de aprovecharlos en el etiquetado FACS necesario en el proyecto MAMIPEC. Para ello, será necesaria la creación de

3

Page 15: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

una aplicación que acceda a toda la información facilitada por el SDK del Kinect mediante el uso de Visual Studio (C++, C# o VisualBasic).

A partir de la información captada por el dispositivo se añaden capas de procesamiento y abstracción:

Primeramente, se extraen los datos correspondientes a la expresión facial y se adaptarán al método CANDIDE-3.

Posteriormente se procesan para adecuarlos al método FACS siguiendo las indicaciones que se facilitarán desde el proyecto MAMIPEC.

Los resultados obtenidos se exponen en un interfaz gráfico junto a la secuencia de video correspondiente y sincronizado con otras posibles fuentes externas, como el audio procedente de equipos auxiliares o la captura de pantalla, para ayudar a desechar reacciones emotivas causadas por elementos externos.

Este interfaz permite además que un experto pueda etiquetar información afectiva en aquellos instantes del video que considere oportuno para complementar la información afectiva detectada.

4

Page 16: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Metodología y Fases de TrabajoPara el desarrollo del PFC se ha seguido una metodología en cascada

y un método de aproximaciones sucesivas basadas en prototipado que, tomando como punto de partida la toma de requisitos, llevó al diseño y desarrollo de la funcionalidad requerida en base a los componentes identificados, así como las correspondientes pruebas unitarias. A lo largo de las distintas fases, se realizó la integración de los componentes y evaluaciones del sistema con el fin de satisfacer las necesidades del usuario. Como lenguaje de modelado se usó UML.

Se han identificado las siguientes fases de trabajo:

1. Familiarización con el entorno Microsoft Visual Studio. [5] [6]

2. Familiarización con el kit de desarrollo de Kinect para Windows. [4]

3. Familiarización con el método CANDIDE-3 y FACS.

4. Decisión del lenguaje a utilizar, C++ o C#, para cada una de las fases del proyecto.

5. Recogida de requisitos para el PFC del proyecto MAMIPEC y análisis de los mismos.

6. Diseño, Desarrollo y Pruebas unitarias del módulo software encargado de extraer la información de Kinect.

7. Diseño, Desarrollo y Pruebas unitarias del módulo de procesamiento de datos aplicando FACS.

8. Mock-up con la propuesta de arquitectura de información para la interfaz gráfica de la herramienta y validación por parte del proyecto MAMIPEC.

9. Diseño, Desarrollo y Pruebas de la interfaz que muestre los resultados y permita a un experto añadir etiquetado manual.

10. Integración de los diferentes módulos desarrollados.

11.Validación y pruebas del sistema final.

12.Elaboración de la documentación del proyecto.

5

Page 17: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Herramientas y recursos utilizadosPrimeramente, hay que elegir qué herramientas se van a utilizar en el

desarrollo de este proyecto. Si se quiere trabar con el SDK oficial de Microsoft, será obligatorio trabajar en Windows y con su propia herramienta de desarrollo Visual Studio. Buscando alternativas nos encontramos con Open Kinect y jnect: el primero es un desarrollo aparecido con la primera versión de Kinect en las que el SDK oficial estaba todavía en versión de pruebas y con fallos, y permitía el desarrollo en otras plataformas como Linux; el segundo venía a dar soporte al entorno de desarrollo Eclipse en lenguaje Java. Sin embargo, el SDK oficial evolucionó hasta la última versión 1.8.0 corrigiendo muchos errores y añadiendo funcionalidades que los desarrollos no oficiales no podían desarrollar a tiempo. De hecho, las páginas de descargas de Open Kinect [7] y jnect [8], no se han actualizado desde 2011 y 2012 respectivamente. De este modo nos encontramos con que el único entorno de desarrollo fiable a largo plazo (al menos, mientras exista Kinect) es el de Microsoft, aunque no debemos dejar de agradecer los intentos de alternativas libres que han obligado a Microsoft a poner a disposición de toda la comunidad de desarrolladores un SDK potente y fácil de usar.

Teniendo ya decidido Visual Studio como el entorno de programación que se debe utilizar, el siguiente paso es decidir el lenguaje de programación: Visual Basic, Visual C++ o Visual C#. Desde el principio hay que descartar Visual Basic por no contar en el SDK con las librerías necesarias para la monitorización facial. Analizando los ejemplos de “Kinect Explorer” de Visual C++ y Visual C# se observa que en C++ toda la generación de ventanas, botones, desplegables, etc. no es en realidad nada “Visual” como podría dar a entender el entorno de programación, sino que se hace todo con comandos. En cambio, en Visual C# se crea un archivo con la representación gráfica arrastrando una serie de elementos predefinidos directamente sobre una ventana y colocándolos de la forma que se crea más conveniente -tienen asociado un código XAML para personalizar dichos elementos e incluso ampliar sus funcionalidades- y en otro archivo se incluye, o no, código extra para controlar lo que presenta cada elemento; esta estructura propicia una separación de la parte visual de la lógica del programa, es decir, permitiría que el diseño gráfico lo realizase alguien especializado en este campo, y el código lo realizase un programador. No es el caso de este proyecto en el que está todo desarrollado por la misma persona, pero en un futuro se podría

6

Page 18: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

mejorar por un diseñador gráfico simplemente retocando la parte gráfica, y poco o nada el código.

Microsoft Visual StudioVisual Studio (en adelante VS) [9] es un completo IDE que permite

crear aplicaciones modernas. Esta herramienta estaba disponible en diferentes versiones, desde una gratuita conocida como Express, hasta otras más avanzadas como la Professional o la Ultimate: en todas las versiones se podía editar y depurar código, sin embargo, las versiones más avanzadas proporcionaban mejores herramientas de edición, más facilidades durante la ejecución en modo depuración, así como instrumentos de análisis que no estaban disponibles en la versión gratuita. Se inició el proyecto con la versión VS 2013 Professional gracias al acuerdo entre Microsoft y las universidades, que proporcionaba una licencia gratuita de su versión Professional para estudiantes a través del programa DreamSpark [10]. Posteriormente, se presentó Visual Studio 2015, también con diferentes versiones en función de sus prestaciones; en cambio, en esta ocasión la versión gratuita ha dejado de ser básica como la antigua Express, y la versión de acceso libre conocida como Visual Studio Community tiene incluso alguna función extra que no tenía la versión Professional de 2013. Siguen existiendo versiones superiores, con funciones adicionales más centradas en desarrollo en entornos de grupo de trabajo, pero no necesarias para el desarrollo de este proyecto. Las versiones finales de los programas de este proyecto se han terminado y compilado en la versión VS 2015 Community, prefiriéndose sobre la del 2013 sobre todo por las mejoras y correcciones del compilador.

Este entorno de programación incluye las herramientas para el desarrollo de aplicaciones de escritorio de Windows (como este proyecto), pero también para la plataforma universal de Windows, iOS y Android. Soporta múltiples lenguajes de programación, herramientas para el desarrollo de aplicaciones web modernas e integración con repositorios como GitHub o Team Foundation Server.

En la instalación se incluye Blend for Visual Studio: se trata de un entorno de desarrollo orientado a la parte visual. Aunque permite editar código, la función principal es el diseño de las ventanas. Permite la personalización de los controles y su correcta ubicación.

7

Page 19: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Lenguaje de programación C# y WPFEl lenguaje de programación C# (pronunciado como C Sharp) está

diseñado para ser un lenguaje de programación orientada a objetos simple, moderno y de propósito general. Utiliza gran parte de la sintaxis de C, pero modifica y recoge conceptos también de otros lenguajes, principalmente Java. Al estar muy relacionado con C (y C++) y Java, cualquier programador que conozca estos lenguajes podrá empezar a trabajar con C# en un corto plazo de aprendizaje.

Al igual que este último lenguaje (aunque C# podría llegar a ser compilado en código máquina) su funcionamiento es bajo un entorno de ejecución conocido como .NET; es decir, se necesita tener instalado este entorno de ejecución para que funcionen los programas creados en este lenguaje (similar a tener instalada la máquina virtual de Java).

El entorno .NET en realidad engloba más lenguajes (por ejemplo, en aplicaciones web de servidor se utiliza ASP.NET), aunque el más conocido y utilizado es C#, por lo a veces se confunden los términos y se indica que un programa está creado en lenguaje .NET, cuando lo correcto es C#. El hecho de contar con .NET, hace que un programa pueda llegar a ejecutarse en varias plataformas y sistemas operativos, siempre que exista el entorno .NET correspondiente y no se hayan utilizado funciones específicas de un sistema concreto.

8

Page 20: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Ilustración 1. Arquitectura de la plataforma .NET

Como lenguaje orientado a objetos no existen las variables o funciones globales, todo debe estar englobado en alguna clase. Por ejemplo, un tipo básico de datos como los números enteros (int) o las cadenas de caracteres (string) son clases derivadas de la clase principal System.Object.

Como se indicaba al principio, la idea era crear un lenguaje de propósito general: al programar en C# no estamos obligados a trabajar con entornos gráficos, sino que también se puede trabajar con programas de la consola de Windows (antiguamente conocida como la ventada de MS-DOS). En el primer ejemplo encontrado en la guía de programación de MSDN [11] se encuentra el típico primer programa “Hello World”.

9

namespace ConsoleHelloWorld{ public class Hello1 { public static void Main() { System.Console.WriteLine("Hello, World!"); } }}

Código 1. Primer programa en C#

Page 21: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Como se ve, no hay nada gráfico, simplemente se imprimirá el texto “Hello, World!” en la consola de Windows o en la ventana de salida de Visual Studio. Analizando este ejemplo, se podrían destacar cuatro puntos:

No es necesario un entorno de programación avanzados para crear un programa, bastaría con un sencillo editor de textos. Se podría utilizar un compilador de línea de comandos para generar el código ejecutable. Aunque en realidad para realizar programación un poco más compleja, es muy recomendable el uso de un entorno de desarrollo como Visual Studio de Microsoft.

Al igual que en el lenguaje C del que parte, el programa principal se inicia siempre desde la función Main, y desde ésta se invocan el resto de funciones.

Tal como se indicaba anteriormente, estamos ante un lenguaje orientado a objetos y todo está englobado en clases: incluso la función principal Main debe estar dentro de una clase, tal como se puede apreciar.

Aunque no es estrictamente obligatorio, sí es muy recomendable que todas las clases de un mismo proyecto estén dentro de un mismo “namespace”1

En relación a este último punto, la llamada a las funciones de consola se hacen a través del espacio de nombres System (notación con . (punto), en vez de :: (doble signo dos puntos) como en C++). Se podría indicar en el programa que se quiera trabajar con las funciones de la biblioteca “System”, para lo cual se añadiría al principio del listado la directiva using (similar a los #include de C). Una vez creada la referencia al espacio de nombres, se pueden usar sus funciones con nomenclatura más reducida. Aplicando esta información y añadiendo una función para leer la entrada de usuario, el ejemplo quedaría así:

1 Espacio de nombres, engloba bajo el mismo ámbito todas las clases, funciones y objetos relacionados

10

Page 22: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Como en C++ y Java, las funciones se declaran con unos argumentos y un valor devuelto. Por ejemplo, esta función Main no toma ningún argumento y tampoco debe devolver ningún valor (si el compilador encuentra una sentencia “return” en una función que no debe devolver nada, void, generará error y no podremos ejecutar el programa.

En la declaración de variables también es muy similar a C y C++, definiendo el tipo de datos que almacenará esa variable. En este sentido se proporcionan los tipos básicos: char, int, short, long, double, string. Y como lenguaje orientado a objetos, cuenta con las palabras clave public, internal (conocida como protected en otros lenguajes) y private para gestionar la visibilidad de cada función y variable.

Por supuesto existen las estructuras habituales de cualquier lenguaje de programación: condicionales if y else, bucles while y for, condicionales múltiples switch y case, etc.

Una función interesante que existe en C# que no está disponible en C++ es foreach: permite recorrer todos los elementos de una lista, o cualquier variable cuyo tipo implemente un enumerador (IEnumerable, IEnumerator).

11

using System;namespace ConsoleHelloWorld{ public class Hello1 { public static void Main() { Console.WriteLine("Hello, World!"); Console.ReadLine(); } }}

Código 2. Primer programa mejorado

static void Main(){ foreach (int number in SomeNumbers()) { Console.Write(number.ToString() + " "); } // Output: 3 5 8 Console.ReadKey();}

public static System.Collections.IEnumerable SomeNumbers(){ yield return 3; yield return 5; yield return 8;}

Código 3. Ejemplo foreach

Page 23: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Una de las limitaciones en las funciones en C es que sólo pueden devolver un valor: la solución que se adoptó en su momento fue usar la lista de parámetros de la función para introducir punteros a variables. Al realizar esto, la función escribe directamente sobre la variable original, consiguiendo que la función devuelva más de un valor. Sin embargo, esto era (y es) una práctica muy peligrosa, ya que el puntero que de la variable que se le da a la función es en realidad su posición de memoria: si la función a la que se le ha pasado la variable escribiera datos fuera de la memoria que corresponde a la variable, se podría estar generando un grave problema en el sistema.

Para no perder esa funcionalidad tan importante, pero sin poner el sistema en riesgo, en C# se pueden pasar variables a las funciones con las palabras clave ref y out. Cuando se pasa una variable con el modificador ref, le estamos dando a la función una variable que ya está inicializada con algún valor para que la use como cualquier otra variable, y si fuera necesario, se puede modificar su valor y el programa que ha invocado la función recibirá la variable con el nuevo valor. Este comportamiento tan similar a los punteros tiene una gran diferencia: no se está pasando la dirección de memoria directamente a la función, sino una copia lógica que en realidad apunta a la misma zona de memoria; además, hay comprobación de tipos, es decir, si en la función se declara una variable ref como int, hay que pasar a la función una variable de tipo int, e internamente en la función se tratará la variable como de tipo int. Cualquier acceso de intentar asignar un valor que no se corresponda con el tipo especificado, será rechazado y generará error al compilar.

En cuando a las variables que se pasan como out, se consideran como variables de salida a todos los efectos: una función que recibe una variable de este tipo no debe intentar usarla ya que probablemente llegará sin inicializar. En cambio, la función está obligada a asignar un valor a dicha variable, en caso contrario, el compilador generará error.

12

static void Main(string[] args){ int number = 20; int numberOUT; AddFive(ref number, out numberOUT); Console.WriteLine(number, numberOUT); Console.ReadKey();}// Output: 5 10static void AddFive(ref int number, out int number2){ number = number + 5; number2 = number + 5;}

Código 4. Paso de parámetros de salida

Page 24: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

El entorno C# ofrece dos posibilidades de crear un programa con entorno gráfico GUI, es decir, con etiquetas, bloques de texto, botones, etc. El más antiguo se conoce como WinForms, y el creado más recientemente se ha denominado WPF, Windows Presentation Foundation: en realidad estas son las herramientas que ofrece Microsoft en Visual Studio, aunque se pueden encontrar otros entornos de programación GUI, aunque en nuestro caso seguimos quedándonos con el entorno proporcionado por Microsoft por la integración completa con el kit de desarrollo de Kinect.

Un programa creado con WinForms está basado en las librerías estándar de Windows Win32/WinAPI. Esto significa que los controles que se utilicen, un botón, por ejemplo, tendrá el aspecto de cualquier botón de Windows. Personalizar cualquier elemento se convierte en una tarea complicada, teniendo que crear el elemento manualmente en la mayoría de los casos, o recurriendo a librería de terceros. En cambio, WPF se ha creado desde cero y en general no dependerá de ningún objeto estándar de Windows. En el caso del botón, está definido como un borde, y se puede meter dentro fácilmente un texto y una imagen. También reacciona a estados, como tener el ratón encima, estar pulsado, etc. Esta flexibilidad tiene como contrapartida que puede llegar a ser muy complicado crear un comportamiento similar al de un control de Windows.

Como ventajas de WinForms se podrían destacar el haber estado presente desde hace mucho tiempo, lo que le confiere bastante estabilidad. Y también esta longevidad permite disponer de una amplia variedad de controles desarrollados por terceros y que ofrecen de forma gratuita o en versión comercial de pago.

Y como ventajas de WPF se podrían destacar:

Al ser más nuevo, está más acorde con los estándares actuales

Microsoft lo usa en gran cantidad de proyectos, por ejemplo, el propio Visual Studio

Es más flexible, y en muchos casos no hace falta recurrir a desarrollos de terceros

Está basado en separar el entorno gráfico en un archivo XAML y el código con la lógica en un archivo estándar .cs: esto permite que un especialista diseñe la parte gráfica (con ayuda de Blend de Visual Studio, por ejemplo) y un programador implemente el código

13

Page 25: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Enlaces de datos, binding, que permiten separar los datos de su representación gráfica

Aprender XAML revierte en tener también conocimientos que se pueden reutilizar en la programación de ASP.NET (programación web) y de Silverlight (web y móviles)

Mejor rendimiento gráfico: mientras que WinForms utiliza los antiguos métodos de renderización, WPF tiene acceso a los aceleradores gráficos por hardware.

En este proyecto se ha utilizado el entono WPF, de hecho, todos los ejemplos de Microsoft con Kinect se han desarrollado en este entorno: por un lado, como apuesta propia, y por otro lado por los requisitos hardware requeridos por Kinect: se necesita un entorno visual que descargue la carga del procesador, y esto WPF lo hace eficientemente gracias a la mejor utilización de los recursos hardware de gráficos que tenga el equipo utilizado.

En función de lo requerido, puede no ser necesario escribir código, y realizar sólo la parte visual.

14

<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta-tion" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Cen-ter" FontSize="72"> Hello, WPF! </TextBlock> </Grid>

Código 5. Primer programa WPF

Page 26: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Al contrario que en el primer ejemplo con salida en la consola de Windows, al ejecutar este programa nos mostrará una ventana con el texto “Hello, WPF!” en un elemento “Bloque de texto”

En entonos GUI antiguos como WinForms, toda la parte gráfica se hacía en el mismo lenguaje de programación que se estuviera haciendo en el programa, ya fuera C# o Visual Basic:NET. Esto impide pode reutilizar el mismo diseño gráfico en los dos lenguajes, teniéndolo que crear para cada lenguaje.

Con XAML se puede reutilizar la parte gráfica y cambiar sólo el archivo de código. Es un lenguaje similar a HTML, etiquetado. Para añadir un control, basta poner su nombre entre los símbolos <…>. Todas las etiquetas deben estar finalizadas, bien en la misma etiqueta, o con el indicativo de fin de etiqueta </…>

En el primer ejemplo se define un botón vacío.

15

Código 6. Salida primer programa WPF

<Button></Button> equivale a <Button />

<Button FontWeight="Bold" Content="A button" />Equivale a<Button>    <Button.FontWeight>Bold</Button.FontWeight>    <Button.Content>A button</Button.Content></Button>

Botón personalizado<Button>    <Button.FontWeight>Bold</Button.FontWeight>    <Button.Content>        <WrapPanel>            <TextBlock Foreground="Blue">Multi</TextBlock>            <TextBlock Foreground="Red">Color</TextBlock>            <TextBlock>Button</TextBlock>        </WrapPanel>    </Button.Content></Button>Equivale a<Button FontWeight="Bold">    <WrapPanel>        <TextBlock Foreground="Blue">Multi</TextBlock>        <TextBlock Foreground="Red">Color</TextBlock>        <TextBlock>Button</TextBlock>    </WrapPanel></Button>

Código 7. Ejemplos de botón

Page 27: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

El segundo botón tendrá el texto “A button” en negrita (bold): se puede observar como las propiedades pueden ir adjuntas en la propia etiqueta principal, o definirse por separado. La decisión de hacerlo de un modo u otro dependerá del propio desarrollador, aunque en ciertas ocasiones será necesario definir la propiedad por separado para poder ampliar las posibilidades.

En el tercer ejemplo se puede apreciar la potencia de WPF y la personalización de un control: el resultado sería un botón con tres textos, cada uno de un color diferente. Realizar esta sencilla adaptación requeriría de mucho más esfuerzo en WinForms (ojo, en ocasiones será al revés, y conseguir que un control de WPF se comporte como uno de WinForms requerirá una gran cantidad de trabajo).

Como en la mayor parte de entonos gráficos, los controles de WPF son capaces de responder a eventos: en este caso, el evento se asocia a alguna función del archivo de código.

En el código XML se ven la etiquetas y como se asocia el evento “MouseUp” a la función de C# pnlMainGrid_MoueUp.: analizando el código se puede ver que si se suelta el botón en cualquier punto de la ventana, se invocará la función creada en C#. La función que se invoca debe cumplir los parámetros definidos para ese evento, siendo el primero una referencia al objeto gráfico que ha generado el evento, y el segundo es una variable con una estructura propia de cada evento. Visual Studio nos brinda la oportunidad de crear la función en código con los parámetros correctos para

16

Código XAML<Window x:Class="WpfTutorialSamples.XAML.EventsSample" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta-tion" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="EventsSample" Height="300" Width="300"> <Grid Name="pnlMainGrid" MouseUp="pnlMainGrid_MouseUp" Background="LightBlue"> </Grid></Window>

Código C#private void pnlMainGrid_MouseUp(object sender, MouseButtonEven-tArgs e){ MessageBox.Show("You clicked me at " + e.GetPosi-

Código 8. Ejemplo de evento

Page 28: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

atender el evento correspondiente, o mostraría otros que hubiera ya creados y que pudiéramos utilizar por coincidir su definición.

Por último, veremos cómo funcionan los enlaces de datos. En este caso se creará un enlace, un “Binding”, entre dos controles de una ventana XAML, pero también se pueden crear enlaces con fuentes de base de datos: por ejemplo, los elementos de una lista desplegable pueden estar recogidos en una variable que lea los códigos de un fichero; con la configuración adecuada, las variaciones que se hagan en la variable que hace las funciones de fuente de datos, se verán automáticamente actualizadas en la

lista desplegable.

En este ejemplo se presenta un cuadro de texto en el que un usuario puede escribir, “TextBox” con nombre “txtValue”. Y a continuación dos bloques de texto, uno con un texto fijo, y el segundo con el enlace de datos: aquí se aprecian dos campos fundamentales:

ElementName que hace referencia al objeto con el que se quiere crear la conexión, en este caso con el cuadro de texto “txtValue”

Y en Path se establece la propiedad del objeto que se quiere enlazar, siendo el texto, “Text”, el que se desea reflejar en este control

Es decir, lo que se consigue es que el bloque de texto vaya actualizando su contenido con lo que el usuario está escribiendo en el en cuadro de texto: esto que requeriría de escribir cierta cantidad de código en otros entornos, en WPF se hace directamente en el entorno gráfico de la aplicación.

17

<Window x:Class="WpfTutorialSamples.DataBinding.HelloBoundWorldSam-

ple" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presen-

tation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="HelloBoundWorldSample" Height="110" Width="280"> <StackPanel Margin="10"> <TextBox Name="txtValue" /> <WrapPanel Margin="0,10"> <TextBlock Text="Value: " FontWeight="Bold" /> <TextBlock Text="{Binding Path=Text,

ElementName=txtValue}" /> </WrapPanel>

Código 9. Ejemplo de enlace de datos Binding

Page 29: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

No tienen porqué que enlazarse sólo campos de texto: por ejemplo, se podría enlazar el tamaño de dos objetos entre sí; o enlazar la posición de un control deslizante (como una barra de zoom) al tamaño de un objeto, de tal manera que al mover el cursor entre los valores mínimo y máximo, el objeto se haga automáticamente más grande o más pequeño, ya que otra de las cualidades de WPF, es que permite aplicar transformaciones a los objetos gráficos: traslaciones en el espacio, rotaciones, cambio de tamaño, etc.

Se pueden encontrar muchos tutoriales en Internet, tanto de C# en la documentación de Microsoft [11] más orientado a su uso con Visual Studio, y otros más genéricos [12]. Una vez conseguida una cierta soltura en C#, el siguiente paso sería adentrarse en el entorno WPF [6].

18

Page 30: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Kinect for Windows SDK y Developer ToolkitPara poder empezar a utilizar el dispositivo Kinect se necesita instalar

su SDK [11] que incluye los drivers para que Windows reconozca el dispositivo y poder trabajar con él.

El SDK incluye también las API que permiten controlar Kinect y obtener la información que se necesite. Permite la programación en C++, C# y Visual Basic, aunque no todas las funciones están disponibles en los tres lenguajes. Por ejemplo, las funciones de seguimiento facial no están disponibles en Visual Basic.

Junto al SDK hay que utilizar el Developer Toolkit [11], que contiene ejemplos, documentación y Kinect Studio. Kinect Studio es un software que es capaz de conectarse a un programa que esté usando el dispositivo Kinect: permite visualizar las imágenes que genera Kinect, tanto en color, infrarrojo y profundidad. También da la opción de grabar toda la información en disco duro, y reproducirla más tarde en el programa que está usando Kinect, sustituyendo de esta manera la información generada en tiempo real. Hay que tener en cuenta que Kinect Studio no sustituye un dispositivo Kinect: aunque se intente utilizar sólo para reproducir, es necesario que Kinect esté conectado.

Entre los ejemplos incluidos hay varios que demuestran la capacidad de monitorizar el rostro, el esqueleto entero, quitar el fondo, averiguar el ángulo por el que llega el audio, etc.

19

Page 31: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Kinect for Windows Runtime En los ordenadores donde se vaya a utilizar el programa de este

proyecto que controla el dispositivo Kinect se necesitará instalar el driver de Windows junto con las librerías que hacen de interfaz entre el driver y el programa. Como no se va a realizar ningún desarrollo, no es necesario instalar el SDK completo, solamente Kinect for Windows Runtime [13], que proporciona lo necesario para que Kinect funcione.

Si en el equipo que se ejecute el programa servidor no se va a conectar ningún dispositivo Kinect, es decir, va a ser independiente del programa cliente, no es necesario instalar este software.

20

Page 32: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Arquitectura de la aplicaciónIntroducciónEn primer lugar, se presenta el diagrama de uso de la aplicación

requerida:

Ilustración 2. Diagrama casos de uso

Para reducir la complejidad del programa, el proyecto se ha dividido en dos programas que se complementan entre sí, en una estructura cliente-servidor. El programa cliente se ejecutará en el PC del alumno que dispondrá de una Kinect que le grabará y monitorizará: los datos obtenidos (imagen del alumno, sus parámetros faciales y una copia de lo presentado en pantalla para relacionar la expresión con lo que está realmente viendo) se empaquetan y envían al programa servidor. El programa servidor recoge estos datos, los procesa según las reglas definidas y los graba en disco duro. Se ha decidido hacer esta división por varios motivos:

En primer lugar, permite que tanto el alumno como el experto que va a definir las reglas estén en lugares diferentes.

Permite recibir datos de varios alumnos, sin tener la necesidad de conectar todos los dispositivos Kinect al mismo equipo.

En el primer análisis de los recursos consumidos en un PC con una Kinect conectada y monitorizando una cara, se apreció un nivel medio-alto de carga de CPU del PC ejecutando el programa de test, por lo que añadirle también la tarea de procesar las reglas definidas, podía conllevar un bloqueo de un PC de gama media.

21

Page 33: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Análisis del dispositivo KinectLa primera toma de contacto con el equipo Kinect y su capacidad para

reconocer y modelar rostros se llevó a cabo con el programa demostración “FaceTrackingBasics-WPF”: este programa consta de una única ventana en la que se muestra la captura de la cámara de color, y cuando reconoce un rostro se superpone la máscara 3D a base de triángulos definida en CANDIDE-3. En las pruebas con este programa se verifica que Kinect es capaz de detectar y monitorizar dos rostros simultáneamente. Según podemos ver en las especificaciones de este equipo, es capaz de detectar hasta seis personas, de las cuales sólo a dos de ellas les puede hacer un seguimiento completo (esqueleto y cara), y de las otras cuatro sólo devolvería su posición [14]. En este documento se observa que la cámara de infrarrojos (la encargada de detectar posiciones, profundidad, etc.) tiene dos campos de visión configurables: “por defecto”, para detección de cuerpo entero con una distancia entre 0.8m y 4.0m (a efectos prácticos entre 1.2m y 3.5m), y “campo cercano” para detección entre 0.4m y 3.0m (a efectos prácticos entre 0.8m y 2.5). Este segundo modo, además permite seleccionar que tipo de detección del usuario queremos: “por defecto” para una persona que está de pie con visibilidad completa, y “sentado” para una persona a la que sólo se le ve (por parte de Kinect) de cintura para arriba; éste es nuestro caso, un usuario cerca de Kinect y sentado en una mesa manejando su ordenador.

El siguiente programa demo incluido en el kit de desarrollo de Kinect es “Face Tracking Visualization”. En este programa se visualiza al usuario con la máscara 3D sobre el rostro, y adicionalmente en un lateral una reconstrucción simple del estado de los puntos muestreados.

Ilustración 3. Face Tracking Basics-WPF vs. Face Tracking Visualization

Como se puede ver en las capturas incluidas en el kit de desarrollo [12], en la segunda aplicación se añade un dibujo con la boca, cara y cejas, que son los principales puntos que supervisa Kinect. Si analizamos el código, nos

22if (AU[3] > 0.1f && AU[5] > 0.05f) { // If the eyebrows are lowered, draw angry eyes m_LowerEyeLid = AU[3]*AU3EyelidsCoefficient; m_UpperEyeLid = 0; }

Page 34: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

encontramos que aquí se analizan las AU de CANDIDE-3 que nos interesan. He aquí la captura del código:

En caso de no tener información suficiente sobre los ojos, intenta determinar cómo estarían en base a los labios y las cejas: si los labios están muy juntos, si están hacia abajo, si las cejas están levantadas, etc., es decir, está intentado determinar la emoción que expresa el individuo para dibujar los ojos para que concuerde con el resto de la expresión.

Aquí se ve el uso para el cual se definió CANDIDE-3: representar un rostro humano por ordenador, y poder simular sus emociones. Si bien se representa la máscara 3D de acuerdo al rostro monitorizado, bien podrían modificarse los parámetros para dibujar un rostro cualquiera, y utilizar las AU del usuario monitorizado para modificar y expresar las emociones en ese nuevo rostro inventado. Podemos encontrar ejemplos de este tipo en algunos juegos de Xbox (como Avatar Kinect [15]) y en películas (aunque en estos casos en vez de usar Kinect se usan sensores adheridos al cuerpo y cara del actor, cuyos actos y expresiones se ven reflejados en seres animados por ordenado, pero están basados también en monitorizar las AU).

Inicialmente hay que comenzar estudiando las capacidades de Kinect para monitorizar [4] rostros y la validez de los datos suministrados. Para ello se modifica el ejemplo utilizado “FaceTrackingBasics-WPF” incluyendo unas etiquetas (“label”) que se vinculan al valor de las AU que proporciona Kinect.

23

if (AU[3] > 0.1f && AU[5] > 0.05f) { // If the eyebrows are lowered, draw angry eyes m_LowerEyeLid = AU[3]*AU3EyelidsCoefficient; m_UpperEyeLid = 0; }

Page 35: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Si nos fijamos en los valores umbrales de las AU que se usan en el programa ejemplo “Face Tracking Visualization” vemos que no son exactamente iguales a los definidos en la documentación de Kinect de Face Tracking [4].

Para la prueba nos fijamos en la AU 6, que se corresponde con la parte exterior de las cejas: según documentación, es una variable que toma valores entre -1 (cejas bajas) y +1 (cejas altas), siendo 0 el valor neutro. Se observa que en reposo el valor es ligeramente superior a 0, pero según los umbrales del programa ejemplo, equivale a “cejas bajas”; para llegar al umbral “de reposo” hay que subir las cejas; y para que lo detecte como “cejas altas” hay que forzar mucho la posición. Para conseguir un valor negativo también hay que forzar mucho la posición, y en ningún caso se acerca al valor límite inferior -1.

Aparece el primer problema: ¿qué considera el hardware/software de reconocimiento como posición neutra? A primera vista no hay ninguna función que nos permita decirle al software cuál es dicha posición neutra.

El segundo problema se ve en las medidas de distancia entre puntos que se obtienen del cálculo de las posiciones tridimensionales que vuelca Kinect. Recordemos la expresión matemática:

d=√(X1−X0)2+(Y 1−Y 0)

2+(Z1−Z0)2

Como se puede apreciar en las etiquetas de la ceja izquierda y derecha, las medidas son exactamente iguales, a pesar de estar forzándose un gesto con una ceja subida y la otra bajada: al no proporcionar los datos reales, sino los interpretados y proyectados, Kinect realiza una tarea de simetría:

24

Ilustración 5. Medidas de distancias

Page 36: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

compensa el lado izquierdo con el derecho, de manera que no se obtienen datos completamente reales.

Tercer problema: la documentación de la API del SDK en relación al seguimiento de rostros en C# no existe. Existe documentación del resto de funciones de Kinect tanto para C++ como para C#, pero del seguimiento de rostros sólo hay documentación completa de las funciones de C++ [16]; en C# hay que ir abriendo cada fichero del SDK y ver qué funciones hay disponibles, cuál es su cometido y cómo se usa con ayuda de los comentarios (al menos la parte de los comentarios sí está relativamente bien documentada). Tercer problema: comparando con la documentación de C++ hay un par de funciones, importantes para el proyecto, que no "existen" en C#.

La primera función que no está completamente disponible es “GetShapeUnits” [17]. Buscando entre los ficheros nos encontramos con la función equivalente en C#, pero no está disponible para su uso directo por cualquier programa que use el SDK: en este caso es sencillo hacer una implementación que sí sea accesible. En el fichero Utils.cs de “Microsoft.Toolkit.FaceTracking” se crea una lista nueva con las referencias de las SU, que luego serán devueltas en la nueva función implementada en la clase FaceTrackFrame perteneciente al mismo Toolkit.FaceTracking. De acuerdo con CANDIDE-3, las SU son elementos no variables del rostro ya que representan la altura de la cabeza, distancia entre ojos, ancho de la boca, etc. y que podrían usarse para asociar un rostro con un usuario concreto; sin embargo, no se estudiará la validez de estos datos ya que se salen del contexto de este proyecto. Lo que interesa de “GetShapeUnits” es el parámetro “hasSuConverged” que también devuelve esta función: nos indica que el reconocimiento facial se ha completado, por lo que a partir de ese momento se pueden considerar válidos el resto de los valores devueltos por las otras funciones de reconocimiento facial.

La segunda función que es de interés para este proyecto y que tampoco está disponible para C# es “GetShapePoints”: las funciones que sí están disponibles nos devuelven la posición de los puntos 3D utilizados por Kinect para realizar la representación 3D en pantalla del rostro; al no tratarse de los puntos que realmente se están monitorizando, no se pueden considerar completamente válidos. La función que está disponible en C# no tiene parámetros, pero si analizamos el código del SDK, se ve que llama a unas funciones complementarias cuyos parámetros entre otros están las AU y las SU calculadas: es decir, el modelo 3D que devuelven las funciones no son los puntos que se están muestreando, sino una representación espacial

25

Page 37: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

creada en base a unos parámetros; de hecho, la versión C++ de esta función sí requiere que se le pasen manualmente dichos parámetros, con lo que se puede modificar la máscara 3D al antojo del programador. Esto podría ser muy útil, por ejemplo, para la creación de un Avatar como se comentaba anteriormente [15]: se obtienen las SU del jugador para crear una cara con sus mismos rasgos y a continuación se pasan diferentes AU a la función IFTModel::GetProjectedShape2 de C++ para obtener una representación facial sonriente, pensativa, enfadada, etc., es decir, se aplicaría CANDIDE-3 para obtener una representación digital, justo lo opuesto a lo requerido en este proyecto. Todo esto se puede encontrar explicado en el blog de Kinect [18]: en este blog nos encontramos con la función wrapper para C# de la ya existente en C++ Get2DShapePoints. Tal como se explica en dicho blog, esta función nos devuelve los puntos que Kinect está realmente muestreando, aunque en 2D ya mapeados sobre la imagen en color: se pierde la coordenada real 3D, necesaria para calcular la distancia real entre puntos. Aunque no sean los puntos realmente muestreados, será necesario usar la coordenada Z de ciertos puntos 3D de la máscara generada y añadirla a los puntos 2D muestreados

2 En C# se necesitaría hacer una función complementaria (wrapper), tal como se ha hecho con GetShapeUnits

26

Page 38: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Programa clienteUna vez conseguidas las funciones que faltaban, se incluye el módulo

de reconocimiento facial del blog anteriormente mencionado en el programa KinectExplorer-WPF incluido en el SDK. Este módulo le permite al usuario elegir tres visualizaciones:

1. Máscara 3D

2. Puntos característicos (puntos en los que se basa la máscara 3D)

3. Puntos muestreados

Tal y como se explica en el blog, elegir más de una visualización repercute en una pérdida de fluidez, incluso la imposibilidad de hacer nada con el programa. Esto se debe a que los puntos característicos y muestreados se muestran como dígitos de texto; se ha modificado el método de representación gráfica para que el programa vaya fluido, aunque se seleccionen las tres opciones y de esta forma no perder datos.

Como este programa residirá en el equipo del usuario hay que incluir también un cliente de red que se conecte con el servidor y le envíe los datos de los puntos muestreados, la imagen en color y una captura del escritorio (para que la persona que analice las reacciones del usuario sepa que está viendo en ese momento en pantalla). El cliente de red será un módulo de conexión y transmisión asíncrona, de tal manera que no bloquee la interfaz de usuario al enviar y recibir datos.

En la aplicación principal se han incluido dos opciones nuevas, servidor y modo:

En el campo servidor se indica el nombre o dirección IP del equipo que va a recibir los datos que se envían desde el programa cliente: cambiar este parámetro provocará reiniciar el canal TCP/IP con el servidor, por lo que se pide al usuario confirmación de este cambio. Al reiniciarse esta conexión pueden llegar a perderse datos si el servidor tarda en responder.

La opción "modo" permite al usuario seleccionar si quiere ser monitorizado o si quiere hacer pruebas con el dispositivo Kinect. El modo “Kinect” da acceso a todas las configuraciones de video, habilitar/deshabilitar el seguimiento, etc.; al seleccionar el modo "Análisis" se deshabilitan ciertas pestañas de la configuración para evitar que el usuario las modifique, como son:

27

Page 39: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

el modo de video: se ha preseleccionado el modo de mínima resolución posible con una calidad aceptable para que la cantidad de datos a transmitir por la red y, por ende, para almacenar en el servidor, no sea excesiva

el seguimiento del esqueleto: tal y como se ha comentado, Kinect puede seguir hasta seis esqueletos, pero sólo dos de ellos de forma completa. Se puede elegir de qué esqueleto o esqueletos queremos hacer ese seguimiento completo y que nos devuelva todos sus puntos: se puede indicar el identificador3 del esqueleto, el más cercano, el más activo, etc. En nuestro caso nos interesará el más cercano, que se corresponderá con el usuario que está sentado frente a la Kinect.

el modo "sentado" y "cercano" para la correcta monitorización de la cara, ya que esta sería la posición correcta del usuario.

Durante las pruebas se han intentado hacer las capturas de pantalla a la misma velocidad que se reciben las capturas de Kinect, es decir, 30 capturas por segundo: sin embargo, posiblemente por limitación del framework .NET, durante las pruebas del programa se comprueba que escribir en pantalla a un ritmo de 30 imágenes por segundo la señal de video de Kinect e intentar capturar el escritorio al mismo ritmo, provoca que el programa se ralentice hasta bloquearse. Por dicha razón, y dado que no necesitaremos mucha calidad de video del escritorio, las capturas se hacen a un ritmo de 1 captura cada 15 frames, es decir, quince imágenes recibidas de Kinect. El formato de estas capturas sería el equivalente al formato bmp de los archivos de imagen, por lo que, si guardáramos esta información directamente, se ocuparía mucho espacio de disco. Una opción sería codificar esas imágenes en un formato de video, sin embargo, no se encuentran opciones disponibles que hagan este proceso en tiempo real, al menos en el lenguaje de programación elegido, C#. Se podría implementar la funcionalidad en una librería en C++ que pudiese ser invocada desde nuestro programa; en cambio, se ha preferido mantener el desarrollo de todo el proyecto en C#, y se ha creado un pseudo-formato de video con las imágenes de las capturas de pantalla y las imágenes recogidas de Kinect (recordemos que de Kinect sólo obtenemos imágenes fijas a un ritmo de 30fps, que al presentarlas de forma continua en pantalla da la sensación de ser un streaming de video, aunque en realidad no es así): estas imágenes se

3 El identificador es un número que asigna Kinect a un esqueleto en cuanto lo detecta, pero no es fijo: si un usuario identificado sale del campo de visión de Kinect y vuelve a entrar, Kinect le asignará un identificador diferente

28

Page 40: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

comprimen en formato jpg, y se generan unos índices de posición y tiempo. Las imágenes junto a los índices y los datos de muestreo de Kinect se envían al servidor a un ritmo de 1 frame cada 80 ms., es decir, 12,5 fps. Se elige este tiempo en base a las pruebas realizadas como compromiso entre calidad de imagen de video enviada y rendimiento del PC que realiza el trabajo. En la función que debe comprimir la imagen de Kinect, se ha añadido una comprobación extra que detecta si la velocidad de presentación en pantalla ha descendido de 25fps, en cuyo caso no se genera una nueva imagen jpg, si no que se mantiene la anterior, al igual que se hace con las capturas de pantalla.

Por último, se añade un cuadro de diálogo que aparece al inicio de la conexión con el equipo Kinect en el que el usuario debe introducir su identificador, que se usará para identificar en el servidor la procedencia de los datos y guardarlos correctamente. En caso de que no se introduzca ningún identificador, se tratará como una sesión anónima. Como luego veremos en el servidor, podremos rechazar esta conexión o aceptarla.

El módulo cliente de la conexión TCP se basa en las funciones de conexión asíncrona provistas por C#. Se ha elegido el modo asíncrono frente al síncrono para que no se quede el programa congelado en caso de que una transmisión se quede bloqueada por cualquier problema en la red o el servidor: el modelo elegido es basado en un Timer que se dispara cada 80ms. para conseguir la anterior mencionada tasa de 12,5fps. Sin embargo, este Timer no es totalmente exacto, ya que se priorizan los eventos gráficos como pulsaciones del usuario, movimiento o redimensión de la aplicación, etc. Aquí es donde el modo de conexión asíncrona entra en juego, ya que se invoca la función de envío de datos y el programa no se queda esperando su finalización, sino que se le indica otra función que se ejecutará automáticamente una vez se hayan terminado de enviar los datos: todo esto sin perjuicio del funcionamiento de los niveles inferiores TCP, que se encargarán de las retransmisiones necesarias y reordenación de los paquetes de información sin que afecten a nuestro programa. En el inicio de la conexión se envía el identificador que haya introducido el usuario en el cuadro de diálogo mencionado en el párrafo anterior. El resto de envíos ya contendrá la información proporcionada por Kinect de todos los puntos mencionados anteriormente, la imagen en color capturada por Kinect y una captura de pantalla del monitor principal: aunque el usuario tenga varios monitores en configuración “escritorio extendido”, sólo se captura el que figure como principal, no sólo por el volumen que podría llegar a tener capturar varios monitores, si no, porque el psicólogo que utilice el programa

29

Page 41: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

de análisis, puede no tener los suficientes recursos como para visualizar varias capturas y la imagen de Kinect en su propia pantalla. Además, de esta manera si un usuario mantiene nuestra aplicación en su segundo monitor, la aplicación no se captura a sí misma, porque sólo va a enviar lo que ocurra en el monitor principal.

30

Page 42: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Programa servidorLa aplicación servidor "Análisis Emocional" no parte de ninguna base

creada hasta ahora, y se ha desarrollado íntegramente para este proyecto. Esta aplicación tiene dos funcionalidades:

Recoger y grabar en disco la información que envían las aplicaciones clientes que ejecutan los usuarios

Realizar todo el procesamiento relacionado con el reconocimiento de las emociones requerido en este proyecto

La primera función se lleva a cabo mediante un servidor TCP asíncrono: este servidor está integrado en el programa, aunque podría haberse desarrollado como una aplicación aparte o incluso como un servicio de Windows. A pesar de estar integrado en el programa, como se utilizan los métodos asíncronos, su funcionamiento no interfiere la funcionalidad y fluidez del resto del programa. Al arrancar el servidor, éste se queda escuchando en todas las interfaces de red del equipo por un puerto predefinido para nuestra aplicación. Cuando recibe una conexión entrante, le envía una notificación al programa principal indicándole la identidad del usuario: si es un usuario ya dado de alta, el programa principal le indica al servidor que acepte la conexión; si es un usuario nuevo, es la persona que está ejecutando el "Análisis Emocional" el que debe decidir si aceptar y dar de alta el nuevo usuario o no. En caso de que al servidor se le dé la orden de aceptar la conexión, éste empieza a grabar en disco tres ficheros en la carpeta correspondiente del usuario:

Los datos de los puntos obtenidos por Kinect en un archivo .dat

Las imágenes comprimidas en formato jpg de la captura en color de Kinect y del escritorio en un archivo .img

Los índices de posición que sincronizan el archivo de datos y el de vídeo en un archivo .idx

Cuando el servidor recibe la desconexión de la aplicación usuario, vuelve a notificar al programa principal tal circunstancia para indicar que se ha finalizado la grabación de la sesión.

Por su parte, el programa principal consta de cuatro módulos:

Pantalla principal

Gestión de usuarios

31

Page 43: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Gestión de reglas

Pantalla de análisis

En la pantalla principal se muestra el listado de usuarios dados de alta con sus datos (identificador, nombre, descripción, fotografía y reglas aplicadas). Este listado se ha realizado aprovechando las funcionalidades de WPF de aislar los datos y la representación: para ello, en la parte del código se ha definido un nuevo tipo de datos (KinectUserCollection) que actúa como fuente de datos y que es capaz de notificar cambios que se realicen en sus datos internos a los elementos que se hayan enlazado con dicha fuente de datos. Y en la parte visual se ha dado de alta un "DataGrid", un elemento que permite representar fácilmente una base de datos basada en una "Collection" como la que se ha implementado en código para este proyecto. El elemento "DataGrid" proporciona por defecto celdas de tipo "Texto" de sólo lectura (TextBlock) y de escritura (TextBox) para editar directamente la base de datos desde esta representación visual; sin embargo, en nuestro caso se ha deshabilitado la escritura ya que la edición de usuarios requiere unas funciones más complejas y se ha desarrollado un módulo específico para esta labor. Sí se han mantenido las funciones de re-colocar columnas, cambiarlas de tamaño y ordenar por una columna determinada. También se han personalizado ciertas columnas para cambiar las celdas predeterminadas por una imagen con la foto del usuario correspondiente, otra con una lista de reglas activas y otra con un botón que abre la ventana de análisis del usuario correspondiente.

En la ventana principal hay dos botones para acceder a la gestión de usuarios y reglas: si se pulsa cualquiera de ellos, el otro queda deshabilitado. Esto se debe a la relación que hay entre ambas colecciones de datos: en cada usuario hay una referencia a todas las reglas existentes (referenciadas por un identificador de regla) con una marca indicando si la regla está activa para dicho usuario, es decir, se permite al psicólogo o persona que utilice el programa crear reglas que pueda aplicar a ciertos grupos de personas (por ejemplo, según sus rasgos), e incluso reglas personalizadas para algún usuario que tenga alguna particularidad. Por otra parte, las reglas tienen la relación de usuarios que las están usando, de manera que una regla no se pueda borrar mientras que haya algún usuario que tenga dicha regla activa. Cuando se cierran las ventanas de gestión de usuarios o reglas, se hace una actualización bidireccional entre las tablas de reglas y la de usuarios, de tal manera que los usuarios tengan el listado de reglas actualizado, y las reglas también tengan correctamente la relación de usuarios que las están usando (para prevenir el borrado accidental de una regla). Esta comprobación

32

Page 44: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

bidireccional también se realiza durante el inicio del programa, después de cargar los datos de ambas tablas de sus correspondientes ficheros: estos ficheros están en formato xml, y son editables, de tal manera que puedan leerse y modificarse fácilmente desde un editor xml externo. Si se realizara una asignación incorrecta de usuarios y reglas directamente en el fichero, estas serían corregidas en esta comprobación. De los ficheros de reglas y usuarios, el programa siempre deja la copia anterior (con la extensión .backup) antes de escribir los nuevos datos, de tal manera que existe una posibilidad de recuperar los datos antiguos en caso de que el programa no fuera capaz de leer correctamente los datos actuales.

La ventana de usuarios se ha basado implementado una vista de pestañas, en la que cada pestaña es una identidad de usuario. Esta vista usa un “TabControl” que se ha tenido que personalizar para adecuarla a los datos que contiene un usuario:

Al realizar la prueba de añadir muchos usuarios, sólo se mostraban las pestañas para acceder a los primeros, mientras que los últimos en ser añadidos no aparecían. En este sentido ha sido necesario “encapsular” las pestañas en un control “ScrollViewer”, de tal manera que, al sobrepasar la cantidad de pestañas visibles en la ventana, se activa una barra de desplazamiento que permite moverse entre todos los usuarios.

La zona de presentación del “TabControl” no consta de un solo tipo de datos, o algo representable en una tabla. Cada usuario consta de un texto de una sola línea con su nombre completo, un texto multi-línea con una descripción o notas que se quieran realizar, una lista con checkbox de las reglas que se usan con el usuario seleccionado y por último una foto del usuario con los correspondientes botones para cargar una nueva foto o eliminarla y dejar una representación básica (esta foto es sólo un dato para facilitar el reconocimiento visual del usuario por parte de la persona que usa el programa, pero no es imprescindible para el análisis).

La ventana de edición de reglas también es una vista personalizada basada en un "TabControl". Las pestañas se han integrado también en un "ScrollViewer" para poder moverse por una larga lista de reglas. En cuanto al contenido de cada regla, consta también de un texto de una línea con su nombre y un texto de varias líneas con la descripción. A continuación, constará de una lista de condiciones basadas en distancias entre dos puntos,

33

Page 45: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

un porcentaje de variación (positivo o negativo), un tiempo durante el cual debe cumplirse la variación de distancia y una línea descriptiva de esa medición. Los puntos a medir elegidos se podrán elegir en base al método FACS, aunque en este caso el psicólogo o persona que use el programa podrá personalizar las reglas para aprovechar las capacidades o suplir las carencias que pueda tener el dispositivo Kinect: como se vio durante el análisis previo de Kinect, las medidas que proporcionaba de las AU no eran del todo fiables, sobretodo porque dependiendo de la persona monitorizada, las variaciones de las AU eran mayores o casi imperceptibles. En este sentido se pueden combinar en las reglas mediciones entre los puntos 2D o los puntos 3D. También se ha añadido la posibilidad de seleccionar puntos de Kinect V1 o V2: recientemente ha aparecido un nuevo dispositivo Kinect con cámaras de mayor resolución que proporcionan monitorización de más puntos: se ha probado a cargar el SDK del nuevo Kinect, pero no funciona con el equipo de este proyecto; esto afectará al programa cliente, pero no al servidor.

Con la capacidad de tener más o menos puntos por regla, 2D y 3D, de Kinect V1 y V2, y la posibilidad de activar o no la regla en usuarios concretos, se puede conseguir que el programa detecte automáticamente la emoción correcta basada en sus propios rasgos.

Por último, la ventana de análisis se divide en dos secciones: en una de ellas se encuentra el reproductor, para lo que se ha creado un control de usuario que opera en segundo plano: se encarga de leer los tres archivos y presenta en pantalla las dos imágenes que se habían captado (cámara de Kinect y captura de escritorio); en cada pasada se genera también un evento con los datos de los puntos que se corresponden a esas imágenes. Enlazado con ese evento está otro control de usuario que dibuja los puntos o la malla 3D igual que podía ver el usuario monitorizado. El mismo evento invoca también la función propia de análisis de reglas: esta función será la que maneje los puntos que ha recibido, mida las distancias entre los puntos especificados en las reglas del usuario y las compare con sus valores neutros; los resultados los devuelve en forma de lista con las reglas analizadas y sus porcentajes de cumplimiento. El reproductor tiene también un botón que permite definir el aspecto en reposo/neutro del usuario estudiado: hasta que no se define el perfil neutro no se permite realizar ningún etiquetado ni se puede realizar el control de las reglas. La segunda zona de esta ventana consta de la parte propia del etiquetado: en primer lugar, hay tres casillas seleccionables para habilitar/deshabilitar el dibujo de los puntos 2D, la malla 3D y los Feature Points (FP). En el listado de las

34

Page 46: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

sesiones grabadas de ese usuario se selecciona la que se quiera analizar. A continuación, tres listas desplegables con unas etiquetas que se han solicitado en relación al proyecto MAMIPEC: los valores de estas listas se cargan de un fichero de texto editable, de tal manera que se puedan añadir y/o modificar los valores actuales. También se requería un cuadro de texto para poder acompañar con datos adicionales la situación en la que se ha detectado la emoción y/o realizado el etiquetado. Una tabla muestra las reglas analizadas y su porcentaje de cumplimiento: esto está acompañado de una selección de umbral de cumplimiento. En este selector se puede especificar que las reglas se den por cumplidas cuando el porcentaje de distancia especificado en la regla entre puntos superen el porcentaje del umbral seleccionado; se ha añadido esta variante para poder probar si el nivel de exigencia que se le ha puesto a una regla es excesivo y no tener que modificarlas continuamente buscando el ajuste más preciso. Cuando una o varias reglas superan o igualan el umbral establecido, se pausa la reproducción de la sesión para que la persona que está realizando el análisis pueda añadir las etiquetas que crea conveniente. A pesar de no cumplir ninguna regla, el etiquetado se puede llevar a cabo en cualquier momento, para que se pueda dejar constancia de los sucesos que se crean necesarios: se grabará la entrada correspondiente con el porcentaje de cumplimiento de las reglas, para su posterior evaluación.

En la barra de tiempo del reproductor de video se generan unas marcas en los momentos en los que se ha detectado una regla o se ha realizado un etiquetado. También hay disponible un desplegable con dichos momentos que posiciona el vídeo en el momento temporal exacto de la detección.

35

Page 47: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Modelo de conocimiento de la aplicaciónAplicación cliente

Ilustración 6. Programa cliente, diagrama clases principal

En Visual Studio C# se parte de una clase App que es la encargada de iniciar la clase principal de la aplicación. En este caso se inicia un objeto de tipo MainWindow, que es el encargado de supervisar los equipos Kinect (KinectSensorItemCollection) y su estado (KinectStatusItem). Cuando detecta un equipo Kinect genera un objeto del tipo KinectSensorItem con el que se supervisa: una vez que la Kinect se encuentra preparada, genera una ventana del tipo KinectWindow pasándole el Id de la Kinect correspondiente.

En KinectWindow encontramos la propiedad KinectSensor con el Id de la Kinect recibido, y del cual se obtendrá toda la información. Las funciones que encontramos en esta clase son:

Asociar el Id de Kinect en la propiedad KinectSensorManager, la cual es un wrapper que replica las funciones del objeto Kinect y le añade unas características adicionales como poder hacer un binding y recibir notificaciones de cambio de estado

Al cargar la ventana se invoca un cuadro de diálogo UserRequestDialog que pide al usuario su identidad y se la pasa al módulo de reconocimiento facial, para que luego se le identifique correctamente en el servidor

Indica al módulo de reconocimiento facial FaceTrackingViewer que puntos debe representar: malla 3D, los puntos de contorno 2D y los puntos FP sobre los cuales se basa la malla 3D.

36

Page 48: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Ventana visualización KinectTodos los elementos visuales están derivados de la clase base

KinectControl que contiene la propiedad KinectSensorManager de tal manera que todos comparten las mismas funciones y capacidades. Cualquier mejora que se quisiera hacer, se realizaría sobre esta propiedad y todos los componentes recibirían el cambio.

Ilustración 7. Programa cliente, diagrama clases KinectWindow

Ilustración 8. KinectWindow, elementos visualizadores (1/2)

Ilustración 9. KinectWindow, elementos visualizadores (2/2)

Los dos elementos que se han modificado han sido KinectSettings y FaceTrackingViewer. En el primero se han modificado:

37

Page 49: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

En la parte visual se ha añadido un control seleccionable para activar el modo de análisis (que envía todos los datos al servidor con una configuración predeterminada) o el modo Kinect (con la que el usuario puede experimentar con todos los ajustes del dispositivo). Justo debajo de esta selección se encuentra la dirección IP o nombre del servidor al que se debe volcar toda la información.

En el archivo de código correspondiente a la parte visual se controla la tecla “Enter” en el cuadro de texto que tiene la información del servidor: se ha creado un enlace de datos, binding, entre este cuadro de texto y la variable que almacena el dato. El enlace de datos tiene varias maneras de actualizar la variable a la que hace referencia: en este caso, se ha forzado para que no se actualice hasta que el cuadro de texto pierda el cursor “LostFocus” o que el usuario pulse la tecla “Enter”, ya que no tiene sentido que se varíe la variable del servidor mientras el usuario escribe, sino cuando ya ha terminado de hacerlo.

Este control representa gráficamente los datos contenidos en el modelo KinectSettingsViewModel, que contenía todas las configuraciones de Kinect: formato de la imagen color, de la imagen en profundidad de campo, la infrarroja, la elevación de las cámaras, … Es en este modelo donde se han añadido las dos nuevas propiedades que se visualizan, SelectedUserMode y SelectedServer.

SelectedUserMode contiene una validación que consiste en presentar un cuadro de diálogo al usuario preguntándole si realmente quiere cambiar de modo. Si se acepta el cambio, el programa actúa de la siguiente manera:

Si se activa el modo “Análisis”, se guarda el estado de todas las configuraciones que se deben cambiar, y se activan las configuraciones de Kinect necesarias para el análisis.

Si se activa el modo “Kinect”, se restauran las configuraciones de Kinect al estado anterior con las modificaciones que hubiera hecho el usuario. Si no hay estado anterior, se quedan las mismas configuraciones que en modo “Análisis”, pero ya se permiten cambios por parte del usuario.

En ambos casos, las configuraciones que se pueden o no modificar por el usuario están especificadas en el código visual, ya que se establece un

38

Page 50: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

enlace entre el estado activo o no en función del modo seleccionado y el conversor UserModeConverter que devuelve verdadero o falso.

SelectedServer tiene definidas tres funciones para ser invocadas al realizar un cambio en la variable:

SelectedServerCoerce verifica que no se hayan escrito caracteres no válidos en el nombre del servidor y los elimina, informando al usuario de tal circunstancia.

SelectedServerValidateCallBack comprueba que el nombre del servidor no está en blanco, en cuyo caso se rechazaría el cambio.

SelectedServerChanged se invoca si la anterior función ha dado un resultado positivo y le pide confirmación al usuario del cambio. En caso de ser afirmativo, se lleva adelante la configuración del nuevo servidor, y si el usuario lo rechaza, se restablece el nombre de antiguo servidor sin que el resto de módulos detecte ningún cambio.

SelectedUserMode y SelectedServer se han creado también en KinectSensorManager y están enlazadas con las propiedades de KinectSettingsViewModel, por lo que un cambio en este módulo es recogido

en todos los visualizadores.

39

Ilustración 10. KinectSensorManager en KinectControl

Page 51: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Control de seguimiento facialEste módulo es el que se ha combinado con el ejemplo original de

Microsoft para dibujar los puntos/malla del rostro detectado, y se ha ampliado para enviar esta información al servidor correspondiente.

Este sería su esquema:

El control FaceTrackingViewer se encarga de la conexión con Kinect y de recibir todos los datos. Aquí se detectan los rostros y los monitoriza con ayuda de la sub-clase SkeletonFaceTracker: se crea un objeto de esta sub-clase por cada persona que detecta Kinect y hace un seguimiento de su rostro. En el proceso inicial del ejemplo incluido en el Developer Toolkit [12] se asocia el evento AllFramesReady que genera Kinect cada vez que ha capturado todos los datos (imágenes color, infrarrojos, profundidad, monitorizaciones, etc.) el método KinectAllFramesReady: aquí se enumeran

40

Ilustración 11. Programa cliente, seguimiento facial

Page 52: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

todas las personas que controla Kinect, se comprueba si ya tienen creado el objeto SkeletonFaceTracker correspondiente (creándolo si no existiera) y le pasa los datos actualizados. Una vez terminado, se le indica al entorno visual que debe re-dibujar este control. Más tarde, cuando dicho control recibe la orden de actualizar su presentación OnRender, éste ejecuta el método DrawFaceModel de cada objeto asociado a una persona.

En ejemplo sólo se visualiza la malla 3D, pero no explora la totalidad de puntos FP. Esa es la funcionalidad añadida en los blogs de desarrollo [18], y que se basa en 3 campos: draw3DMesh, drawFeaturePoints y drawShapePoints, asociados a las correspondientes casillas de verificación mostradas en la ventana del programa:

draw3DMesh controla la presentación de la malla 3D dibujada en el método original DrawFaceModel.

drawFeaturePoints controla la presentación de los puntos FP, bases de la monitorización. Es este caso, no es una casilla de verificación sino un desplegable que permite elegir entre ver el número del punto (dentro de la lista de puntos generada por Kinect) o ver el nombre significativo de dicho punto.

drawShapePoints permite dibujar los puntos de contorno que se obtienen de la nueva función Get2DShapePoints que se crea como wrapper de la función equivalente en C++ dentro de las herramientas de seguimiento facial de Microsoft.

Estas dos representaciones se realizan en las funciones SetFeaturePointsLocations y SetShapePointsLocations. Inicialmente se utilizaban controles Etiquetas (Label) para escribir en pantalla el número o texto de cada punto. Sin embargo, en un programa de alto procesamiento como este, ese trabajo adicional sobrecargaba el equipo de pruebas y la experiencia visual al ejecutar el programa era muy pobre. Por tanto, se sustituyeron las funciones FindTextControl y UpdateTextControls por la función pre-existente DrawGlyphRun del contexto visual junto a CreateGlyphRun para dibujar el texto en pantalla utilizando recursos gráficos: el texto pierde algo de nitidez, pero la velocidad de representación es bastante superior.

41

Page 53: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Recogida de datosEsta funcionalidad se ha dividido entre el control principal

FaceTrackingViewer y su sub-clase SkeletonFaceTracker. En la recepción de datos de Kinect en la función KinectAllFramesReady se analiza cuál es la persona más cercana al sensor (debería ser la que está utilizando el ordenador, si está todo correctamente colocado) y se le pide al correspondiente objeto que devuelva todos los datos necesarios para el análisis: imagen en color de Kinect, captura de pantalla y todos los datos de los puntos recibidos (se muestren o no en pantalla). La captura de pantalla, TakeScreenShot, sólo se realiza en uno de cada quince muestreos (Kinect trabaja a un ritmo de unos 30FPS) por los motivos de rendimientos expuestos durante el análisis del proyecto. Al igual que tampoco se actualiza la imagen en color procesada si la presentación en pantalla baja de 25FPS. Ambas imágenes se comprimen en formato jpg en vez de usar el original bmp que consumiría mucho espacio en el disco del servidor y ancho de banda de la red. Los datos se codifican en una estructura de datos serializable por XML, SerializableFaceTrackingData. Una estructura de datos se puede codificar de varias maneras para enviarla entre dos equipos, como pueden ser el formato binario y el XML: en modo binario hay que tener en cuenta las representaciones numéricas internas de los dos equipos; también se complica la modificación de la estructura de los datos, que hay que realizarla tanto en el servidor como en el cliente de forma simultánea. En cambio, al enviar esos mismos datos bajo un esquema de etiquetas como XML, con identificadores estándar, es mucho más sencilla la reconstrucción de los datos y la inclusión de mejoras. Por ejemplo, se puede incluir en una nueva fase un nuevo dato en el programa cliente, que el servidor descartará directamente, sin ningún problema por no reconocerlo como suyo, hasta que se haga la correspondiente actualización. Y lo mismo a la inversa, es decir, si se la estructura de datos del servidor tiene más campos que los enviados por el cliente, se quedarán sin inicializar, pero no generarán ningún error (será responsabilidad del programador no utilizar esos campos no inicializados).

A pesar de ser un proceso separado de la presentación en pantalla, la respuesta visual de la aplicación puede verse afectada en cierta manera, ya que hasta que no se terminan todos los procesos no se le indica al hilo principal de la aplicación que debe actualizar la presentación visual.

Para que el envío pueda realizarse se genera un evento de forma periódica que invoca el método serverCheckTimer_Elapsed que comprueba la conexión con el servidor o si el usuario ha cambiado el servidor sobre el

42

Page 54: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

cual se debe enviar la información. En caso de alguna eventualidad, reinicia la conexión.

Por otra parte, se crea otro evento temporizado para el propio envío de datos. A diferencia del temporizador anterior que trabaja sobre el hilo principal de la aplicación por realizar procesos sencillos que no consumen excesivos recursos, sendTimer_Elapsed trabaja en segundo plano para no sobrecargar el entorno de visualización ya que el envío sí que lleva un procesamiento más complejo.

43

Page 55: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Envío de información al servidor

La clase CSASocketClient proporciona los métodos necesarios para crear una conexión asíncrona, y realizar también de forma asíncrona el envío y recepción de datos. Se crea primero el objeto correspondiente indicándole el servidor con el que crear la conexión: si se pasa un nombre en vez de una dirección IP, se hace una consulta al servidor DNS que tenga configurado el ordenador en el que se ejecuta la aplicación. Una vez conocida la dirección IP, se inicia la petición de conexión al puerto 4510 de dicha dirección IP. Se ha escogido un puerto que no está en el rango de los servicios conocidos. Si la petición de conexión temporiza o es rechazada por estar el puerto remoto cerrado, se produce una espera de 30 segundos antes de un reintento automático de conexión. Esto se realiza por si el programa servidor no está en ejecución en el momento de la petición. Si la conexión falla por cualquier otro motivo, la conexión no se vuelve a intentar. Tras esto, sería la función serverCheckTimer_Elapsed anteriormente mencionada la que se encarga de supervisar que la conexión siga establecida o de cambiar de servidor.

44

Ilustración 12. Programa cliente, conexión asíncrona

Page 56: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Una vez establecida la conexión, la función de envío Send está sobrecargada para hacer un primer envío de la identidad del usuario analizado, y después realizar el envío de toda la información. En esta segunda función se han realizado varias pruebas y combinaciones: primeramente, la codificación de las imágenes capturadas (Kinect y escritorio) de formato bmp a jpg se hacía en esta función; sin embargo, se vio que esto demoraba mucho el envío y no se conseguía el ritmo adecuado. Por esa razón se pasó esta función a la sección de recogida de datos. Enviar y almacenar los datos en el formato XML que se generaba también ocupaba demasiado espacio, por lo que se decidió comprimir esos datos en XML en formato gzip: al ser sólo texto, el proceso es muy rápido y el tamaño final muy pequeño.

Por último, se crea el paquete de información a enviar con la siguiente estructura:

cabecera identificativa de inicio de trama, basada en la cabecera única de gzip, pero con ciertas modificaciones

cabecera de datos con el tiempo en milisegundos desde el envío anterior, longitud de la información de los puntos comprimida, tamaño de la imagen de Kinect y tamaño de la imagen del escritorio

datos comprimidos de Kinect

imagen de Kinect

imagen del escritorio

Esta es la estructura que espera encontrar el servidor: primeramente, buscará el inicio de la información usando la cabecera modificada de gzip, y a continuación el resto de los datos en el orden indicado y con el tamaño correcto.

Si el envío de datos falla, por ejemplo, por caída momentánea de la red, se reintenta la conexión al servidor: se re-implementa aquí esta supervisión para no esperar al proceso periódico programado y ganar en velocidad de re-conexión y perder la menor cantidad posible de información.

Aunque no se han llegado a usar en este proyecto, se han desarrollado las funciones de recepción de datos, para una señalización básica con el servidor.

45

Page 57: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Aplicación servidor

La ventana principal MainWindow carga la información de los usuarios y reglas que se hayan dado de alta previamente y los carga en las respectivas fuentes de datos KinectUserCollection y RuleClassCollection, o las crea vacías si es la primera vez que se ejecuta. Los datos se pueden pasar fácilmente de un equipo a otro simplemente copiando los ficheros de reglas, de usuarios y de sus sesiones.

Estas colecciones se pueden modificar (altas, bajas y cambios) en sus respectivas ventanas de edición, UserEditionWindow y RulesEditionWindow. La colección de usuarios está formada por objetos KinectUser, los cuales a su vez tienen una estructura interna UserSettings. En esta segunda estructura se guardan los identificadores de reglas y si están o no activos, y la posición por defecto de los puntos del usuario, es decir, los puntos que corresponden a la posición neutra de su rostro. Está preparada para futuras ampliaciones incluyendo variables como si el usuario cuenta con una cámara de video extra o sensores físicos. La colección de reglas está formada por reglas de tipo RuleClass, y cada regla tiene a su vez una serie de Condition,

46

Ilustración 13. Programa servidor, diagrama de clases

Page 58: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

donde se guardan los dos puntos a medir, la variación de distancia, el tiempo a medir, y su descripción. Incluida en la clase RuleClass hay un valor estático, PointTypeClass, en el que se carga el listado de puntos 2D y 3D, y a que versión de Kinect pertenecen. Esta última clasificación es una preparación para futuras mejoras, evitando que el programa quede restringido al dispositivo Kinect de este proyecto.

Cuando se abre una ventana de análisis, EmotionAnalizeWindow, se le pasa sólo el usuario que se va a analizar y las reglas, de las cuales se seleccionan a posteriori las que están habilitadas para ese usuario y, por tanto, las que se deben analizar. El hecho de pasar las reglas, es dar la posibilidad de editar las reglas, y/o habilitar/deshabilitar algunas desde la ventana principal. La ventana de análisis contiene a su vez dos visualizadores: por un lado, está Player que es el encargado de leer en un proceso en segundo plano los ficheros de la sesión elegida y decodificar las imágenes de Kinect y del escritorio para mostrarlas en pantalla; tras mostrar las imágenes, envía a FaceViewer los puntos decodificados que corresponden a las imágenes actuales. En función de las opciones marcadas en la ventana, FaceViewer mostrará unas representaciones u otras.

También el código de la ventana de análisis recibirá los puntos, y deberá hacer los cálculos necesarios según las reglas que el usuario tiene activados. Este proceso se realizará en un proceso en segundo plano para que no afecte al entorno de visualización. Tras el análisis, se devuelve una tabla con las reglas analizadas y su porcentaje; esta tabla se mostrará en pantalla. Cuando una regla se cumple superando el umbral establecido (100% por defecto), se genera una marca visual en la línea de tiempo del video, y una entrada en la lista de emociones detectadas.

Otra función que hace el programa en segundo plano es recibir las conexiones de los usuarios y grabar los datos recibidos. Para esta labor se ha creado el módulo KinectServer, que en realidad es un servidor TCP asíncrono. El servidor se encarga de grabar la información en disco e informar al programa principal de cuando un usuario se conecta, para dar de alta una sesión en su base de datos y mostrar en pantalla tal situación, y también cuando el usuario se desconecta para actualizar la vista en pantalla.

47

Ilustración 14. Programa servidor, interacción Clase principal y Servidor

Page 59: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Ventana principal del servidor

La primera acción es cargar los usuarios en KinectUsers y las reglas en RulesCollection, tras lo cual se realiza un CrossCheckRulesUsers: esta función comprueba que los usuarios que tiene cada regla asignados sea correcta, y actualiza los usuarios con las reglas actuales, añadiendo, borrando y cambiando el nombre según el caso necesario. Esta función también se invoca al terminar de editar las reglas o los usuarios, de forma que las dos bases de datos estén siempre actualizadas.

48

Ilustración 15. Programa servidor, estructura ventana principal

Page 60: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

49

<DataGrid x:Name="gridKinectUsers" Margin="5" AutoGenerateColumns="False" RowHeight="50" LoadingRow="gridKinectUsers_LoadingRow" FrozenColumn-Count="1" CanUserAddRows="False" CanUserDeleteRows="False"> <DataGrid.Columns> <DataGridTextColumn Header="User ID" Width="175" Binding="{Binding UserId}" IsReadOnly="True"> <DataGridTextColumn.ElementStyle> <Style TargetType="{x:Type TextBlock}"> <Setter Property="VerticalAlignment" Value="Center"></Setter> <Setter Property="Padding" Value="2,0,0,0"/> <Style.Triggers> <DataTrigger Binding="{Binding Status, Converter={StaticResource StatusConverter}}" Value="True"> <Setter Property="Background" Value="Light-Green"/> </DataTrigger> </Style.Triggers> </Style>

Código 11. Representación de usuarios

Page 61: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Con los datos necesarios ya cargados se inicia el servidor kinectServer: al igual que en la aplicación cliente se trabaja en modo asíncrono. El servidor abre el puerto 4510 en todas las interfaces de red a la espera de peticiones

de conexión de los clientes. Este dato hay que tenerle en cuenta para abrir el puerto en el firewall. En el primer paquete de información que debe llegar del programa cliente es la identidad del usuario, si no es así, se descarta la información; en ambos casos, se reinicia la espera de conexión de otro usuario. En el caso de haber recibido correctamente una identidad de usuario, se informa al programa principal de un UserStatusChanged.

El programa principal busca el identificador entre los usuarios de la base de datos, y si lo encuentra, crea los ficheros de la sesión correspondiente y se los pasa al servidor para que empiece a recibir y grabar, BeginReceive, toda la información del usuario. En caso de no encontrar el identificador, se le pregunta al gestor del servidor si desea añadir el usuario a la base de datos: en caso de aceptar el nuevo usuario, se procede como en el caso anterior a crear los ficheros de sesión y pasarlos al servidor. Cuando el servidor detecta la desconexión del usuario, se lo vuelve a notificar al programa principal para que cierre los archivos de la sesión.

Desde la ventana principal se tiene acceso a las ventanas de edición de usuarios, reglas y análisis emocional.

50

Ilustración 16. Programa servidor, estructura interna del servidor

Page 62: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Ventana de edición de usuarios

La primera vez que se inicia el programa, sin usuarios dados de alta, se presenta una pantalla en blanco indicando que se den de alta usuarios. Una vez se crean, aparecen sus fichas donde editar sus datos. La representación se ha hecho con fichas seleccionables con pestañas, similar a los exploradores web, pero colocando dichas pestañas en vertical en vez de horizontalmente, de forma que se vean más claramente los identificadores de los usuarios.

La edición de usuarios se ha controlado de tal manera que no se permite cambiar de pestaña o cerrar la ventana en si misma si se han hecho cambios en un usuario, sin antes aplicar o rechazar los cambios: con esa finalidad se han creado los métodos y campos extra que figuran en la Ilustración 17, ya que debemos asegurarnos de que los cambios son realmente deseados.

51

Ilustración 17. Programa servidor, edición de usuarios

Page 63: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

En el fragmento presentado se aprecia que se ha modificado el control estándar “TabControl” de forma que las pestañas que contienen las identidades de usuarios se vean correctamente englobándolas en otro control “ScrollViewer”. Por su parte, la ficha del usuario también está personalizada a través del estilo contenedor TabItemStyle.

Una vez conseguida diseñar la ventana, la ficha del usuario es bastante sencilla. Consta de los siguientes elementos:

Nombre

Descripción

Foto

Tabla de las reglas creadas donde marcar las que se desean aplicar en el análisis del usuario.

Ventana de edición de reglas

52

<TabControl TabStripPlacement="Left" x:Name="userTabControl" Margin="10" Grid.Row="1" ItemContainerStyle="{StaticResource TabItemStyle}" IsSynchronizedWithCurrentItem="True" SelectionChanged="userTabControl_SelectionChanged"> <TabControl.Template> <ControlTemplate TargetType="TabControl"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled"> <TabPanel x:Name="HeaderPanel" Margin="2,2,2,0" IsItemsHost="true"/> </ScrollViewer> <ContentPresenter Grid.Column="1" x:Name="PART_SelectedCon-tentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Margin="{TemplateBinding Padding}" ContentSource="SelectedContent"/> </Grid> </ControlTemplate> </TabControl.Template></TabControl>Código 12. Programa servidor, detalle del control de usuarios

Page 64: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

La plantilla base de esta ventana es igual que la edición de usuario: inicialmente se parte de una ventana en blanco, con las indicaciones necesarias para dar de alta la primera regla. En este caso sólo se pide al usuario confirmación de los cambios al cerrar la ventana, no en cada modificación de regla.

La complejidad de esta ventana reside en la definición de las reglas: en primer lugar, hay que tener conocimientos del estándar FACS [2] [19] para decidir con qué puntos vamos a trabajar para reconocer las diferentes emociones. Hay que recordar que en el estándar se identifica el movimiento de ciertos músculos con la emoción expresada. En el programa hay cargadas dos listas de puntos: estos datos se obtienen del fichero “CSXmlSerialization.xml”, creado con la herramienta auxiliar “XMLPointGenerator”: un programa creado para este proyecto con una lista de puntos 2D y 3D que genera el fichero xml necesario para el etiquetado de los puntos. Variando este fichero, se pueden añadir, quitar o cambiar nombres de los puntos a evaluar. En el listado de puntos 3D se ha conseguido asignar nombre a todos los puntos, gracias a la colaboración de

53

Ilustración 18. Programa servidor, edición de reglas

Page 65: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

otros investigadores [20]. En cambio, a los puntos 2D no se les ha asignado nombre, ya que no tienen una correspondencia tan directa; tal como se ve en la documentación [18], en su mayoría son puntos de contorno, al contrario que los puntos 3D que se intentan ajustar más a los vértices clave de cada parte del rostro.

La selección de los puntos a medir se hace en dos ComboBox desplegables. Se parte de una lista con dos diccionarios, uno con puntos 2D y otro con puntos 3D: la lista se elige en el primer ListBox mostrado en el Código 13. Con el segundo ListBox se filtra el diccionario elegido con los puntos que cumplen la condición especificada, en este caso, si son puntos de Kinect v1 (el dispositivo utilizado en este proyecto) o v2 (el nuevo equipo lanzado por Microsoft). Con las selecciones hechas, se pueden desplegar las listas de puntos y elegir los que se quieran medir.

Cuando se da de alta una condición para una regla, esta condición permanece configurada en los elementos seleccionables, de manera que se pueda añadir a otra regla sin tener que volver a realizar el proceso completo.

Al dar de baja una condición de medida de una regla, los datos que tuviera se auto-configuran en los selectores: de esta manera se puede

54

Código 13. Programa servidor, selector de puntos

Page 66: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

cambiar el dato que sea necesario y volver a añadirla a la regla, o se podría agregar a otra regla en la que encaje mejor. Esto se verá más claramente en el manual de uso.

Ventana de análisis de usuario

En esta ventana se desarrolla la verificación de las reglas definidas anteriormente. En primer lugar, se rellena una lista de SupervisionCondition con las reglas definidas y activas del usuario: si ya existe un perfil neutro se completará con las distancias que correspondan a la posición de reposo, de manera que no haya que calcular estos valores continuamente en cada

55

Ilustración 19. Programa servidor, análisis emocional

Page 67: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

valoración de las reglas. Esta lista se actualiza si se vuelve a pulsar sobre el botón de perfil neutro, o si se detecta un cambio en las reglas: bien por modificación de los valores de una regla activa, o bien porque se ha activado/desactivado una regla desde las respectivas ventanas de edición de reglas y usuarios.

En este proyecto se realiza un proceso supervisado, no es automático, ya que no se sabe a priori la fiabilidad de los datos que volcará Kinect: ya se ha visto que sí sirve para hacer una representación gráfica del rostro bastante fiel, pero queda comprobar que pueda servir para el reconocimiento de las expresiones y emociones que se pretende conseguir en este proyecto. Por tanto, hay que seleccionar primero la sesión que se quiera analizar, y a continuación reproducir el video: si se avanza la posición del video saltando en el tiempo, ese salto de tiempo quedará sin analizar.

Con la sesión ya seleccionada, se crea el objeto miPlayer que será el encargado de leer los ficheros y reproducir las secuencias de video de Kinect y del escritorio. Como ya se explicó en la arquitectura de la aplicación, le pasa los datos de los puntos de cada instante al visualizador y también a la función FaceDataAnalisis. Desde aquí se manejan dos listas:

DetectedRules es la fuente de datos de la tabla de reglas de la ventana de análisis: en esta tabla se pueden ver las reglas analizadas y su porcentaje de cumplimiento

DetectedEmotions se compone tanto de las emociones detectadas por el propio programa en base a las reglas, como por las emocione o etiquetas que haga el usuario del programa servidor.

Las emociones detectadas se graban en disco asociadas a la sesión correspondiente en formato xml, además de dos imágenes por cada entrada en el fichero: una imagen proporcionada por Kinect y la otra imagen capturada del escritorio.

Hay que tener en cuenta que, en ausencia de cambios, dos pasadas de análisis por la misma zona de video ofrecerán los mismos resultados; pero si se ha variado algún dato como el umbral general o las condiciones de una regla, el resultado puede ser diferente. En caso de que se realicen modificaciones y el programa reconozca una emoción diferente en el mismo instante de tiempo, generará dos entradas en la lista de emociones detectadas, es decir, no se borran las entradas anteriores: será el usuario el

56

Page 68: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

que decida que emociones han sido resultado de un “falso positivo” y eliminar las entradas manualmente.

En el fragmento de código presentado se ven los tres elementos

representados: colorImage contendrá la imagen devuelta por Kinect, screenshotImage tendrá la captura de pantalla, y faceTrackingViewer dibujará los puntos que el usuario active en las casillas correspondientes.

57

Código 14. Programa servidor, visualizadores

Page 69: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Manuales de usoPrograma clienteEl programa consta de una ventana inicial en la que se muestran los

equipos Kinect conectados y su estado (inicializando, preparado, etc.).

Ilustración 20. Pantalla inicial cliente

Cuando el programa detecta una Kinect conectada y preparada, automáticamente abre la ventana principal con los controles de Kinect y aparecerá también un cuadro de diálogo como el mostrado en la imagen en el que deberá indicar la identidad de usuario que le habrán proporcionado.

58

Page 70: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Ilustración 21. Petición de identificación de usuario

A partir de ese momento puede acceder a todas las opciones de configuración de su Kinect:

Color Stream le permite seleccionar el formato y resolución de la cámara de color

Ilustración 22. Selección formato video

59

Page 71: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Exposure Settings permite ajustar la luminosidad

Ilustración 23. Ajustes de exposición

Color Settings sirve para ajustar los parámetros de color y nitidez

Ilustración 24. Ajustes de color

Depth Stream se utiliza para la cámara de profundidad

Ilustración 25. Ajustes de cámara de profundidad

60

Page 72: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Skeleton Stream habilita el seguimiento de esqueletos y facial, así como la elección de a quién seguir

Ilustración 26. Selección de modo de seguimiento

Sensor Settings le permite ajustar el ángulo de elevación de su Kinect, para adecuarlo a su posición y la de Kinect. Nunca incline el equipo manualmente, utilice esta opción de configuración

Ilustración 27. Ajuste de inclinación

Accelerometer simplemente muestra la aceleración relativa de Kinect respecto a una superficie plana

Ilustración 28. Acelerómetro

Por último, la configuración de la Conexión le permite elegir el modo Kinect para explorar las posibilidades del equipo, mientras que el modo Análisis es el indicado para realizar sus actividades: una vez seleccionado este modo, puede minimizar la ventana y continuar trabajando. En el campo “Servidor” deberá indicar los datos que le han suministrado junto a su Id de usuario

61

Page 73: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Ilustración 29. Selección de modo funciomiento

Bajo la imagen en color hay tres elementos seleccionables para ver en pantalla los puntos muestreados y la representación 3D correspondiente. El programa está optimizado para que la respuesta visual sea lo más fluida posible. Pero en los equipos con procesadores menos potentes se ha observado que, de forma esporádica, el programa deja de responder a las acciones del usuario, a pesar de seguir mostrando correctamente el video capturado y la representación facial. En estos casos, basta con bloquear momentáneamente la cámara con la mano, y desmarcar la representación facial.

Ilustración 30. Selección de puntos mostrados

62

Page 74: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Programa servidorLa primera vez que se empieza a funcionar con el programa tendremos

una ventana vacía donde habrá que añadir usuarios y reglas.

Se pueden añadir primero los usuarios o las reglas, pero no a la vez: cuando se abre una de las dos ventanas de edición, la otra queda deshabilitada debido al grado de dependencia mutua.

Empecemos creando una regla básica, pulsando en “Editar Reglas”.

Y luego en el botón [+] como se nos indica e indicamos “regla1” como identificador, y en nombre ponemos “Felicidad”. Para detectar esa emoción, según FACS [19] están implicadas las AU 6 y 12. Si analizamos en el documento de ésta clasificación [2], encontramos lo siguiente:

63

Ilustración 31. Servidor, primera ejecución

Ilustración 32. Edición de reglas inicial

Page 75: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

AU 6 consiste en elevar los pómulos, y estrechar sensiblemente los ojos

AU 12 se consigue elevando los extremos de los labios y alejándolos entre sí

Hay que tener cuidado porque, según se indica en la definición de las AU, el movimiento de otros músculos adicionales implicaría realizar otra AU diferente, o una combinación de las AU 6, 7 y 12.

Empezamos seleccionando puntos 3D (en la versión 2D no hay puntos referentes a las mejillas), y dejamos marcadas las dos versiones de Kinect. Para identificar AU 6 hay que establecer que los puntos 63 (mejilla izquierda, LeftSideOfCheek) y 57 (punto medio del párpado inferior del ojo izquierdo, UnderMidBottomLeftEyelid) se acerquen. En una medida práctica de un rostro, la distancia en reposo es de 3cm., mientras que al sonreír se acorta a 2.5cm.: esto supone una disminución de 16.67%. En la casilla de “% Variación” se pueden poner valores positivos para puntos que se separan, valores negativos para puntos que se acercan, y el valor especial 0.0 para puntos que no deben variar su distancia (de forma que se puedan seguir las indicaciones FACS y distinguir dos AU similares, aunque en el ejemplo no lo utilizaremos). Como la variación de la AU 6 supone un acercamiento, el valor a introducir será negativo, por lo que pondremos un valor de -16.67. En cuanto al tiempo, tendrá que mantenerse el acercamiento al menos 2 segundos, para distinguir la emoción de una simple mueca.

Para identificar la AU 12 usaremos dos mediciones, por un lado, el alejamiento de los extremos de los labios, y por otro, el acercamiento del extremo a la parte baja del ojo. Traducido en puntos, se trata del 31 (extremo derecho de la boca, OutsideRightCornerMouth) y del 64 (extremo izquierdo de la boca, OutsideLeftCornerMouth). Si la variación es de 6cm. a 7cm., supone un alejamiento de 16.67%. Y la otra condición se calcularía entre los puntos 31 y 57: con una variación de 6cm. a 5cm., es decir, pondremos -16.67%. Se puede poner el mismo tiempo en todas las condiciones, o ajustarlo a cada una de ellas: por ejemplo, puede permanecer la AU 12 más que la AU 6. En este caso usaremos 2s en todas las mediciones.

64

Page 76: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Si nos equivocáramos en cualquier condición, basta con pulsar el botón de su derecha [-]: en ese momento, todos los valores de dicha condición se quedarían activados en la zona de selección para poder modificarlos y volver a añadirlos corregidos.

Una vez finalizada la creación de la regla, cerramos la ventana y aceptamos los cambios.

Pulsamos en “Usuarios” para agregar a los que queremos monitorizar. De momento sólo se añadirá uno para comprobar si la evaluación de la regla creada funciona y se detecta la emoción correctamente.

65

Ilustración 33. Definición de una regla

Page 77: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Ilustración 34. Edición de usuarios inicial

Al igual que antes, partimos de una página en blanco. Hay que pulsar el botón [+] para añadir usuarios.

En este caso la ficha es muy fácil de rellenar: se necesita un identificador de usuario único, el nombre completo y opcionalmente se puede incluir una descripción. Por último, se marcarán las reglas que se quieran aplicar a dicho usuario. He aquí como quedaría con la regla que se ha creado:

66

Ilustración 35. Primer usuario de pruebas

Page 78: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Al aplicar los cambios y cerrar esta ventana, aparecerá ya su ficha en la ventana principal, como se puede ver a continuación.

Cuando este usuario se conecte, su estado pasará a ser “Connected”, y quedarán resaltados sus datos con un fondo verde: de esta manera se puede ver claramente qué usuarios están conectados. Por defecto al arrancar el programa, los usuarios están ordenados según se han dado de alta, pero pinchando en la cabecera correspondiente se puede ordenar la tabla por el identificador de usuario, por su nombre, por su estado o por su descripción.

Una vez que hay alguna sesión grabada del usuario, podemos dar al botón [Mostrar].

La primera vez que se va a analizar un usuario hay que definir su perfil neutro: para ello se puede seleccionar cualquier sesión que haya grabada y

67

Ilustración 36. Ventana principal con usuario creado

Ilustración 37. Ventana de análisis

Page 79: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

visualizarla. Cuando se aprecie que tiene la expresión serena, se pulsaría el botón [Perfil Neutro]: a partir de ese momento se empiezan a analizar las reglas, y también se habilita el botón [Etiquetar], para poder marcar momentos de tiempo en los que no se cumplan las reglas.

Volviendo al ejemplo, y ya con el perfil neutro definido, el programa no detecta en ningún momento que se cumplan las condiciones de la expresión felicidad que habíamos definido anteriormente. Fijándonos en los porcentajes que aparecen en la tabla, se baja el umbral de precisión al 95%, y se reproduce el video de nuevo. En este caso, se pausa el video y se genera una marca a los 16 segundos, con la regla cumplida al 99.9%

La división entre las pantallas de Kinect y de escritorio se puede mover a izquierda y derecha para hacer más grande una imagen o la otra.

Las etiquetas están basadas en fichero de texto fácilmente modificable para poder añadir, quitar o renombrarlas.

Si añadimos más reglas y se vuelve a visualizar el vídeo, puede que lo detectado ahora como Felicidad, sea detectado como otra emoción: en ese caso se generaría una nueva marca, pero no se perdería la anterior. Si se quiere eliminar, habría que hacerlo seleccionándola y usando el botón [Borrar marca]

68

Ilustración 38. Detección de regla y etiquetado

Page 80: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

ConclusionesEn base a la representación facial obtenida con este dispositivo Kinect,

podemos afirmar que la implementación que hace basada en CANDIDE-3 está muy lograda. Sin embargo, obtener unos datos FACS fiables es más complicado:

Partimos de la base de no tener las posiciones exactas de los puntos monitorizados, sino sus coordenadas de representación.

En segundo lugar, la resolución obtenida no es muy alta.

Y en relación a lo anterior, el entorno influye mucho en la fiabilidad de los datos obtenidos: tanto el ángulo de iluminación como la posición de Kinect respecto a usuario repercuten en los datos recibidos. Como ya se vio durante el análisis previo, a pesar de estar inmóviles frente al dispositivo, éste generaba datos muy variables: si se eliminara la imagen en color, y quedara solo la representación de los puntos generados, se podría deducir que el usuario estaba en continuo movimiento, abriendo y cerrando la boca, siendo esta situación equivocada.

Estas limitaciones nos obligarían a crear un puesto de estudio especial, que tal vez no pudiera cumplirse en todos los casos.

En cambio, sí podemos afirmar que, con las condiciones correctas, y un ajuste correcto de los umbrales de detección en las reglas, se podría llegar a convertir el servidor en un entorno autónomo. Según se podido observar, una vez estabilizada la captura, sí se pueden capturar ciertos estados. Descartando obviamente el hecho de que el sistema intenta generar una simetría del rostro, que no es siempre correcta: al levantar sólo una ceja o entornar los labios en una dirección, Kinect intenta compensarlo repartiendo el movimiento entre los dos lados de la cara y manteniendo la simetría. Por tanto, la emociones que requieran de este tipo de asimetrías no podría reconocerse (Ilustración 5)

Por tanto, estamos ante el comienzo de una nueva forma de análisis que aplicar al entorno educativo. Como se puede ver es una nueva línea de investigación, y la idea de aplicar un reconocimiento FACS bastante adecuada. Como primer acercamiento servirá para sacar unos primeros análisis que aplicar en futuros desarrollos de entornos educativos. FACS hace referencia a una gran cantidad de emociones, siendo algunas muy

69

Page 81: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

complejas de detectar por la gran cantidad de movimientos de músculos implicados, con movimientos casi imperceptibles para la tecnología actual. Otras emociones, sin embargo, requieren de menos puntos de referencia y sí pueden detectarse, como se vio en el capítulo anterior.

Empresas tecnológicas ya se han interesado en los estudios desarrollados por el grupo MAMIPEC [21]: cuanto más se investigue y mejores equipos se utilicen, más fiables serán los resultados obtenidos. El hecho de que empresas como Telefónica patrocinen un blog dedicado a las TIC, y que contengan un artículo titulado “La computación afectiva puede ayudar a una mayor involucración en el aprendizaje”, da una idea de la repercusión que este tipo de estudios tienen.

También se puede obtener más información del método FACS en los videos de las entrevistas con Paul Ekman [22] [23]. Existe un curioso vídeo que representa gestualmente lo explicado en la documentación FACS [24]: en él se aprecian las diferentes emociones según los músculos afectados por las AU.

Como idea final recalcar la limitación de Kinect que es no proporcionar las coordenadas 3D de los puntos reales muestreados: a pesar de que los puntos 2D no cubren la superficie del rostro, y son contornos lo que delimitan, la falta de una coordenada Z real supone un gran problema, porque cualquier movimiento respecto de la posición de grabación genera un cambio de distancia entre puntos (en el plano 2D), pero no se corresponde con una modificación real de la expresión facial.

70

Page 82: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Futuras líneas/trabajosEl proyecto se ha desarrollado de la forma más abierta posible para que

se puedan incluir mejoras con el menor número de modificaciones posible.

La primera mejora que se podría incluir es la adaptación al nuevo dispositivo Kinect v2: en este caso habría que modificar el programa cliente para que trabaje con el SDK y los drivers correspondientes, ya que según se mencionó anteriormente, estos son incompatibles con el Kinect que se ha utilizado en este proyecto. Inicialmente habría que revisar si ya están incluidas las funciones de obtención de puntos en lenguaje C# que hubo que implementar en este proyecto (GetShapeUnits y GetShapePoints); si no fuera así, es probable que las mismas funciones que se añadieron en este proyecto se puedan utilizar en el nuevo SDK con una mínima o incluso nula modificación. Un punto a tener en cuenta, según se ve en la documentación de este nuevo dispositivo, es que el número de puntos monitorizados que devuelve es mayor al actual debido a sus cámaras de mayor resolución, y también la calidad de la imagen capturada. Estos hechos habrá que notificarlos al servidor. Gracias a que el envío de esta información se envía codificada en formato XML es posible añadir más campos que incluyan la versión de Kinect, el formato de imagen, etc. También se puede aprovechar la mayor resolución y analizar los datos de GetShapeUnits ya que, al dar unas medidas más exactas de los rasgos faciales, se podrían quizás utilizar para la identificación automática del usuario, o la aplicación de unas reglas específicas.

Una vez mejorado el programa cliente, se puede actualizar el servidor para que reconozca los nuevos puntos. Modificando la herramienta que se creó para este proyecto, se puede generar fácilmente un nuevo archivo XML que el servidor leerá la próxima vez que arranque y dará la posibilidad de seleccionar estos nuevos puntos en la edición de reglas. En este sentido, habría que intentar que coincidieran la mayor parte de los identificadores con la versión de Kinect de este proyecto, de tal manera que se pudieran aprovechar las reglas de detección que ya estuvieran creadas.

Aunque no se utiliza en este proyecto, el módulo de conexión del cliente está preparado para recibir información del servidor: se puede aprovechar este canal para que el servidor informe de ciertas incidencias al usuario de la aplicación cliente; por ejemplo, que coloque mejor la Kinect, falta de iluminación, etc.

71

Page 83: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

En la última versión del kit de utilidades de Kinect, se muestra un ejemplo en el que se genera un servidor WEB local desde el que obtener la imagen captada por Kinect. Este caso implicaría revertir el proceso generado en este proyecto. El equipo que tiene el dispositivo Kinect sería el servidor de conexiones, y el programa de análisis iniciaría la conexión en modo cliente. Omitiendo la generación WEB e incorporando el módulo de reconocimiento facial, se podría integrar dicha solución en el propio programa educativo que vaya a emplear el alumno: una vez que éste ha iniciado sesión en el servidor de contenidos, el servidor de análisis se conectaría con el PC del alumno para recoger los datos de su Kinect.

En cuanto al programa servidor se podría cambiar de aspecto sin necesidad de retocar el código utilizando la herramienta adicional Blend para Visual Studio. Recordemos que en C# las ventanas de aplicación se componen de dos ficheros, uno con el código de lógica de control y otro con la definición y posición de los elementos gráficos en formato XAML: este segundo fichero es el que se podría modificar desde Blend, que da incluso de modificar la plantilla sobre la que está basado un elemento. Por ejemplo, un botón consta de un borde, un fondo y un texto: se puede cambiar el texto por imágenes, variar el borde para crear efectos 3D, etc.

Se podría también estudiar la posibilidad de utilizar una librería externa de codificación de video en tiempo real, por ejemplo, en C++, con un equipo servidor más potente, en vez de utilizar un PC de escritorio. Las imágenes en formato jpg recibidas del cliente se utilizarían para generar dicho fichero de vídeo que podría ser visualizado desde un reproductor estándar.

Los datos que se guardan actualmente en ficheros, podrían guardarse en una base de datos: actualmente hay diversas opciones a la hora de elegir un programa de base de datos, desde el propio SQL de Microsoft en su versión gratuita Express, o las de pago, pasando por otras como MaríaDB, MySQL, MongoDB, etc. Cada una de estas bases de datos tienen sus propias características y funcionan mejor para un cierto tipo de datos y estructuras: con ayuda de un experto en estas labores, se escogería la base de datos correspondiente y se enlazaría con el servidor.

En cualquier caso, la mejor y mayor ampliación que se puede considerar necesaria sería el adaptar los programas al nuevo dispositivo Kinect por su mayor resolución, llegando incluso a captar cuando el usuario abre o cierra un ojo, algo completamente inviable con el dispositivo utilizado en este proyecto.

72

Page 84: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

La inclusión de módulos que recojan datos fisiológicos del usuario también sería otra ampliación importante: aunque antiguamente serían necesarios costosos y engorrosos aparatajes, hoy en día existe una amplia gama de dispositivos tipo Smartwatch y similares capaces de recoger el pulso, nivel de azúcar, etc., que apenas interfieren al usuario, envían la información de forma inalámbrica y podrían ser de utilidad para el análisis final. Valiéndonos del formato XML de intercambio de información entre cliente y servidor, se puede ampliar la información enviada. En el servidor se tendrá que crear la representación correspondiente de esos datos, y su análisis si procediera.

73

Page 85: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Presupuesto de ejecución materialSe incluye en este presupuesto los gastos en herramientas empleadas,

tanto hardware como software, así como la mano de obra.

En la ejecución de este proyecto han participado las siguientes personas:

Un Ingeniero Superior de Telecomunicación, encargado del desarrollo y redacción del proyecto, así como de la obtención e interpretación de los resultados.

Un licenciado en psicología, encargado del asesoramiento del diseño y requerimientos del análisis FACS

Un mecanógrafo, encargado de la escritura del proyecto en un procesador de textos, elaboración de gráficos, etc.

Relación de salarios Se parte del sueldo base mensual de cada una de las personas que

han intervenido en el proyecto para calcular el sueldo base diario respectivo. A éste habrá que añadir las obligaciones sociales.

Sueldo base

mensual

Sueldo base diario

GratificaciónSueldo

total diario

Ingeniero Superior de Telecomunicación

1.334,59 44,49 6,07 50,56

Licenciado psicología 1.200,50 40,02 5,80 45,82

Mecanógrafo 632,49 21,08 5,67 26,76

Sueldos de las personas que han intervenido en el proyecto

74

Page 86: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Relación de obligaciones sociales

Obligaciones sociales

Relación de salarios efectivos totalesSueldo diario

Obligaciones sociales

Total/día

Ingeniero Superior de Telecomunicación

50,56 27,11 77,67

Licenciado psicología 45,82 24,57 70,39

Mecanógrafo 26,76 14,35 41,11

Salarios efectivos totales

Coste de la mano de obraPara calcular el coste de la mano de obra basta con aplicar el número

de días trabajado por cada persona por el salario respectivo.Días Salario (€) /día Total (€)

Ingeniero Superior de Telecomunicación

520 77,67 40.388,40

Licenciado en psicología 60 70,39 4.223,40Mecanógrafo 40 41,11 1.644,40

Coste Total de Mano de Obra

46.256,20

Coste de la mano de obra

Coste total de materialesPara la ejecución de este proyecto se han empleado un ordenador

personal de gama alta (PC con procesador i7 y sistema operativo Windows),

75

CONCEPTOVacaciones anuales retribuidas 8,33%

Indemnización por despido 1,60%Seguro de accidentes 7,00%

Subsidio familiar 2,90%Subsidio de vejez 1,80%

Abono días festivos 12,00%Días de enfermedad 0,75%

Plus de cargas sociales 4,25%Otros conceptos 15,00%

TOTAL 53,63%

Page 87: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

así como dos monitores, un SAMSUNG de 19’’ y un BENQ de 22’’ panorámico, y una impresora HP Deskjet F4180, para la elaboración de toda la documentación necesaria. También se incluyen los gastos de material fungible y de oficina.

Recordemos que se ha utilizado la licencia gratuita de Visual Studio, que permite generar programas para entornos educativos y de investigación.

76

Page 88: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Los costes referentes a los materiales utilizados se reflejan en la siguiente tabla:

Precio (€)Uso

(meses)Amortización

(años)Total (€)

1 ordenador personal para el desarrollo

1099,00 12 5 219,80

2 monitores 350,00 12 5 70,00Impresora HP Deskjet F4180

180,71 1 5 3,01

Kinect para Windows 150,00 12- 5 30,00Material fungible y de oficina

87,50 - - 87,50

Gasto Total de Material

410,31

Coste de materiales

Importe total del presupuesto de ejecución material

El presupuesto de ejecución material se calcula basándose en los costes de mano de obra y los costes materiales.

Concepto Importe (€)Coste Total de Materiales 410,31Coste Total de Mano de Obra 46.256,20Presupuesto Total de Ejecución Material 46.666,51

Presupuesto de ejecución material

Importe de ejecución por contrataAl importe de ejecución material hay que añadirle los siguientes

conceptos:Concepto Importe (€)

Gastos Generales y Financieros (22%) 10.266,63Beneficio Industrial (6%) 2.799,99Total G.G y B.I. 13.066,62

Relación de conceptos adicionales

77

Page 89: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Resultando:Importe de Ejecución por Contrata (€) 59.733,13

Importe de Ejecución por Contrata

Honorarios FacultativosEste proyecto se encuadra dentro del grupo XII: Aplicaciones de la

Electrónica y Aparatos de Telecomunicación. Si se aplican las tarifas correspondientes sobre el importe del presupuesto de ejecución material se tiene:Hasta 30.050,61 (Coef. 1,0 sobre 7%) 2.103,54Hasta 60.101,21 (Coef. 0,9 sobre 7%) 1.870,00Total Honorarios Facultativos (€) 3.973,54

Total Honorarios Facultativos

Los honorarios que hay que aplicar son los correspondientes tanto por redacción del proyecto como por dirección, por lo que el total de honorarios es:Honorarios de Ingeniero por redacción 3.973,54

Honorarios de Ingeniero por dirección 3.973,54Total Honorarios (€) 7.947,08

Honorarios Totales

Importe Total del ProyectoEl Importe Total del Proyecto es la suma del Importe de Ejecución por

Contrata, los Honorarios de Redacción y los Honorarios de Dirección, al cual habrá que aplicar el 21% de IVA.

EJECUCIÓN POR CONTRATA 59.733,13HONORARIOS 7.947,08IMPORTE 67.680,21IVA (21%) 14.212,84IMPORTE TOTAL 81893,05

El importe total del presente proyecto asciende a la cantidad de OCHENTA Y UN MIL OCHOCIENTOS NOVENTA Y TRES euros y CINCO céntimos.

EL INGENIERO AUTOR DEL PROYECTO

78

Page 90: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Fdo.: David Revilla Muñoz

MADRID, MARZO DE 2016.

79

Page 91: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Pliego de condicionesCondiciones generales

La obra será realizada bajo la dirección técnica de un Ingeniero de Telecomunicación y el número de programadores necesarios.

La ejecución material de la obra se llevará a cabo por el procedimiento de contratación directa. El contratista tiene derecho a obtener, a su costa, copias del pliego de condiciones y del presupuesto. El ingeniero, si el contratista lo solicita, autorizará estas copias con su firma, después de confrontarlas.

Se abonará al contratista la obra que realmente se ejecute, de acuerdo con el proyecto que sirve de base para la contrata.

Todas las modificaciones ordenadas por el ingeniero-director de las obras, con arreglo a sus facultades, o autorizadas por la superioridad, serán realizadas siempre que se ajusten a los conceptos de los pliegos de condiciones y su importe no exceda la cifra total de los presupuestos aprobados.

El contratista, o el organismo correspondiente, quedan obligados a abonar al ingeniero autor del proyecto y director de obra, así como a sus ayudantes, el importe de sus respectivos honorarios facultativos por dirección técnica y administración, con arreglo a las tarifas y honorarios vigentes.

Tanto en las certificaciones de obra como en la liquidación final, se abonarán las obras realizadas por el contratista a los precios de ejecución material que figuran en el presupuesto, por cada unidad de obra.

En el caso excepcional en el que se ejecute algún trabajo no consignado en la contrata, siendo admisible a juicio del ingeniero-director de las obras, se pondrá en conocimiento del organismo correspondiente, proponiendo a la vez la variación de precios estimada por el ingeniero. Cuando se juzgue necesario ejecutar obras que no figuren en el presupuesto de la contrata, se evaluará su importe a los precios asignados a ésta u otras obras análogas.

Si el contratista introduce en el proyecto, con autorización del ingeniero-director de la obra, alguna mejora en su elaboración, no tendrá derecho sino a lo que le correspondería si hubiese efectuado la obra estrictamente contratada.

80

Page 92: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

El ingeniero redactor del proyecto se reserva el derecho de percibir todo ingreso que en concepto de derechos de autor pudiera derivarse de una posterior comercialización, reservándose además el derecho de introducir cuantas modificaciones crea convenientes.

Condiciones generales a todos los programas Estarán realizados en lenguajes estándar.

Se entregarán tres copias de los listados para cada programa o subrutina.

Los programas y subrutinas deberán ir documentados, indicando brevemente su función, entradas y salidas, y cualquier otra información de interés.

Se entregará, junto con los programas, un manual de uso e instalación.

Condiciones generales a la pruebaLos programas y subrutinas que se entreguen deberán funcionar sobre

un ordenador PC o compatible con microprocesador i7 o superior con un puerto dedicado USB 2.0 (Kinect no funcionará con puertos USB 3) y con un dispositivo Kinect para Windows. Se ejecutarán bajo sistema operativo Windows 7 o superior en entorno local o en red.

El PC que se conecte a Kinect deberá contar con los drivers adecuados, bien con el kit de desarrollo o, más recomendable, el entorno de ejecución de Kinect v1.8 [14].

Tanto el programa cliente como el servidor necesitarán disponer del entorno de ejecución (framework) .NET 4.5, descargable de la página de Microsoft.

Solamente se aceptarán los programas si funcionan correctamente en todas sus partes, rechazándose en caso contrario. Si, por causas debidas al contratista, los programas no funcionaran bajo las condiciones expuestas anteriormente, la empresa contratante se reservará el derecho de rescindir el contrato.

81

Page 93: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Recursos materialesUn ordenador de sobremesa con procesador i7-3770 de Intel de ocho

núcleos a 3.4 GHz, disco duro de 1 TB de capacidad y 32 GB de memoria RAM. Tarjeta de sonido integrado. Dos monitores en configuración de escritorio extendido. Dispositivo Kinect para Windows.

Recursos lógicos Sistema operativo Windows 8, Windows 8.1 y Windows 10.

Entorno de desarrollo Visual Studio 2015 Community.

Software de desarrollo (SDK) de Kinect versión 1.8.

Conjunto de herramientas para el desarrollador de Kinect versión 1.8.

82

Page 94: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Anexo – Listados de códigoSe incluyen las dos funciones más importantes que hubo que añadir al

SDK de Kinect que faltaban en lenguaje C# y que hubo que incluir en FaceTrackFace.cs; también se incluirá el módulo de conexión TCP asíncrona, ya que ahí se genera el formato de los datos enviados.

Del servidor se incluye el código de la ventana principal, tanto el código visual XAML, como la lógica en C#. En ellos se muestra como crear una tabla de datos personalizada, y como cargar y grabar los datos en archivos XML.

Función GetShapePoints()/// <summary>/// Get the 2D shape points. http://kinect405.rssing.com/chan-4564226/

all_p5.html, Mysteries of Kinect for Windows Face Tracking output ex-plained

/// http://blogs.msdn.com/b/kinectforwindows/archive/2014/01/31/clear-ing-the-confusion-around-kinect-for-windows-face-tracking-output.aspx

/// </summary>/// <returns>/// The 2D shape points. populates an array for the ShapePoints/// </returns>public PointF[] GetShapePoints(){ // get the 2D tracked shapes IntPtr pointsPtr = IntPtr.Zero; uint pointCount = 0; this.faceTrackingResultPtr.Get2DShapePoints(out pointsPtr, out

pointCount); // volanie unmanaged kodu if (pointCount == 0) { return null; }

// create our array to hold the points PointF[] shapePoints = new PointF[pointCount];

int sizeInBytes = Marshal.SizeOf(typeof(PointF)); for (int i = 0; i < pointCount; i++) {

IntPtr faceShapePointsPtr;if (IntPtr.Size == 8){ // 64bit faceShapePointsPtr = new IntPtr(pointsPtr.ToInt64() + (i *

sizeInBytes));}else{ // 32bit faceShapePointsPtr = new IntPtr(pointsPtr.ToInt32() + (i *

sizeInBytes));

83

Page 95: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

}

// copy the datashapePoints[i] = (PointF)Marshal.PtrToStructure(faceShape-

PointsPtr, typeof(PointF)); } return shapePoints;}

Código 15. Obtención de puntos muestreados 2D

Función GetShapeUnits(out bool hasSuConverged)/// <summary>/// Returns the Shape Units. Created by David Revilla for Analisis Emo-

cional Project/// </summary>/// <returns>/// Returns the Shape Units/// </returns>[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design",

"CA1024:UsePropertiesWhereAppropriate", Justification = "Analysis doesn't see these as arrays. If this returned an actual array, we wouldn't see this warning.")]

public EnumIndexableCollection<ShapeUnitsEnum, float> GetShapeUnits(out bool hasSuConverged)

{ this.CheckPtrAndThrow();

IntPtr shapeUnitCoeffPtr; uint shapeUnitCount = 0; float scale;

var faceTracker = this.parentFaceTracker.Target as FaceTracker; if (faceTracker == null) { throw new ObjectDisposedException("FaceTracker", "Underlying

face object has been garbage collected. Cannot copy."); } faceTracker.FaceTrackerPtr.GetShapeUnits(out scale, out shapeUnitCo-

effPtr, ref shapeUnitCount, out hasSuConverged);

float[] shapeUnitCoeff = null; if (shapeUnitCount > 0) { shapeUnitCoeff = new float[shapeUnitCount]; Marshal.Copy(shapeUnitCoeffPtr, shapeUnitCoeff, 0, shapeUnitCo-

eff.Length); }

return new EnumIndexableCollection<ShapeUnitsEnum, float>(shapeUnit-Coeff);

}

84

Page 96: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Código 16. Obtención de rasgos faciales y estado de seguimiento

85

Page 97: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Funciones de envío asíncronas de CSASocketClient.cspublic static void Send(Socket client, SerializableFaceTrackingData

data, int mspf=40, object locker = null){

byte[] magicNoGzip = { 0, 0, 0, 0, 0, 8, 139, 31, 139, 8, 0, 0, 0, 0, 0 };

if (client != null) {

if (client.Connected){ try {

StringBuilder sb2 = new StringBuilder(); TextWriter tw = new StringWriter(sb2); serializer.Serialize(tw, data); sb2.Append(endOfData);

MemoryStream ms = new MemoryStream(); GZipStream comp = new GZipStream(ms, CompressionLevel.Fastest,

true); comp.Write(Encoding.Unicode.GetBytes(sb2.ToString()), 0, En-

coding.Unicode.GetBytes(sb2.ToString()).Length); comp.Close(); IndexSerializer lengths = new IndexSerializer(); lengths.arrayIndexes.MillisencondsPerFrame = (int)(mspf > 0 ?

mspf : 40); lengths.arrayIndexes.DataLength = ms.ToArray().Length; lengths.arrayIndexes.ColorImageLength = data.ColorImage-

bytes.Length; lengths.arrayIndexes.ScreenshotLength = data.bmpScreenshot-

bytes.Length; byte[] byteData = Combine<byte>(magicNoGzip, lengths.Serial-

ize(), ms.ToArray(), data.ColorImagebytes, data.bmpScreenshot-bytes);

// Begin sending the data to the remote device. client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);

} catch (Exception e) {

Debug.WriteLine(e.ToString());sendDone.Set();

}}else{ sendDone.Set();}

86

Page 98: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

} else {

sendDone.Set(); }

}

private static void SendCallback(IAsyncResult ar){ Socket client = null; try {

// Retrieve the socket from the state object.client = (Socket)ar.AsyncState;

// Complete sending the data to the remote device.int bytesSent = client.EndSend(ar);Debug.WriteLine("{0} Bytes sent to server.", bytesSent);

} catch (SocketException e) {

// https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx

// https://msdn.microsoft.com/en-us/library/ms740668.aspx// https://msdn.microsoft.com/en-us/library/system.net.sockets.-

socketerror.aspx

if ((((System.Net.Sockets.SocketException)(e)).SocketErrorCode == SocketError.ConnectionAborted)

|| (((System.Net.Sockets.SocketException)(e)).SocketErrorCode == SocketError.ConnectionReset))

{ Console.WriteLine(e.ToString());

TimeSpan interval = new TimeSpan(0, 0, 30); Thread.Sleep(interval);

connectionRetry = true;}else{ Console.WriteLine(e.ToString()); connectionRetry = false;}

} catch (Exception e) {

Console.WriteLine(e.ToString());connectionRetry = false;

} finally {

// Signal that all bytes have been sent.sendDone.Set();

87

Page 99: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

if (connectionRetry && (client != null)){ receiveDone.Set(); connectionRetry = false;

Debug.WriteLine("Retry connection",remoteEP.ToString()); client.Disconnect(true); client.BeginConnect(remoteEP,new AsyncCallback(ConnectCallback), client);}

}}

Código 17. Conexión cliente Asíncrona

88

Page 100: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Ventana principal del servidorEsta sería la implementación visual

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta-tion" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:AnalisisEmocional" xmlns:d=http://schemas.microsoft.com/expression/blend/2008 xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006 mc:Ignorable="d" x:Class="AnalisisEmocional.MainWindow" Title="Proyecto Análisis Emocional" Height="350" Width="525" MinHeight="200"> <Window.Resources> <DataTemplate DataType="{x:Type local:KinectUser}"> <StackPanel ToolTip="{Binding Description}" > <TextBlock Text="{Binding UserId}" /> <TextBlock Text="{Binding Name}" /> <TextBlock Text="{Binding Status}" /> <!--<TextBlock Text="" />--> <ListBox x:Name="rulesList" ItemsSource="{Binding Set-tings.ActiveRules}"> <ListBox.ItemTemplate> <HierarchicalDataTemplate> <CheckBox Content="{Binding Name}" Is-Checked="{Binding IsChecked, Mode=OneWay}"/> </HierarchicalDataTemplate> </ListBox.ItemTemplate> </ListBox> </StackPanel> </DataTemplate> <DataTemplate DataType="{x:Type local:UserSettings}"> <StackPanel> <TextBlock Text="{Binding Video}" /> <TextBlock Text="{Binding ActiveRules}" /> <TextBlock Text="{Binding PhysicalSensors}" /> <TextBlock Text="{Binding UserFacePoints}" /> </StackPanel> </DataTemplate> <local:StatusConverter x:Key="StatusConverter"/> <local:ImagePathConverter x:Key="ImagePathConverter"/> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Button Content="Editar _Reglas" HorizontalAlignment="Center" Margin="10" VerticalAlignment="Center" x:Name="rulesButton"

Padding="10,2,10,2" Click="Rules_Button_Click"> <Button.Style> <Style TargetType="{x:Type Button}"> <Style.Triggers> <DataTrigger Binding="{Binding IsEnabled, Rela-tiveSource={RelativeSource Mode=Self}}" Value="false"> <Setter Property="ToolTip" Value="Finalice la edición de usuarios, antes de editar las reglas"/> <!--http://wpftutorial.net/ToolTip.html-->

89

Page 101: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

<Setter Property="ToolTipService.ShowOnDis-abled" Value="True"/> </DataTrigger> </Style.Triggers> </Style> </Button.Style> </Button> <Button Content="_Usuarios" HorizontalAlignment="Center" Mar-gin="10" Grid.Row="1" VerticalAlignment="Center" x:Name="userButton"

Padding="10,2,10,2" Click="User_Button_Click"> <Button.Style> <Style TargetType="{x:Type Button}"> <Style.Triggers> <DataTrigger Binding="{Binding IsEnabled, Ele-mentName=userButton}" Value="false"> <Setter Property="ToolTip" Value="Finalice la edición de reglas, antes de editar los usuarios"/> <Setter Property="ToolTipService.ShowOnDis-abled" Value="True"/> </DataTrigger> </Style.Triggers> </Style> </Button.Style> </Button> <!-- From: WPF 4.5 in C# book --> <Grid Grid.Row="2">

<DataGrid x:Name="gridKinectUsers" Margin="5" AutoGenerate-Columns="False" RowHeight="50" LoadingRow="gridKinectUsers_LoadingRow"

FrozenColumnCount="1" CanUserAddRows="False" CanUserDeleteRows="False"> <!--<ToolTip="{Binding Description}"--> <DataGrid.Columns> <DataGridTextColumn Header="User ID" Width="175" Binding="{Binding UserId}" IsReadOnly="True"> <DataGridTextColumn.ElementStyle> <Style TargetType="{x:Type TextBlock}"> <Setter Property="VerticalAlignment" Value="Center"></Setter> <Setter Property="Padding" Value="2,0,0,0"/> <Style.Triggers> <DataTrigger Binding="{Binding Sta-tus, Converter={StaticResource StatusConverter}}" Value="True"> <Setter Property="Background" Value="LightGreen"/> </DataTrigger> </Style.Triggers> </Style> </DataGridTextColumn.ElementStyle> </DataGridTextColumn> <DataGridTextColumn Header="Nombre" Binding="{Bind-ing Name}" IsReadOnly="True"> <DataGridTextColumn.ElementStyle> <Style TargetType="{x:Type TextBlock}"> <Setter Property="VerticalAlignment" Value="Center"></Setter> <Setter Property="Padding" Value="2,0,2,0"/> <Style.Triggers> <DataTrigger Binding="{Binding Sta-tus, Converter={StaticResource StatusConverter}}" Value="True">

90

Page 102: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

<Setter Property="Background" Value="LightGreen"/> </DataTrigger> </Style.Triggers> </Style> </DataGridTextColumn.ElementStyle> </DataGridTextColumn> <DataGridTextColumn Header="Estado" Binding="{Bind-ing Status}" IsReadOnly="True"> <DataGridTextColumn.ElementStyle> <Style TargetType="{x:Type TextBlock}"> <Setter Property="VerticalAlignment" Value="Center"></Setter> <Setter Property="Padding" Value="2,0,2,0"/> <Style.Triggers> <DataTrigger Binding="{Binding Sta-tus, Converter={StaticResource StatusConverter}}" Value="True"> <Setter Property="Background" Value="LightGreen"/> </DataTrigger> </Style.Triggers> </Style> </DataGridTextColumn.ElementStyle> </DataGridTextColumn>

<DataGridTextColumn Width="400" Binding="{Binding Description}" Header="Descripción" IsReadOnly="True" > <DataGridTextColumn.ElementStyle> <Style TargetType="{x:Type TextBlock}"> <Setter Property="TextWrapping" Value="Wrap"/> <Setter Property="ScrollViewer.CanCon-tentScroll" Value="True" /> <Setter Property="ScrollViewer.Verti-calScrollBarVisibility" Value="Auto"/> <!-- Si ponemos este Setter en vez del Trigger, se pierde el color del fondo al seleccionar la fila --> <!--<Setter Property="Background" Value="{Binding Status, Converter={StaticResource BackgroundStatusCon-verter}}"></Setter>--> <Style.Triggers> <DataTrigger Binding="{Binding Sta-tus, Converter={StaticResource StatusConverter}}" Value="True"> <Setter Property="Background" Value="LightGreen"/> </DataTrigger> </Style.Triggers> </Style> </DataGridTextColumn.ElementStyle> <DataGridTextColumn.CellStyle> <Style TargetType="{x:Type DataGridCell}"> <Setter Property="ScrollViewer.CanCon-tentScroll" Value="True" /> <Setter Property="ScrollViewer.Verti-calScrollBarVisibility" Value="Auto"/> <Setter Property="ToolTip" Value="{Bind-ing Description}" /> </Style> </DataGridTextColumn.CellStyle> </DataGridTextColumn>

<DataGridTemplateColumn>

91

Page 103: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

<DataGridTemplateColumn.CellTemplate> <DataTemplate> <Image Stretch="Uniform"

Source="{Binding UserImagePath, Converter={StaticResource ImagePathConverter}}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn>

<DataGridTemplateColumn> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button Margin="10" Padding="10,2,10,2" Click="Show_EmotionAnalizeWindow" Content="Mostrar"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn>

<DataGridTemplateColumn Header="Reglas" Width="100*"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ListBox x:Name="rulesList" ItemsSource="{Binding Settings.ActiveRules}"> <ListBox.ItemTemplate> <HierarchicalDataTemplate> <CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked, Mode=OneWay}" IsEnabled="False"/> </HierarchicalDataTemplate> </ListBox.ItemTemplate> </ListBox> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid>

</Grid></Window>

Código 18. XAML de la ventana principal del servidor

Y a continuación la implementación del código asociado// Thanks to this blog, it clarifies some doubts from http://msdn.micro-soft.com/en-us/library/jj130970.aspx// http://blogs.msdn.com/b/kinectforwindows/archive/2014/01/31/clearing-the-confusion-around-kinect-for-windows-face-tracking-output.aspx

using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Diagnostics;using System.IO;using System.Linq;using System.Net.Sockets;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;

92

Page 104: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;using System.Xml.Serialization;

namespace AnalisisEmocional{ /// <summary> /// Lógica de interacción para MainWindow.xaml /// </summary> public partial class MainWindow : Window { private RulesEditionWindow rulesEditionWindow; private UserEditionWindow userEditionWindow; private bool cerrando; private KinectUserCollection KinectUsers; private RuleClassCollection RulesCollection; private ObservableCollection<ActiveRules> commonRules; //private ObservableCollection<PointTypeClass> PointTypeList; private readonly Dictionary<string, UserAnalizeSession> User-AnalizeSessions = new Dictionary<string, UserAnalizeSession>();

private const string userSettingsFile = @"userSettings"; private const string rulesSettingsFile = @"rulesSettings";

private KinectServer kinectServer;

//private static int contador = 0; //private static int repeticion = 0;

public MainWindow() { InitializeComponent(); this.Closing += MainWindow_Closing; this.cerrando = false;

/****************************** Module Header ******************************\ * Module Name: Program.cs * Project: CSXmlSerialization * Copyright (c) Microsoft Corporation. * * This sample shows how to serialize an in-memory object to a local xml file * and how to deserialize the xml file back to an in-memory object using * C#. The designed MySerializableType includes int, string, generic, as well * as customized type field and property. * * This source is subject to the Microsoft Public License. * See http://www.microsoft.com/en-us/openness/resources/li-censes.aspx#MPL. * All other rights reserved. * * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WAR-RANTY OF ANY KIND, * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTIC-ULAR PURPOSE.

93

Page 105: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

\***************************************************************************/ ///////////////////////////////////////////////////////////////// // Deserialize from a XML file to an object instance. //

// Create the serializer XmlSerializer serializer = XmlSerializer.FromTypes(new[] { typeof(ObservableCollection<PointTypeClass>) })[0]; // Deserialize the object ObservableCollection<PointTypeClass> PointTypeList; using (StreamReader streamReader = File.OpenText( "CSXmlSerialization.xml")) { PointTypeList = serializer.Deserialize(streamReader) as ObservableCollection<PointTypeClass>; } foreach (PointTypeClass pointTypeClassItem in PointTypeList) { pointTypeClassItem.PointDict = new Dictionary<int, KinectPoint>(); foreach (KinectPoint pointItem in pointTypeClassItem.-PointList) { if (!pointTypeClassItem.PointDict.ContainsKey(pointItem.PointId)) { pointTypeClassItem.PointDict.Add(pointItem.-PointId, pointItem); } } } RuleClass.PointTypeList = PointTypeList;

// Restore Windows Size & Position // try { Rect bounds = Properties.Settings.Default.WindowPosi-tion; this.Top = bounds.Top; this.Left = bounds.Left; // Restore the size only for a manually sized // window. if (this.SizeToContent == SizeToContent.Manual) { this.Width = bounds.Width; this.Height = bounds.Height; } } catch { MessageBox.Show("No settings stored."); }

LoadUsersData();

LoadRulesData();

CrossCheckRulesUsers(false, false);

94

Page 106: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

kinectServer = new KinectServer(); KinectServer.UserStatusChanged += KinectServer_UserSta-tusChanged;

}

private void LoadRulesData() { // Get the current directory. string path = Directory.GetCurrentDirectory(); string rulesFile = path + @"\" + rulesSettingsFile; Debug.WriteLine("Rules settings file is {0}", rulesFile); if (File.Exists(rulesFile)) { try { using (Stream rulesFileStream = File.OpenRead(rules-File)) { XmlSerializer deserializer = XmlSerializer.From-Types(new[] { typeof(RuleClassCollection) })[0]; this.RulesCollection = (RuleClassCollection)de-serializer.Deserialize(rulesFileStream); if (this.commonRules == null) { this.commonRules = new ObservableCollec-tion<ActiveRules>(); } foreach (var rule in RulesCollection) { ActiveRules ar = new Ac-tiveRules(rule.RuleId, rule.RuleName, false); this.commonRules.Add(ar); } } } catch (Exception e) { Debug.WriteLine("Error cargando reglas: {0}", e.ToS-tring()); } finally { if (this.RulesCollection == null) { this.RulesCollection = new RuleClassCollec-tion(); this.commonRules = new ObservableCollection<Ac-tiveRules>(); } } } else { this.RulesCollection = new RuleClassCollection(); this.commonRules = new ObservableCollection<Ac-tiveRules>(); } }

95

Page 107: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

private void LoadUsersData() { // Get the current directory. string path = Directory.GetCurrentDirectory(); string userFile = path + @"\" + userSettingsFile; Debug.WriteLine("Users settings file is {0}", userFile); if (File.Exists(userFile)) { try { using (Stream userFileStream = File.OpenRead(user-File)) { XmlSerializer deserializer = XmlSerializer.From-Types(new[] { typeof(KinectUserCollection) })[0]; this.KinectUsers = (KinectUserCollection)deseri-alizer.Deserialize(userFileStream); } } catch (Exception e) { Debug.WriteLine("Error cargando usuarios: {0}", e.-ToString()); } finally { if (this.KinectUsers == null) { this.KinectUsers = new KinectUserCollection(); } } } else { this.KinectUsers = new KinectUserCollection(); } this.gridKinectUsers.ItemsSource = this.KinectUsers; }

private async void KinectServer_UserStatusChanged(object sender, ResultDataEventArgs e) { Socket handler = sender as Socket; KinectUser user; try { this.KinectUsers.UserLookup.TryGetValue(e.UserId, out user); if ((user == null) && (e.UserConnected == true)) {

bool? dialogResult = false; // Open the dialog box modally // http://stackoverflow.com/questions/4274553/in-validoperationexception-thrown-while-trying-to-open-new-window Action action = () => { AddDialog dlg = new AddDialog("Alta Usuario", "Id usuario", "Identificador de usuario");

// Configure the dialog box dlg.Owner = this; dlg.forceId(e.UserId);

96

Page 108: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

dlg.ShowDialog(); dialogResult = dlg.DialogResult; }; await Dispatcher.BeginInvoke(action); //dlg.ShowDialog();

if (dialogResult == true) { user = new KinectUser(e.UserId); if (user != null) { if (this.KinectUsers.UserLookup.ContainsKey(user.UserId)) { MessageBox.Show(String.Concat("No se puede añadir ", user.UserId, ", ese usuario ya existe"), "Usuario dupli-cado", MessageBoxButton.OK, MessageBoxIm-age.Exclamation); } else { Action action2 = () => { this.KinectUsers.Add(user); }; await Dispatcher.BeginInvoke(action2); } } } }

if (user != null) { user.Status = e.UserConnected ? KinectUser.UserSta-tus.Connected : KinectUser.UserStatus.Disconnected; if (e.UserConnected == true) { // Get the current directory. string path = Directory.GetCurrentDirectory(); //string target = @"c:\temp"; string sesionName = user.UserId + @"_" + Date-Time.Now.ToString("yyyyMMddHmmss"); user.SessionsId.Add(sesionName); string target = path + @"\" + user.UserId; Debug.WriteLine("User directory is {0}", tar-get); if (!Directory.Exists(target)) { Directory.CreateDirectory(target); } DumpStreams ds = new DumpStreams(); ds.imageStream = new FileStream(target + @"\" + sesionName + @".img", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, true); ds.imageIndexStream = new FileStream(target + @"\" + sesionName + @".idx", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, true); ds.dataStream = new FileStream(target + @"\" + sesionName + @".dat", FileMode.OpenOrCreate,

97

Page 109: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

FileAccess.ReadWrite, FileShare.ReadWrite, 4096, true);

Dispatcher.Invoke(() => SaveUpdatedUsers()); user.CurrentFiles = ds; Debug.WriteLine("Ficheros abiertos"); KinectServer.BeginReceive(handler, user.UserId, ds); } else { Debug.WriteLine("Ficheros cerrados"); user.CurrentFiles.imageStream.Flush(); user.CurrentFiles.imageStream.Close(); user.CurrentFiles.imageIndexStream.Flush(); user.CurrentFiles.imageIndexStream.Close(); user.CurrentFiles.dataStream.Flush(); user.CurrentFiles.dataStream.Close(); } } else { handler.Shutdown(SocketShutdown.Receive); handler.Close(); } } catch (Exception ex) { Console.WriteLine("Error al recibir conexión de usuario {0}", ex.ToString()); } }

// Reuse brush objects for efficiency in large data displays. private SolidColorBrush highlightBrush = new SolidColor-Brush(Colors.LightGreen); private SolidColorBrush normalBrush = new SolidColorBrush(Col-ors.White);

private void gridKinectUsers_LoadingRow(object sender, Data-GridRowEventArgs e) { KinectUser user = e.Row.DataContext as KinectUser; if (null != user) { if (user.Status == KinectUser.UserStatus.Connected) e.Row.Background = highlightBrush; else e.Row.Background = normalBrush; } }

private void FormatRow(DataGridRow row) { KinectUser user = (KinectUser)row.DataContext; if (user.Status == KinectUser.UserStatus.Connected) row.Background = highlightBrush; else row.Background = normalBrush; }

void MainWindow_Closing(object sender, System.ComponentModel.-CancelEventArgs e)

98

Page 110: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

{ this.cerrando = true;

if (this.rulesEditionWindow != null) this.rulesEditionWindow.Close();

if ((this.cerrando == true) && (this.userEditionWindow != null)) this.userEditionWindow.Close();

if (this.cerrando == false) e.Cancel = true; else { foreach (UserAnalizeSession session in UserAnalizeSes-sions.Values) session.EndSession(); Properties.Settings.Default.WindowPosition = this.Re-storeBounds; Properties.Settings.Default.Save(); } }

private void Rules_Button_Click(object sender, RoutedEventArgs e) { if (this.rulesEditionWindow == null) { this.rulesEditionWindow = new RulesEditionWin-dow(this.RulesCollection); this.rulesEditionWindow.Show(); this.rulesEditionWindow.Owner = this; this.rulesEditionWindow.Closed += rulesEditionWindow_Closed; this.rulesEditionWindow.Closing += rulesEditionWindow_Closing; this.userButton.IsEnabled = false; } else { if (this.rulesEditionWindow.WindowState == Window-State.Minimized) this.rulesEditionWindow.WindowState = Window-State.Normal; this.rulesEditionWindow.Activate(); this.rulesEditionWindow.Show(); this.userButton.IsEnabled = false; } }

/// <summary> /// Future improvements /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void rulesEditionWindow_Closing(object sender, System.Component-Model.CancelEventArgs e) {

//If rules are changed, but not saved, ask to cancel

99

Page 111: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

if (this.rulesEditionWindow.AreRulesChanged) { string msg = "Se ha cambiado la configuración de las re-glas. ¿Desea confirmar los cambios?"; MessageBoxResult result = MessageBox.Show( msg, "Reglas modificadas", MessageBoxButton.YesNo, MessageBoxImage.Warning); if (result == MessageBoxResult.No) { this.commonRules = new ObservableCollection<Ac-tiveRules>(); LoadRulesData(); }

} }

void rulesEditionWindow_Closed(object sender, EventArgs e) { CrossCheckRulesUsers(this.rulesEditionWindow.Are-RulesChanged, false); this.rulesEditionWindow = null;

if (cerrando == false) { this.Activate(); this.Show(); this.userButton.IsEnabled = true; } }

private void User_Button_Click(object sender, RoutedEventArgs e) { if (this.userEditionWindow == null) { this.userEditionWindow = new UserEditionWindow(Kinec-tUsers, commonRules); this.userEditionWindow.Show(); this.userEditionWindow.Owner = this; this.userEditionWindow.Closed += userEditionWindow_Closed; this.userEditionWindow.Closing += userEditionWindow_Closing; this.rulesButton.IsEnabled = false; } else { if (this.userEditionWindow.WindowState == Window-State.Minimized) this.userEditionWindow.WindowState = Window-State.Normal;

this.userEditionWindow.Activate(); this.userEditionWindow.Show(); this.rulesButton.IsEnabled = false; } }

void userEditionWindow_Closing(object sender, System.Component-Model.CancelEventArgs e)

100

Page 112: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

{ // If user data has changed, but not saved, ask to cancel if (this.userEditionWindow.AreUsersChanged) { string msg = "Se ha cambiado la configuración. ¿Cerrar sin grabar?"; MessageBoxResult result = MessageBox.Show( msg, "Usuario modificado", MessageBoxButton.YesNo, MessageBoxImage.Warning); if (result == MessageBoxResult.No) { // If user doesn't want to close, cancel closure e.Cancel = true; this.cerrando = false; }

} }

void userEditionWindow_Closed(object sender, EventArgs e) { CrossCheckRulesUsers(false, this.userEditionWin-dow.SaveUsers); this.userEditionWindow = null;

if (cerrando == false) { this.Activate(); this.Show(); this.rulesButton.IsEnabled = true; }

}

private void CrossCheckRulesUsers(bool _saveRules = false, bool _saveUsers = false) { bool saveRules = _saveRules; bool saveUsers = _saveUsers; commonRules.Clear();

if (RulesCollection.Count > 0) { foreach (RuleClass rc in RulesCollection) { ActiveRules arFalse = new ActiveRules(rc.RuleId, rc.RuleName, false); commonRules.Add(arFalse); // tempAssignedUsersId will have at the end, as-signed UsersId that do no exist anymore (maybe due to data corruption) List<string> tempAssignedUsersId = new List<string>(rc.AssignedUsersId); // Another way to clone the list //List<string> tempAssignedUsersId = rc.Assigne-dUsersId.ToList(); foreach (KinectUser ku in KinectUsers) { bool found = false;

101

Page 113: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

// deleteRules will have at the end, assigned Rules to the user that do no exist anymore (maybe due to data corrup-tion) List<ActiveRules> deleteRules = new List<Ac-tiveRules>(); foreach (ActiveRules ar in ku.Settings.Ac-tiveRules) { if (ar.Id == rc.RuleId) { found = true; // Update RuleName if necessary if (ar.Name != rc.RuleName) { ar.Name = rc.RuleName; saveUsers = true; } // Update also asigned user if (ar.IsChecked == true) { if (!(rc.AssignedUsersId.Contains(ku.UserId))) { rc.AssignedUsersId.Add(ku.UserId); saveRules = true; } else { tempAssignedUsersId.Remove(ku.UserId); } } else { if (rc.AssignedUsersId.Contains(ku.UserId)) { rc.AssignedUsersId.Remove(ku.UserId); tempAssignedUsersId.Remove(ku.UserId); saveRules = true; } } } else { if (!(RulesCollection.RuleLookup.Con-tainsKey(ar.Id))) { deleteRules.Add(ar); } } } if (found == false) { ActiveRules arTemp = new Ac-tiveRules(rc.RuleId, rc.RuleName, false); ku.Settings.ActiveRules.Add(arTemp); saveUsers = true; }

102

Page 114: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

foreach (ActiveRules arDelete in deleteRules) { ku.Settings.ActiveRules.Remove(arDelete); } } foreach (string deletedUserId in tempAssignedUser-sId) { rc.AssignedUsersId.Remove(deletedUserId); saveRules = true; } } } else { foreach (KinectUser ku in KinectUsers) { if (ku.Settings.ActiveRules.Count > 0) { saveUsers = true; ku.Settings.ActiveRules.Clear(); } } }

if (saveRules == true) { SaveUpdatedRules(); }

if (saveUsers == true) { SaveUpdatedUsers(); } }

private void SaveUpdatedUsers() { // Get the current directory. string path = Directory.GetCurrentDirectory(); string userFile = path + @"\" + userSettingsFile; string userFileTemp = path + @"\" + userSettingsFile + @".temp"; string userFileBackup = path + @"\" + userSettingsFile + @".backup"; bool rename = true; try { using (Stream userFileStream = File.Create(user-FileTemp)) { XmlSerializer serializer = XmlSerializer.From-Types(new[] { typeof(KinectUserCollection) })[0]; serializer.Serialize(userFileStream, KinectUsers); } } catch (Exception ex) { Debug.WriteLine("Error grabando usuarios: {0}", ex.ToS-tring()); rename = false; } finally

103

Page 115: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

{ if (rename) { if (File.Exists(userFile)) { File.Replace(userFileTemp, userFile, userFile-Backup, true); } else { File.Move(userFileTemp, userFile); } } else { File.Delete(userFileTemp); } } }

private void SaveUpdatedRules() { // Get the current directory. string path = Directory.GetCurrentDirectory(); string rulesFile = path + @"\" + rulesSettingsFile; string rulesFileTemp = path + @"\" + rulesSettingsFile + @".temp"; string rulesFileBackup = path + @"\" + rulesSettingsFile + @".backup"; bool rename = true; try { using (Stream rulesFileStream = File.Create(rules-FileTemp)) { XmlSerializer serializer = XmlSerializer.From-Types(new[] { typeof(RuleClassCollection) })[0]; serializer.Serialize(rulesFileStream, RulesCollec-tion); } } catch (Exception ex) { Debug.WriteLine("Error grabando reglas: {0}", ex.ToS-tring()); rename = false; } finally { if (rename) { if (File.Exists(rulesFile)) { File.Replace(rulesFileTemp, rulesFile, rules-FileBackup, true); } else { File.Move(rulesFileTemp, rulesFile); } } else {

104

Page 116: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

File.Delete(rulesFileTemp); } } }

private void Show_EmotionAnalizeWindow(object sender, RoutedE-ventArgs e) { KinectUser user = (KinectUser)this.gridKinectUsers.Selecte-dItem; UserAnalizeSession session; UserAnalizeSessions.TryGetValue(user.UserId, out session); if (session == null) { session = new UserAnalizeSession(user, RulesCollection); UserAnalizeSessions.Add(user.UserId, session); }

session.ShowAnalizingWindow();

}

}}

Código 19. Código C# de la ventana principal del servidor

105

Page 117: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

Bibliografía

[1] O. C. Santos, J. G. Boticario, M. Arevalillo-Herráez, M. Saneiro, R. Cabestrero, E. del Campo, Á. Majarrés, P. Moreno-Clari, P. Quirós y S. Salmerón-Majadas, «MAMIPEC - Affective Modeling in Inclusive Personalized Educational Scenarios,» [En línea]. Available: https://adenu.ia.uned.es/web/es/Proyectos/mamipec.

[2] P. P. Ekman, P. W. V. Friesen y P. J. C. Hager, «Facial Action Coding System Manual (FACS)».

[3] J. Ahlberg, «CANDIDE-3 – AN UPDATED PARAMETERISED FACE,» 2001. [En línea]. Available: http://www.bk.isy.liu.se/publications/LiTH-ISY-R-2326.pdf.

[4] Microsoft MSDN, «Face Tracking,» [En línea]. Available: http://msdn.microsoft.com/en-us/library/jj130970.

[5] Microsoft MDSN, «Learn to Program for Windows in C++,» [En línea]. Available: http://msdn.microsoft.com/en-us/library/windows/desktop/ff381399(v=vs.85).aspx.

[6] net-tutorials.com, «The complete WPF tutorial,» [En línea]. Available: http://www.wpf-tutorial.com/.

[7] Open Kinect, «Revision history of "Roadmap",» [En línea]. Available: http://openkinect.org/w/index.php?title=Roadmap&action=history.

[8] Eclipse Labs, «jnect,» [En línea]. Available: https://code.google.com/a/eclipselabs.org/p/jnect/downloads/list.

[9] Microsoft, «Visual Studio,» [En línea]. Available: https://www.visualstudio.com/products/visual-studio-community-vs.

[10] Microsoft, «DreamSpark,» [En línea]. Available: https://www.dreamspark.com/.

[11] Microsoft MSDN, «HelloWorldTutorial,» [En línea]. Available: https://msdn.microsoft.com/en-us/library/aa288463(v=vs.71).aspx.

[12] net-tutorials, «The complete C# Tutorial,» [En línea]. Available: http://csharp.net-tutorials.com/.

[13] Microsoft, «Kinect for Windows SDK 1.8,» [En línea]. Available: https://msdn.microsoft.com/en-us/library/hh855347.aspx.

[14] Microsoft, «Kinect for Windows Developer Toolkit v1.8.0,» [En línea]. Available: https://www.microsoft.com/en-us/download/details.aspx?id=40276.

[15] Microsoft, «Kinect for Windows Runtime v1.8,» [En línea]. Available: https://www.microsoft.com/en-us/download/details.aspx?id=40277.

106

Page 118: lorien.die.upm.eslorien.die.upm.es/~juancho/pfcs/DR/Libro Proyecto David... · Web viewFamiliarización con el entorno Microsoft Visual Studio. [5] [6] Familiarización con el kit

[16] Microsoft MSDN, «Skeletal Tracking,» [En línea]. Available: https://msdn.microsoft.com/en-us/library/hh973074.aspx.

[17] Microsoft Xbox, «Avatar Kinect,» [En línea]. Available: http://www.xbox.com/en-HK/Kinect/KinectAvatars.

[18] Microsoft MSDN, «Kinect for Windows SDK Reference,» [En línea]. Available: https://msdn.microsoft.com/en-us/library/jj572480.aspx.

[19] Microsoft MSDN, «IFTFaceTracker::GetShapeUnits Method,» [En línea]. Available: https://msdn.microsoft.com/en-us/library/microsoft.kinect.facetracking.iftfacetracker.getshapeunits.aspx.

[20] «Mysteries of Kinect for Windows Face Tracking output explained,» [En línea]. Available: http://blogs.msdn.com/b/kinectforwindows/archive/2014/01/31/clearing-the-confusion-around-kinect-for-windows-face-tracking-output.aspx.

[21] Wikipedia, «Facial Action Coding System,» [En línea]. Available: https://en.wikipedia.org/wiki/Facial_Action_Coding_System.

[22] «FaceModelDiagramPointsNames,» [En línea]. Available: http://www.nuicapture.com/img/face_model_diagram.pdf.

[23] C. D. Méndez, «A un clic de las TIC,» Telefónica Educación Digital, [En línea]. Available: http://aunclicdelastic.blogthinkbig.com/la-computacion-afectiva-puede-ayudar-a-una-mayor-involucracion-en-el-aprendizaje/.

[24] Paul Ekman Group, «Dr. Paul Ekman on Expression and Gesture and Their Role in Emotion and Deception - Part 1,» [En línea]. Available: https://www.youtube.com/watch?v=J9i-9_QuetA.

[25] Paul Ekman Group, «Dr. Paul Ekman on Expression and Gesture and Their Role in Emotion and Deception - Part 2,» [En línea]. Available: https://www.youtube.com/watch?v=b_tlSAccoWU.

[26] G. dominguez, «FACS en Youtube,» [En línea]. Available: https://www.youtube.com/watch?v=-G7IRRydpVA.

107