Detección de emociones de varias personas simultáneamente. FIN…

Posted in Avances en la práctica on mayo 27, 2009 by emotionalbot

El programa ahora mismo es capaz de diferenciarnos, gracias al clasificador de enfado de Dani. Por tanto para integrar las emociones de los dos, lo primero es realizar los clasificadores de Jorge; de estos, sólo ha dado tiempo a hacer el de sonrisa y sorpresa, dado que los demás generalmente no tuvieron un resultado satisfactorio los intentados (¿quizás por la barba?). A continuación, debemos añadirlas al programa, pero esto es relativamente sencillo, vamos a pensar en el proceso que debe seguir el programa:

  1. El programa lanza todos los clasificadores y detecta todas las emociones, tanto las de Dani como las de Jorge.
  2. Cuando llega a 20 capturas, comprueba con el número de Jorges,( hallados básicamente con el número de enfados que haya sin ninguna otra emoción) si quien está es Jorge o Dani.
  3. Una vez diferenciados, si es Jorge, se fija en las variables de los clasificadores de Jorge (JnumSonrisa, JnumSorpresa…), y si no, (si es Dani), en la de los clasificadores de Dani(numSonrisa, numSorpresa…), que se aumentarán al entrar en cada clasificador, como ya explicamos previamente.
  4. En cuanto a la variable emoción que se le pasa al robot, si es Jorge, se editará según la emoción de Jorge, y si es Dani, según la emoción de Dani, por lo tanto el funcionamiento sigue siendo el mismo, pero con la funcionalidad añadida de poder detectar emociones en los dos, ya que nos diferencia y sabe qué emociones tiene que elegir.

Con esto, nos damos cuenta también, de que la algunas de las emociones que se detectan en uno, también son detectadas en el otro, sobre todo las más uniformes como son sonrisa grande (con dientes) y sorpresa. Esto podría permitir quizás hacer un clasificador de emociones universal, introduciendo en las muestras fotos de distintos tipos de persona. Esto está limitado porque las emociones deben de tener mucho en común (como una sonrisa enseñando dientes o una boca abierta de sorpresa), pero quizás sería más difícil detectar un enfado, ya que como vemos, es el clasificador de enfado de Dani en que permite diferenciarnos.

De hecho, actualmente, gente que no fuera ninguno de nosotros, podría jugar, y probablemente habría emociones que serían detectadas. Lo primero le detectaría como Jorge o Dani con el “detector de cejas grandes” (cuidado que nunca se sabe lo que va a triunfar y se lo vendemos a L’Oreal) , y en caso de ser Jorge, podría decir si sonríe o está sorprendido; en caso de ser Dani, probablemente detectaría esas dos emociones  también y a lo mejor, enfado o sonrisa floja. Lo bueno, es que si no detecta, interpreta que estás neutral, y tiene una restricción bastante elevada, de forma que sea mejor el que no detecte que el que detecte.

De todas maneras, es sencillo con el modo HaarTraining en el programa, generar las muestras necesarias para crear vuestros propios clasificadores o clasificadores universales. Ahora bien, se necesita probar bastante, para saber cuál es la mejor opción.

Y poco más tenemos que decir de esta práctica, aunque posiblemente la continuación podría tener los siguientes objetivos:

  • Integración total con el juego del tres en raya con Trivial FTP. Si se modificara el fichero a enviar, las modificaciones en nuestra práctica serían sencillas: cambio del formato del fichero e interpretación de los mismos.
  • Integración de más emociones, como podría ser triste ( que es bastante difícil).
  • Utilización de clasificadores de cara y ojos para una misma emoción para que sea más robusto, ahora mismo el único que utiliza los ojos es el de enfado, que con la boca cometía muchos errores.
  • Posible detección universal de emociones integrando grandes bases de datos de emociones, ahora bien, el problema es encontrar a gente que ponga su cara.
  • Posible distinción de personas, aunque nuestra experiencia es que esto es bastante complicado con Haartraining, como hemos explicado en entradas anteriores.
  • Mayor interacción con el robot, agregando aleatoriedad al comportamiento (por ejemplo que cada cierto tiempo deba estar una proporción de tiempo mostrando cada emoción) , o teniendo en cuenta más cantidad de entradas, que podrían ser:
    • Confort del robot, con la  información de la temperatura.
    • Grado de amistad, teniendo memoria de las distintas personas (para esto sería necesario la distinción de personas).
    • Grado de cansancio, quizás el robot deba estar un porcentaje de horas en un día dormido.
    • Grado de ganas de jugar/aburrimiento, según la gente que haya jugado con él.

