Reconnaissance des émotions et des expressions faciales

Fin 2010, en 5ème année à l’ESGI, Mr Lioret, professeur du cours d’animation comportementale, d’intelligence artificielle et de « machine learning », nous explique que les réseaux de neurones artificiels peuvent permettre de déterminer sur la photo d’un visage l’émotion qui s’y trouve. C’est à ce moment que Mathieu Jeudi et moi avons décidé de faire de la reconnaissance d’expressions faciales notre sujet de fin d’étude. Voici donc le résultat concluant de notre expérimentation.

Stack technique

OpenCV et C++ sous Visual Studio

Etape 1 : la recherche

Tous projets du type "Comment on fait? on y connait rien" demande de faire des recherches. Double objectif : étude de faisabilité et récupération des données inhérentes a la conception du projet: librairies, articles, contact, liens images, etc.. Bref, pour vois épargner certaines de ces recherches voilà un série de documents qui vous aidera si vous suiviez la même entreprise que nous:

PDF : A Fusion Process Based on Belief Theory for Classification

PDF : Automatic Facial Emotion Recognition

PDF : Feature-Point Tracking by Optical Flow Discriminates

PDF : Haarlike

PDF : La reconnaissance en général

PDF : Real Time Facial Feature Points Tracking with

PDF : Reconnaissance d’Expressions Faciales à l’Aide d’une Mémoire Associative

PDF : Simple approach to facial expression recognition

PDF : Stavensopencvoptical_flow

PDF : Visual-Based Emotion Detection for Natural

Pour tester l’efficacité et la mise en œuvre du projet, un échantillon de visages exprimant différentes émotions était nécessaire. Nous avons cherché à obtenir les bases de données qui, dans le monde, ont prouvé leur efficacité pour la reconnaissance d’expressions faciales ; il faut citer : la « Hammal-Caplier database », la « Cohn Kanade database » et la « Cottrel database ». Seule la base de données de Cohn Kanada est disponible gratuitement à des fins non commerciales. Malheureusement, après avoir contacté avec succès l’université la fournissant et lui avoir fourni les pièces nécessaires à l’obtention de la base, aucune suite n’a été donnée de sa part. Suite à cela, une seule solution : utiliser nos propres visages pour les tests du projet.

L’efficacité du python et la présence de la librairie « openCV » en python pour la reconnaissance faciale nous ont d’abord amené à utiliser l’interface de développement « Eclipse » conjointement au python. Il apparaît clairement que la documentation sur openCV était trop faible en python pour réaliser le projet. De ce fait nous avons changé de langage en passant au C++ avec « openCV » sous « Visual Studio 2010 ».

Etape 2 : Petit retour historique

Alors que l’innovation et les technologies récentes poussent de plus en plus l’interactivité homme-machine à être maximale, la recherche des expressions faciales est un point fondamental dans de nombreuses applications. Il ne faut cependant pas oublier que la recherche des expressions faciales est un sujet bien plus ancien que la recherche d’interaction entre l’homme et la machine. Cette recherche trouve ces fondements dans les travaux menés par Darwin. Par la suite Ekman formalise cette recherche en classant les expressions faciales en 6 émotions : joie, tristesse, surprise, peur, colère et dégoût. Ces émotions sont, selon sa définition ; communes à tous les êtres humains.

FACS

Dans les années 70, une méthode de description des mouvements du visage est développée par les psychologues Paul Ekman et Wallace Friesen : le « FACS » (facial action coding system). Ce « FACS » classe les mouvements du visage en une quarantaine d’unités d’action (exemple : Action Unit le front se plisse). C’est en utilisant le « FACS » que nous pouvons relier les émotions humaines aux mouvements du visage.

Etape 3 : la technique - La reconnaissance des expressions faciales

Notre projet a demandé des ressources techniques ; aussi bien conceptuelles (la technique à utiliser) que fonctionnelles (la mise en œuvre). Il peut être décomposé en trois parties : d’abord la reconnaissance des éléments du visage, puis l’extraction des points caractéristiques à étudier et enfin, l’utilisation de ces points pour définir une émotion.

La reconnaissance faciale représente un enjeu clé dans la reconnaissance d’émotions. La principale difficulté de la reconnaissance faciale est qu’il n’existe pas deux visages identiques. De ce fait, chaque individu possède un faciès qui lui est propre et qui sera marqué par son sexe, son ethnie, son âge ou encore sa coupe de cheveux. A cela, s’ajoutent encore la forme, la taille et la disposition des éléments du visage. Par exemple, la détection d’un visage fin mais asymétrique éloigné de la caméra ne répond pas aux mêmes critères que celle d’un visage large rougi par le froid et très proche de la caméra.

