Ce guide s’adresse aux développeurs cherchant à intégrer rapidement et de manière stable la reconnaissance d’expressions faciales en temps réel dans une application web. Nous utilisons la librairie JavaScript Face-API.js, exécutée localement dans le navigateur grâce à TensorFlow.js.
Cet article fournit la méthodologie complète, incluant les solutions aux problèmes de cache et d’environnement souvent rencontrés dans ce type de projet.
Le code fourni est volontairement minimaliste afin d’aller droit au but sans “pollution” inutile. L’idée est que vous puissiez tester en un éclair. Commençons par une base front end simpliste. Remarquez qu’on a même pas besoin de charger TensorFlow, car FaceApi.js s’en chargera pour nous.
Nous n’avons donc à ce stade besoin que de 3 fichiers : la base HTML5, le fichier JS contenant toute la logique et 3 modèles à importer.
⚠️ Avertissement Crucial : Serveur Local Obligatoire
NE TENTEZ JAMAIS d’ouvrir directement le fichier detectEmotions.html depuis votre explorateur de fichiers (via l’URL file:///...).
Le chargement des modèles de Machine Learning (Étape 2) est soumis aux règles de sécurité des navigateurs. Sans un serveur HTTP local (comme Live Server de VS Code, un serveur Node ou Python), vous rencontrerez systématiquement des erreurs CORS et vos modèles ne se chargeront pas.
Étape 1. Structure du Projet et Dépendances
L’efficacité du système repose sur la bonne organisation des ressources.
| Ressource | Description | Rôle | 
| detectEmotions.html | La page hôte. | Charge les scripts et initialise le videoet lecanvas. | 
| detectEmotions.js | Le cœur de la logique. | Gère le chargement des modèles, l’accès à la webcam et la boucle de détection. | 
| ./face-api/ | Dossier de Modèles. | Contient les fichiers binaires ( .bin) et manifestes (.json) des réseaux neuronaux. | 
Exigence Cruciale : Pour un fonctionnement sans erreur CORS, le projet doit être servi via un protocole HTTP (ex: http://localhost:5500/), et non directement depuis le disque dur (file:///).
<!doctype html>
<html lang="fr">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Détection d'émotions en temps réel en utilisant TensorFlow.js et FaceAPI.js">
    <meta name="author" content="Techmastermind.fr">
    <script src="https://cdn.jsdelivr.net/npm/face-api.js@0.22.2/dist/face-api.min.js" defer></script>
    <script src="detectEmotions.js" defer></script>
    <title>Détection d'émotions avec TensorFlow + FaceAPI.js</title>    
</head>
<body>
    <div>
        <div class="text-center">
            <video id="video" width="500" height="500" crossorigin="anonymous" autoplay muted></video>
            <canvas id="overlay" width="500" height="500">
                Désolé, votre navigateur ne prend pas en charge <canvas>.
            </canvas>
        </div>
    </div>
</body>
</html>
    
Bien sûr vous pouvez utiliser le front de votre choix, pensez simplement à insérer face-api.js et les 3 modèles suivants dont nous aurons besoin.
Étape 2 – Acquisition et Organisation Locale des Modèles de réseaux de neurones
Les réseaux neuronaux utilisés par Face-API.js sont des fichiers volumineux. Tenter de les charger depuis un CDN ou un service tiers ralentit considérablement la démo.
La meilleure approche, en tant que développeur, est de les considérer comme des ressources statiques locales et de les placer à la racine de votre projet.
Le Dépôt Source
Vous pouvez récupérer tous les modèles pré-entraînés depuis le dépôt GitHub officiel : https://github.com/justadudewhohacks/face-api.js-models.
Organisation des Fichiers
Téléchargez les fichiers suivants et placez-les dans un dossier nommé /face-api à la racine de votre projet, comme défini dans notre code.
| Modèle (Réseau Neuronal) | Fichier Manifest (JSON) | Fichier de Poids (Binaire) | Rôle | 
| SSD MobileNet V1 | ssd_mobilenetv1_model-weights_manifest.json | 
 ssd_mobilenetv1_model-shard2.bin | Détection du visage | 
| Face Landmark 68 | face_landmark_68_model-weights_manifest.json | face_landmark_68_model-shard1.bin | Localisation des 68 points faciaux | 
| Face Expression | face_expression_model-weights_manifest.json | face_expression_model-shard1.bin | Reconnaissance des 7 émotions | 
Total : Vous devez donc copier ces 7 fichiers principaux.
Comment charger correctement les modèles Face-API.js sans erreur CORS
Le chemin d’accès dans votre JavaScript, const MODEL_URL = './face-api/';, garantit que ces fichiers seront chargés rapidement et sans erreur CORS depuis votre serveur local.
Étape 3 – Le Code JavaScript (detectEmotions.js)
Ce script intègre les correctifs pour l’initialisation, le cache réseau (304), et le chemin d’accès, garantissant un démarrage stable du système.
let video = document.getElementById('video');
let canvas = document.getElementById('overlay');
// Chemin d'accès relatif essentiel pour les serveurs locaux (Live Server)
const MODEL_URL = './face-api/'; 
/**
 * Solution Avancée : Patch du service 'fetch'
 * Cette fonction surcharge l'appel réseau de Face-API.js. Elle contourne
 * l'erreur HTTP 304 (Not Modified) en forçant le navigateur à toujours
 * re-télécharger les modèles, garantissant un statut 200 OK.
 */
faceapi.fetch = (uri, options) => {
    const newOptions = { 
        ...options, 
        cache: 'no-store' // Ignore le cache local
    };
    return fetch(uri, newOptions); 
};
document.addEventListener("DOMContentLoaded", (event) => {
    
    // Chargement des trois modèles asynchrones requis :
    // 1. Détection du visage (ssdMobilenetv1)
    // 2. Landmarks faciaux (faceLandmark68Net)
    // 3. Détection des expressions (faceExpressionNet)
    Promise.all([
        faceapi.nets.ssdMobilenetv1.loadFromUri(MODEL_URL),
        faceapi.nets.faceLandmark68Net.loadFromUri(MODEL_URL),
        faceapi.nets.faceExpressionNet.loadFromUri(MODEL_URL)
    ]).then(startLiveDetection)
      .catch(err => {
          console.error("Erreur critique: Échec du chargement des modèles.", err);
      });
    function startLiveDetection() {
        
        // Nous utilisons les options par défaut du détecteur SSD MobileNet V1 pour une précision maximale.
        const detectionOptions = new faceapi.SsdMobilenetv1Options(); 
        // 2. Initialisation et connexion au flux de la webcam
        navigator.mediaDevices.getUserMedia({ video: {} })
            .then(stream => {
                video.srcObject = stream;
                
                // 3. Démarrage de la boucle de détection
                video.addEventListener('play', () => {
                    const displaySize = { width: video.width, height: video.height }; 
                    faceapi.matchDimensions(canvas, displaySize);
                    // Boucle de détection en temps réel, exécutée toutes les 100 ms
                    setInterval(async () => {
                        
                        // Enchaînement des étapes : Détection du visage -> Landmarks -> Expressions
                        const detections = await faceapi.detectAllFaces(video, detectionOptions) 
                            .withFaceLandmarks()
                            .withFaceExpressions();
                        // Mise à l'échelle des résultats pour correspondre au redimensionnement de la vidéo
                        const resizedDetections = faceapi.resizeResults(detections, displaySize);
                        
                        // Affichage
                        canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
                        faceapi.draw.drawFaceExpressions(canvas, resizedDetections, 0.05);
                    }, 100); 
                });
            })
            .catch(err => console.error("Erreur d'accès à la caméra : Veuillez vérifier les permissions.", err));
    }
});   
    
    
Étape 4 – Optimiser la reconnaissance d’expressions faciales avec TensorFlow.js
Une fois le code stable, l’étape suivante est l’optimisation des performances perçues :
Problème de Fidélité des Émotions
Si la détection du visage fonctionne mais que la lecture des émotions est incohérente, la cause est presque toujours la qualité des données d’entrée.
Le modèle d’expression (faceExpressionNet) est extrêmement sensible aux variations de lumière et de contraste. Une faible luminosité ou des ombres portées peuvent masquer les subtilités des micro-expressions, ce qui fait chuter le score de confiance des prédictions (ex: happy: 0.35 vs neutral: 0.30).
💡 Astuce : pour stabiliser la détection, réduisez la taille de la vidéo à 320×240 — les réseaux tourneront plus vite, améliorant la réactivité perçue sans perte majeure de précision.
Solution
Améliorer l’éclairage de la scène est la solution la plus efficace. Pour un débogage avancé, les développeurs peuvent consulter les scores bruts dans la console (via console.log(detections[0].expressions)) pour vérifier que le modèle travaille correctement mais manque de confiance, confirmant ainsi que la limite est physique (lumière) et non logicielle.
Conclusion
Face-API.js reste aujourd’hui la meilleure passerelle entre le monde du Machine Learning et le front-end. Ce type d’intégration ouvre la voie à des interactions web réellement émotionnelles, sans backend ni latence réseau.
Pour aller plus loin
Détection multi-visages :
detections.forEach(d => console.log(d.expressions));
🔗 Documentation officielle Face-API.js : https://justadudewhohacks.github.io/face-api.js/docs/


 
										