También animamos a la gente a que explore en el campo de open CV y sobre todo Haartraining para la detección de patrones que se repiten, en nuestro caso emociones, pero también podría ampliarse al tratamiento de cualquier tipo de imagen en la que haya cosas que se repitan.

Muchas gracias a los que nos hayan seguido, y esperamos sorprenderos con los vídeos que colgaremos en poco tiempo, que representarán los resultados conseguidos.

Limpieza de código y modos de funcionamiento

Posted in Avances en la práctica on mayo 24, 2009 by emotionalbot

Nuestro programa tiene mucho código. Por una parte hay código procedente del propio programa base sobre el que empezamos a desarrollar, facedetect. En el que se cargan las librerías adecuadas, se inicializa el sistema, se establece la comunicación con la cámara…

Por otra parte tenemos código debido a la función de entrenamiento de haartraining, es decir, código para obtener muestras, con las cuales elaboramos modelos con haartraining que posteriormente utilizamos para detectarnos.

Ese es el tercer tipo de código, el de detección, el de cargar todos los clasificadores y aplicarlos en batería para posteriormente tomar decisiones sobre nuestras salidas por la pantalla y a través de Groucho.

Y finalmente está el código con el que controlamos a Groucho, que tampoco es nuestro, pero también está mezclado con el resto.

Para hacer el programa más comprensible, procedimos a una limpieza del programa. En primer lugar eliminamos las partes de código que usamos en algún momento de nuestro desarrollo pero que ya no usamos. Posteriormente procedimos a comentar las partes de código que a veces usábamos y a veces no, por ejemplo las que nos sacan imágenes de parte de la cara, que pueden resultar útiles para definir rectángulos a partir de los cuales obtener muestras para haartraining.

A continuación ordenamos el código, ordenamos la definición de las variables por su funcionalidad, renombramos algunas de ellas para que su función fuese más comprensible, etc… Todo esto pone de manifiesto las ventajas de tener un código ordenado desde el principio.

Finalmente decidimos separar la parte de haartraining de la de detección. Para ello, simplemente hicimos uso de ‘define’, ‘ifdef’ y ‘endif’, que son una serie de sentencias de C en las que lo que esté entre ‘ifdef’ y ‘endif’ se ejecutará solo en caso de que esté definido lo que ponemos después de ‘ifdef’ mediante la sentencida ‘define’. Así fuimos tomando las partes de código de haartraining y metiéndolas dentro de este tipo de estructuras. Este sistema nos permite ejecutar el código en modo detección o en modo generación de muestras simplemente comentando o descomentando una sola sentencia ‘define’, por contraposción a comentar y descomentar bloques enteros de código lo cual resultaba engorroso y poco elegante.

Un saludo.

Groucho muestra emociones, aumenta su interactuación.

Posted in Uncategorized on mayo 22, 2009 by emotionalbot

Ahora, querríamos añadir funcionalidades a nuestro robot. Básicamente añadimos dos diferentes opciones de mostrar emociones por el robot:

  1. Sensor de presencia:Un poco más abajo está explicado el funcionamiento de este sensor, y la reacción del robot ante nuestra presencia o ausencia será la siguiente:
  • Ante una llegada a su cercanía, donde nos pueda ver, llamará la atención y se alegrará. De ahí pasará a imitar nuestras emociones.
  • Si nos ve y nos vamos, se empezará a enfadar paulatinamente según van pasando capturas, para al final quedarse triste, como podemos observar en el gráfico de los estados