haar

Afin de répondre à ces conditions, nous avons choisi de mettre en place l’une des premières techniques utilisées dans la détection de visage en temps réel : la méthode de Paul Viola et Michael Jones3. Cette méthode, utilisée aujourd’hui dans le monde entier, vise à regrouper les pixels de l’image en un ensemble de groupes de pixels contigus, formant alors des zones. Chaque zone possède donc une couleur moyenne. Pour deux zones contiguës, les pixels de la zone la plus claire sont soustraits à ceux de la zone la plus sombre et de la zone la plus claire. On parle alors de caractéristique « pseudo Haar » ou plus communément et internationalement de « Haar-like features ».

Conjointement à ce procédé, l’essentiel de la technique réside dans l’utilisation d’un « classifier ». Un « classifier » est une méthode d’analyse de l’image permettant de regrouper et de classer l’ensemble des caractéristiques « pseudo Haar » d’une image. L’utilisation de ce « classifier » est cependant délicate. En effet, un « classifier » de visage utilisé sur une photo demande à ce que la comparaison « classifier »/photo soit faite à différentes échelles et autant de fois qu’il est possible de placer pour chaque échelle une zone d’analyse sur la photo. Cela a pour impact le rejet de nombreuses zones qui ne correspondent pas au « classifier ».

De ce fait, pour optimiser au mieux l’analyse d’une photo, Paul Viola et Michael Jones4 proposent de classer les données en cascade de sorte à pouvoir rejeter au plus tôt toute fausse correspondance entre la zone de la photo analysée et le « classifier ». Ainsi, une cascade est composée de plusieurs « classifiers ». Le premier « classifier » est le plus optimisé et permet de rejeter plus rapidement une zone si aucun visage ne s’y trouve. Si potentiellement un visage s’y trouve, alors le deuxième « classifier » est utilisé et ainsi de suite jusqu’au dernier.

<img src="./imgs/HaarCascade.png" " " title="IllustrationArchitectureCascade">

Etant donné qu’il faut plusieurs centaines d’individus, tous différents les uns des autres, pour créer un « classifier » efficace, nous avons utilisé le fichier haarcascadefrontalfacealt.xml qui est une cascade de « classifier » pour le visage.

Dans la pratique, c’est avec la bibliothèque openCV que nous avons réalisé l’intégralité des traitements de reconnaissance faciale. La première étape consiste donc à charger les cascades de « classifiers ». Pour notre besoin, nous chargeons les cascades qui nous permettent de trouver le visage, les yeux et la bouche. Ensuite, pour chaque frame de l’image nous utilisons :

//ms_ImageReduitePourAnalyse est l’image de la vidéo à l’instant t que nous avons réduite pour accélérer les traitements.
//CFace::ms_CascadeVisage est la cascade de « classifier » du visage.
//ms_Storage est un espace de stockage pour les traitements.
//1.10 est le facteur d’échelle de l’image.
//2 est le nombre de voisins minimums à une zone pour qu’elle soit analysée.
//CV_HAAR_DO_CANNY_PRUNING est utilisé pour optimiser les traitements en supprimant les cas où il y a trop de contours ou pas assez.
//cvSize(20, 20) est la taille minimum en pixels d’une zone d’analyse sur la photo. Plus cette valeur est petite, plus les traitements sont longs
cvHaarDetectObjects( ms_ImageReduitePourAnalyse, CFace::ms_CascadeVisage, ms_Storage, 1.10, 2, CV_HAAR_DO_CANNY_PRUNING,cvSize(20, 20) )

Une fois le visage récupéré de la sorte, nous réitérons l’opération, sur le visage uniquement, afin de récupérer cette fois les yeux et la bouche. cvHaarDetectObjects() étant très stricte sur les paramètres à utiliser de nombreuses opérations sur l’image sont nécessaires, tels que des redimensionnements, des passages en niveaux de gris ou encore des réductions de zone d’analyse. Une fois le visage récupéré, ainsi que les yeux et la bouche, le tracking des points caractéristiques du visage peut commencer.

Etapes 4 : la technique - Le «facial tracking »

Afin de déterminer les unités d’actions, nous devons détecter le mouvement de 8 points stratégiques :

  • Les deux coins de la bouche
  • Le haut de la lèvre supérieure
  • Le bas de la lèvre inférieure
  • Deux points par sourcils soient quatre au total

