PC & Mobile

Reconnaissance faciale en temps réel – Goran Jovanov – Moyen

Reconnaissance faciale en temps réel - Goran Jovanov - Moyen


Il n'y a pas si longtemps, Vincent Mühler a publié plusieurs articles sur son étonnante bibliothèque de reconnaissance de visage face-api.js basée sur TensorFlowJS. Pour moi, ayant déjà travaillé avec OpenCV côté serveur, l’idée de faire de la reconnaissance faciale dans le navigateur me paraissait assez complaisante à essayer. Face à cette curiosité, Face® est né.

Face® n'est pas un projet d'intelligence artificielle, mais simplement un projet d'ingénierie, essayant d'utiliser face-api.js pour effectuer la reconnaissance faciale dans le navigateur et concevoir une solution logicielle prenant en charge les aspects de l'application, tels que:

  • Enregistrement de l'utilisateur
  • Chargement des modèles
  • Téléchargement, redimensionnement et suppression d'images
  • Utiliser l'appareil photo (prendre et redimensionner des photos, reconnaissance du visage)
  • Formation (extraction de repères / descripteurs de visages) et stockage de modèles
  • DevOps - Déploiement à l'aide de Docker

en utilisant la pile technologique suivante:

  • VueJS / NuxtJS / VuetifyJS - Frontend (simplement pour avoir fière allure)
  • NodeJS / ExpressJS - Backend (contenu statique et gestionnaires d'API)
  • PM2 - Clustering (support multi processus - un par cœur de CPU)
  • Docker / Apline Edge - Déploiement (application conteneurisée lean)

Si vous voulez en savoir plus sur la bibliothèque face-api.js, je vous recommande de commencer par le message de Vincent.

Ici, nous allons nous concentrer sur la création d’une application utilisant cette bibliothèque.

Alors plongeons dedans.

Des modèles

Nous allons utiliser les modèles suivants:

  • Détecteur de minuscules visages - 190 KB - pour la détection de visages (rectangles de visages)
  • Modèles de détection de points de repère en 68 points - 80 kb - pour l'extraction de points de repère du visage (yeux, sourcils, nez, lèvres, etc.)
  • Modèle de reconnaissance de visage - 6.2 MB

La taille totale de tous les modèles est inférieure à 6,5 MB.

Flux de travail de l'application

Par souci de simplicité, cette application n’utilisera aucune base de données comme stockage proprement dit, mais le processus d’enregistrement de chaque utilisateur s’appuiera sur:

  • créer un nouveau sous-dossier dans le dossier / data / users / par exemple. pour l'utilisateur Goran l'application va créer / data / users / Goran, dans lequel seront stockées toutes ses photos nécessaires à la formation du modèle de reconnaissance faciale.
  • et modèle de reconnaissance faciale formé pour tous les utilisateurs et toutes leurs photos seront stockées dans un fichier statique /data/faces.json (voir format ci-dessous).

Tout d'abord, l'utilisateur devra s'inscrire en tapant son nom, après quoi il / elle devra télécharger au moins 3 photos de lui-même. Le téléchargement de photos peut être effectué soit par un téléchargement de fichiers ou en prenant des photos en utilisant le caméra de navigateur (API WebRTC getUserMedia). Pendant le téléchargement, toutes les photos sont redimensionnées 320x247 en utilisant la bibliothèque de traitement d’image performante sharp.

Après l’enregistrement, l’utilisateur peut démarrer le processus de formation, qui prend tous les utilisateurs du catalogue (et leurs photos téléchargées) et des extraits:

  • rectangles avec leurs visages (facultatif)
  • 68 points de repère face (facultatif)
  • 128 descripteurs de visage (requis uniquement pour l'apprentissage du modèle)

et stocke le la modèle de reconnaissance de visage dans le fichier statique /data/faces.json dans le format suivant:

Architecture

L'application utilise NUXT.JS avec SSR (rendu côté serveur) et suit la convention de structure de répertoire par défaut.

L'application en Mode de développement va diviser le SERVEUR dans deux processus distincts:

  • /server/index.js- pour le contenu statique (frontend) - écoute sur le port 3000
  • /api/index.js- pour les appels API (backend) - écoute sur le port 3001
npm run dev
npm run api

En séparant le client du serveur pendant le développement, nous réduisons le nombre de fichiers chargés par Nuxt, ainsi que la taille et la durée de ce fichier. démarrage initial, ainsi que nous bénéficions de plus rapide démarrage / arrêt consécutif de l'API nécessaire lors du débogage.

D'autre part, dans mode de production, l’application fusionne le côté serveur en un seul processus, l’écoute sur le port 3000.

npm run build
npm run start

Chargement des modèles

Lorsque l'utilisateur se connectera à notre application, nous chargerons tous les modèles TensorflowJS. Pour ce faire, nous utiliserons le monté() gestionnaire de la /layouts/default.vue :

Avec charge() l'action étant traitée par /store/face.js:

Enregistrement de l'utilisateur

Nous enregistrons l'utilisateur via le formulaire simple dans le /pages/users/index.vuepage gérée par le registre() méthode:

Avec registre() l'action étant traitée par le /store/user.js:

Et appel API en cours de traitement par /api/controller/user-controller.js :

qui crée un nouveau dossier: / data / users / _name .

Téléchargement de photos

L'utilisateur dispose de deux options / onglets pour télécharger une photo:

  • onglet-1: Soit par une entrée HTML de téléchargement de fichier, gérée par filesChange () méthode (redimensionnée à 320x247côté serveur)
  • onglet 2: Ou en utilisant la caméra du navigateur (WebRTC getUserMedia API) et en prenant des instantanés de photo via le canevas HTML5, géré par prendre une photo() méthode (dimensionnée à 320x247côté client)

Après l’enregistrement, nous avons consulté l’utilisateur sur la page où il peut continuer de télécharger des photos. /pages/users/_name.vue.

Avec télécharger() et uploadBase64 () actions en cours de traitement par le /store/user.js:

Et les appels d'API en cours de traitement par /api/controller/user-controller.js :

Pour extraire le contenu du fichier de la mutipart / form-data nous utilisons Multer. De plus, étant donné que l'utilisateur peut télécharger des images de différentes tailles et formes, nous redimensionnons l'image téléchargée à l'aide de sharp. Enfin, les photos sont stockées dans le dossier de l’utilisateur: / data / users / _name /.

Formation - Exraction de descripteur de visage

La formation est le processus d'extraction de 128 descripteurs de visage sur une image pour un utilisateur donné (vecteur de 128 valeurs de descripteur).

Il est recommandé qu'un utilisateur ait au moins 3 photos téléchargées pour la formation. Par conséquent, après la formation, le modèle de reconnaissance faciale sera composé de n X m vecteurs descripteurs; m - étant le nombre d'utilisateurs et n - le nombre de photos pour un utilisateur donné.

Nous pouvons effectuer une formation de l’une des manières suivantes:

  • Un par un - formation après chaque téléchargement de photos d'un utilisateur sélectionné
  • Par utilisateur - formation pour les photos de tous les utilisateurs d’un utilisateur sélectionné
  • Lot - formation pour tous les utilisateurs et toutes leurs photos à la fois

Dans cette application, nous allons mettre en œuvre un Lotprocessus de formation, qui finira par stocker le modèle de reconnaissance de visage à l'intérieur de /data/faces.jsonfichier.

Le processus de formation par lots est lancé à partir du /pages/train.vue:

qui parcourt la liste des utilisateurs et, pour chacune de leurs photos, extrait les descripteurs de visage (128 descripteurs de visage). Ensuite, le modèle de reconnaissance de visage JSON est enregistré via le enregistrer() action du /store/face.js:

Et l'appel d'API en cours de traitement par /api/controllers/face-controller.js:

Reconnaissance

Le processus de reconnaissance de visage lit le modèle de reconnaissance de visage (faces.json) et crée un Matcher Visage, capable de calculer le Distance euclidienneentre les vecteurs descripteurs de visage du modèle de reconnaissance de visage enregistré et tout nouveau visage à reconnaître.

Dans l’interface utilisateur, via la caméra (API WebRTC getUserMedia), nous commençons à échantillonner avec 60 images par seconde (images par seconde) instantané stocké dans un élément de canevas HTML. Ensuite, pour chaque instantané de ce type, nous extrayons ses descripteurs de visage et, à l'aide de l'outil de correction de visage, nous produisons la meilleure correspondance et le renvoyons sur le canevas.

Le processus de reconnaissance faciale est lancé via le /pages/recognize.vue:

getFaceDetections () , drawLandmarks (), reconnaître()et drawDetections ()les actions sont gérées par /store/face.js:

Production

Comme NodeJS fonctionne par défaut dans un seul processus, cette approche n’est pas optimale en production, en particulier si nous avons du matériel avec plusieurs processeurs et / ou cœurs de processeur.

Par conséquent, nous utiliserons PM2 pour instancier autant de processus que le nombre de cœurs de processeur dont nous disposons (-i0 param), et équilibrons la charge de la requête entre ces processus:

pm2 start server / index.js -i 0 - attach

Déployer

Nous allons emballer notre application comme une image très maigre, basée sur Alpine: Edge (moins de 300 Mo car la taille compte):

Ensuite, nous pouvons soit:

  • construire l'image de Docker par docker construire -t gjovanov / facer.
  • ou utiliser le script de versioning de Travis Reeder ./build.sh

Ou tirez celui de Docker Hub docker tirer gjovanov / facer.

Enfin, nous pouvons exécuter le conteneur Docker en:

docker run -d --name facer 
--hostname facer
--restart toujours
-e API_URL = https: //facer.xplorify.net
-p 8081: 3000
-v / gjovanov / facer / data: / facer / data
--net = pont
gjovanov / facer

Code source et démo

Le code source et une démo sont disponibles à l’essai.

Toute suggestion d’amélioration ou de demande de retrait est la bienvenue.

Show More

SupportIvy

SupportIvy.com : Un lieu pour partager le savoir et mieux comprendre le monde. Meilleure plate-forme de support gratuit pour vous, Documentation &Tutoriels par les experts.

Related Articles

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Close
Close