2. Interactuación con el juego:

En el caso de recibir información del juego, que como hemos dicho se hace mediante el envío de un fichero de texto, el robot tendrá un comportamiento bastante interesante:

  • Primero, reaccionará frente a los datos. Si hay trampas, se enfadará bastante con una reacción bastante llamativa y quedará al final maquinando. Si ha perdido, hará algo parecido pero se quedará triste
  • Después ponemos el número de capturas a 0, y el bit correspondiente en un array de chars de nuestro programa a 1, de forma que cuando las capturas lleguen a 20, y llamemos a la rutina correspondiente, como trampas o perdido serán 1, el robot ya no imitará, sino que mostrará una emoción según la emoción mostrada por el jugador tras hacer trampas o ganar.

Pongamos un ejemplo sencillo. El jugador hace trampas, el robot estaba imitando al jugador que estaba sonriendo. Al detectar las trampas, el robot se enfada y se queda maquinando. Supongamos que el jugador sonríe, el robot se enfadaría, pero si el jugador ante su trampa se enfadará, el robot se asustaría (¿Sería un poco raro no? Haces trampas y encima te enfadas…)

Para dejar claro el proceso que sigue el robot en su muestra de emociones, hemos realizado un diagrama de estados, que se adjunta a continuación:

estados

Simplemente indicar que en el diagrama, el globo de responde emoción engloba tanto la imitación en caso de que no haya llegado información de la partida, como la reacción ante esta información en caso de si haber llegado.

El esquema seguido sería el siguiente:

if hay trampas—->según la emoción mostrada, respondo.

else if he perdid—->según la emoción mostrada, respondo.

else——->según la emoción mostrada, imito.

Groucho mostrando emociones sencillas. Dónde fueres haz lo que vieres.

Posted in Uncategorized on mayo 22, 2009 by emotionalbot

Ahora, nuestro trabajo, se va a basar en cómo responderá la cara de nuestro robot Groucho, según los datos de la webcam y del juego que vaya recibiendo.

Existen una serie de métodos ya definidos por el alumno que está trabajando con la cara para su proyecto de fin de carrera, Carlos, al que agradecemos su colaboración.

Estos métodos cubren prácticamente todas las emociones, y pretendemos adaptarlos a nuestro esquema de emociones para que el robot nos responda según nuestro estado emocional. Así, nuestro primer objetivo, es que el robot nos imite, es decir, nuestro robot va a seguir el dicho típico de donde fueres haz lo que vieres, y por tanto y según la emoción que nosotros tengamos, el mostrará la misma, e irá cambiando cada 20 capturas.

Las emociones se identifican bastante bien en la cara robótica, porque el robot tiene servos para la boca, las cejas y los párpados, con lo cual hay un enorme rango de emociones. A cada uno de los 5 servos se le define un estado. Los estados están definidos en otro archivo, aunque son bastante intuitivos: ARRIBA, ABAJO, AMPLIA, ENTOR, ARRIBA2, ABAJO2, etc.  Probamos con bastantes variaciones, con lo cual adaptamos los primeros métodos que existían a lo que nosotros necesitamos. Por ejemplo un método para mostrar una emoción en la cara del robot sería algo así:

void caraAGusto(void)

{

printf(“cara a gusto\n”);

Cejas.estado=ARRIBA;

Cejas.amplitud=0;

Cejas.frecuencia=NULA;

Parpados.estado=ENTOR;

Parpados.amplitud=0;

Parpados.frecuencia=NULA;

Boca.estado=ARRIBA2;

Boca.amplitud=0;

Boca.frecuencia=NULA;

controlParpados(Parpados, cara, serial_port);

controlCejas(Cejas, cara);

controlBoca(Boca, cara);

tx_secuencia(cara,serial_port,sizeof(cara));

}