<img src="./imgs/tracking-UA.jpg" "tracking - Action Unit" title="35">

Nous voyons, qu’à chacun des mouvements des différents points, correspond une unité d’action:

  • Lever des points intérieurs des sourcils (AU1)
  • Lever des points extérieurs des sourcils (AU2)
  • Abaissement des points extérieurs des sourcils(AU4)
  • Lever de la lèvre supérieure(AU10)
  • Lever des coins des lèvres(AU12)
  • Abaissement des coins des lèvres(AU15)
  • Extension de la bouche(AU20)
  • Rétrécissement de la bouche(AU24)
  • Abaissement de la lèvre inférieure(AU26)

La phase de détection de mouvements s’effectue en plusieurs étapes :

  • Détection de l’emplacement des points à l’état initial.
  • Détection du mouvement de ces points en calculant l’écart entre la position courante et la position initiale.
  • Déclenchement d’une unité d’action en fonction du résultat obtenu.

Une fois l’ensemble des unités d’actions calculées pour un visage donné à l’instant t, une émotion doit être attribuée au visage.

Etape 5 : la technique - Le tri des émotions

Le tri des émotions doit faire face aux changements d’états et à la pluralité des émotions sur un visage. En effet, le passage de la surprise à la joie entraîne un changement d’état progressif. De même, un individu qui est surpris peut aussi être effrayé. La logique fut donc dans notre projet d’utiliser un réseau neuronal dit linéaire. Celui-ci est composé de 9 entrées et 6 sorties :

réseau neuronal - les entrées sorties

Pour que la jonction soit parfaitement effective entre les entrées et les sorties, le réseau neuronal est composé de 10 neurones cachés. Cette valeur est choisie dans le but d’offrir une efficacité maximum dans les réponses obtenues. Chaque entrée étant connectée à chaque neurone caché et chaque neurone caché étant relié à chaque sorties, il existe en tout 150 connections. Conformément à la définition d’un réseau neuronal, chaque connexion est pondérée par un poids dont la valeur varie entre -0.5 et 0.5. La détermination de ces poids se produit lors de l’apprentissage du réseau neuronal. L’apprentissage doit suivre des règles précises, c’est-à-dire qu’il faut informer quelles sont les valeurs des unités d’action pour chaque émotion.

réseau neuronal - Règles d’apprentissage

La méthode d’apprentissage choisie est celle de la rétro- propagation : chaque poids est initialisé aléatoirement et modifié en fonction des erreurs produites par le lancement du réseau de neurones.

Résultat final

Nous obtenons une application capable de détecter nos émotions en temps réels. Un graphique présentant le résultat de l’émotion engendrée en fonction des unités d’actions déclenchées est présent au sein de l’application. Celui-ci se met à jour en temps réel.

Utilisation

Bouton d’initialisation: L’initialisation est obligatoire, cette phase permet de stocker la position des points à l’état initiale. Il est indispensable d’adopter un visage neutre durant cette phase.

Bouton de mise en pause: L’affichage est figé et le calcul des émotions ne se fait plus lorsque le programme est en pause

Bouton d’affichage des éléments du visage: Ce bouton permet d’afficher un cadre autour du visage, de la région des yeux ainsi que de la bouche

A travers nos différents tests, nous avons pu nous rendre compte que les résultats sont différents selon les situations.Plusieurs critères influent sur la qualité des résultats :

  • Celle-ci doit rester le plus identique possible à celle acquise lors de l’initialisation. Il est nécessaire d’être placé face à l’écran les yeux rivés sur celui-ci, la tête doit être la plus droite possible afin de pouvoir correctement déterminer les points de tracking.
  • Les points de tracking étant attribués grâce au contraste entre les régions d’intérêt, nous obtiendrons de meilleurs résultats si, par exemple, la personne est rasée. Le visage ne doit pas être couvert par des lunettes de soleil ou tout autre accessoire pouvant nuire à la détection des éléments du visage.
  • Afin d’être correctement déterminée, celle-ci doit être très prononcée. En effet, la différence entre la peur et la colère n’est pas des plus marquantes.
  • Les résultats ne sont pas pertinents si la luminosité de la pièce dans laquelle se trouve l’utilisateur est trop faible ou au contraire trop élevée.
  • L’image présente un léger mouvement lors de la capture, par conséquent les points de tracking se voient constamment légèrement modifiés.