Antes de llamar a estos métodos, es necesario que la cara esté conectada a la alimentación y también llamar al método inicializa().

Obteniendo la información del 3 en raya.

Posted in Avances en la práctica on mayo 22, 2009 by emotionalbot

Quizás después de todo este tiempo trabajando con la webcam, hemos perdido un poco la noción del contexto en el que nos encontramos, y hemos de recordar, que el robot que “vea” con nuestra webcam, también deberá jugar al tres en raya, y así poder conseguir que converjan la práctica de nuestros compañeros Juan Carlos Hernández y Enrique Fueyo. (http://3nraya.wordpress.com/)

Para la comunicación con el sistema del juego al tres en raya, nos será necesario leer un fichero, donde ellos nos pasarán la información de la partida (la comunicación será por el sistema trivial FTP) ,  y nosotros actuaremos según lo leído. En principio, el formato definido consiste en que el primer carácter represente con un 1 si ha habido cambios, el segundo si ha habido trampas y el tercero si el robot ha perdido. El método leerá un fichero, y guardará la información en un array de caracteres que devolverá.

Una vez leído y realizados los cambios del estado del robot, volveremos a poner los tres bits a 0, aunque el que importa realmente es el primero, que es en el que nos fijaremos para ver si hay cambios.

Como va a ser un fichero que va a ir cambiando, observamos que hay conflicto al leer los datos al probar con un fichero, y por tanto, añadimos un bucle en el que lo intente unas cuantas veces y en caso de que no lo consiga en esos intentos, devuelva los tres bits a cero, como si no lo hubiera leído.

Después habrá que hacer lo necesario con la información leída del fichero para reaccionar frente a los cambios en el estado de la partida, ya sea por trampas o por la finalización de ésta.

AGREGANDO FUNCIONALIDADES: “SENSOR DE PRESENCIA”

Posted in Avances en la práctica on mayo 14, 2009 by emotionalbot

Dado que Groucho es un robot cuya finalidad principañ es jugar con nosotros e intentar ganarnos, debe disponer de algún sistema para avisarnos de que quiere jugar cuando estemos cerca.

Hemos desarrollado esto mediante varias condiciones dentro del programa. En primer lugar el programa se ejecuta normalmente pero ahora, cada vez que entramos en el bucle de las capturas se incrementa una variable para saber el número de capturas sin caras. Posteriormente, en el caso de detectarse una cara, es decir en el caso de activarse tanto el clasificador de caras como el de ojos, que nos proporcinaba facedetect, dicha variable se decrementa. Por otra parte si ocurre eso aumenta una variable nueva llamada capturas con caras.

En el caso de estar el número de capturas con caras a 0 y producirse 100 capturas sin caras Groucho nos escribe un mensaje en pantalla avisándonos de que se aburre. Si llegamos a las 200 capturas nos escribirá uno aún más imperioso. Por otra parte si detecta una captura, automaticamente nos pedirá con un mensaje por pantalla que nos quedemos porque quiere jugar con nosotros. Además si se producen las 100 capturas con 1 o más capturas con caras el mensaje será para que volvamos a jugar (“vuelve!”) en lugar de “ven a jugar!”, es decir, Groucho sabrá cuando hemos estado jugando hace poco y cuando no hemos jugado en ningún momento. El número de caputuras sin caras se pone a cero cada vez que detectamos alguna cara.

Además es necesaria una variable temporizadora en forma de una serie de capturas 5-7, durante las cuales el sistema no puede enviarnos mensajes sobre nuestra proximidad o lejanía, una vez que el robot ha detectado que hemos vuelto. Esto se ha hecho así porque ahora el sensor de proximidad se actualiza cada 5 capturas y usamos su misma ventana como ventana por la que Groucho nos hace llegar sus mensajes, dado que si no la pantalla se llenaría de ventanas innecesarias. Así pues, si hemos estado jugando y volvemos aparecerá el mensaje de “bien has vuelto!”, pero si eso se produce en la captura número 4 de 5, no se verá pues automáticamente pasaremos al siguiente mensaje de proximidad o lejanía. Para solucionarlo usamos una variable que valdrá 5 o 7 cuando hayamos vuelto y que se irá decrementando cada vez que capturemos una cara. Al llega a un valor negativo el sistema volverá a mostrarnos mensajes de proximidad o lejanía.

De esta forma con una serie de sencillas variables sobre las caputuras se puede implementar un sensor de proximidad bastante útil.

Actualmente estamos pensando en utilizar la cara robótica de Groucho, ayer instalada gracias a Carlos, para que ponga diferentes caras como de aburrimiento o tristeza o enfado si no vamos a jugar con Groucho, e incluso hemos pensado en introducir audio al sistema en forma de reproducción de mensajes mp3 cada vez que groucho detecte alguna cosa para hacer el sistema más realista.

Ya veremos como queda al final, saludos.

VÍDEOS, EXPLICACIÓN DE LA PARTE VISUAL

Posted in Uncategorized on mayo 6, 2009 by emotionalbot

En los dos siguientes vídeos se pueden apreciar nuestros avances hasta el momento, por problemas con la cámara no hemos podido grabar el sonido explicando los detalles.

Vamos a explicar un poco la parte visual en la pantalla del ordenador del programa, aunque quizás no sea lo más importante, porque utilizaremos toda la información para que el robot actúe de una determinada forma, o te diga que te acerques o te alejes, pero no te lo mostrará en una pantalla. Sin embargo, en nuestro desarrollo hemos incluido imágenes y colores para que se vea fácilmente lo que ocurre en la pantalla del ordenador.

DETECCIÓN DE EMOCIONES

Cada emoción saldrá de un color. Recordamos que las emociones sonrisa fuerte, sonrisa floja, sorpresa y neutral se detectarán en la boca, y cada una de ellas saldrá de un color. A parte, el enfado, detectado en los ojos saldrá de color azul. Estos colores indican lo que instantáneamente detectan los clasificadores, sin tener en cuenta nuestro filtrado posterior.

En nuestro filtrado posterior, como ya explicamos antes, vemos de 20 capturas cuál es la emoción predominante, basándonos en una serie de parámetros que determinamos por simple prueba y observación. Con esto, cuando sepamos qué emoción predomina, mostramos una imagen con esa emoción en la ventana de estado. Buscamos robustez, y por tanto, podremos observar que es mejor detectar el estado normal de más que detectar una emoción cuando no la haya.

En el siguiente vídeo demostramos la parte visual del programa de la parte de detección de emociones.

VÍDEO 1: Deteccíon de emociones. Demo by Dani.

http://lorien.die.upm.es/juancho/20090506184145.mpg

DETECCIÓN DE DISTINCIÓN ENTRE DOS PERSONAS

Como ya indicamos lo haremos basándonos en el clasificador de enfado y se abrirá otra ventana en la que saldrá una foto de Dani o de Jorge, según quien sea el que está enfrente. Como en el caso de Jorge no tenemos grabados los clasificadores, no aparecerá su emoción, sino una cara interrogante.

DETECCIÓN DE DISTANCIAS Y MOVIMIENTO

Como ya se explicó en una entrada anterior, las distancias tendrán distintos rangos, que aparecerán en otra ventana nueva, que nos indicará si estamos demasiado cerca o demasiado lejos.

Otra ventana utilizará la función del movimiento indicandono si nos hemos acercado o alejado o nos hemos quedado quietos.

En caso de no estar en el rango óptimo, no nos indicará ni quién es la persona, ni que estado emocional tiene, porque podría fallar y simplemente sale una cara interrogante en ambas ventanas.

En el siguiente vídeo demostramos la parte visual del programa de la parte de detección de distinción entre Dani y Jorge y de detección de distancia y movimiento.

VÍDEO 2: Detección de distinción entre dos personas, de distancias y movimiento by Jorge.

http://lorien.die.upm.es/juancho/20090506184912.mpg