SYSTEME DE RECONNAISSANCE FACIALE AVEC PYTHON

 Dans ce didacticiel, vous apprendrez à utiliser OpenCV pour effectuer une reconnaissance faciale. Pour construire notre système de reconnaissance faciale, nous allons d'abord effectuer la détection des visages, extraire les intégrations de visage de chaque visage à l'aide d'un apprentissage en profondeur, former un modèle de reconnaissance faciale sur les intégrations, puis enfin reconnaître les visages dans les images et les flux vidéo avec OpenCV.


Vous pouvez bien sûr échanger votre propre ensemble de données de visages ! Tout ce que vous avez à faire est de suivre ma structure de répertoires pour insérer vos propres images de visage.

En prime, j'ai également inclus comment étiqueter les visages "inconnus" qui ne peuvent pas être classés avec suffisamment de confiance.

Pour savoir comment effectuer la reconnaissance faciale OpenCV, continuez à lire !

  • Mise à jour juillet 2021 : Ajout d'une section sur les méthodes alternatives de reconnaissance faciale à considérer, y compris la façon dont les réseaux siamois peuvent être utilisés pour la reconnaissance faciale.
Reconnaissance faciale OpenCV

Dans le didacticiel d'aujourd'hui, vous apprendrez à effectuer une reconnaissance faciale à l'aide de la bibliothèque OpenCV.

Eh bien, gardez à l'esprit que le message de reconnaissance faciale dlib s'appuyait sur deux bibliothèques externes importantes :

  1. dlib (évidemment)
  2. face_recognition (qui est un ensemble d'utilitaires de reconnaissance faciale facile à utiliser qui entoure dlib)

Bien que nous ayons utilisé OpenCV pour faciliter la reconnaissance faciale, OpenCV lui-même n'était pas responsable de l'identification des visages.

Dans le tutoriel d'aujourd'hui, nous allons apprendre comment nous pouvons appliquer ensemble l'apprentissage en profondeur et OpenCV (sans autres bibliothèques que scikit-learn) pour :

  1. Détecter les visages
  2. Calculer des plongements de visage 128-d pour quantifier un visage
  3. Former une machine à vecteurs de support (SVM) au-dessus des incorporations
  4. Reconnaître les visages dans les images et les flux vidéo

Toutes ces tâches seront accomplies avec OpenCV, nous permettant d'obtenir un pipeline de reconnaissance faciale OpenCV "pur".

Comment fonctionne la reconnaissance faciale d'OpenCV

Figure 1 : Un aperçu du pipeline de reconnaissance faciale OpenCV. L'étape clé est un extracteur de caractéristiques CNN qui génère des incorporations faciales 128-d. source )

Afin de construire notre pipeline de reconnaissance faciale OpenCV, nous appliquerons l'apprentissage en profondeur en deux étapes clés :

  1. Pour appliquer la détection de visage , qui détecte la présence et l'emplacement d'un visage dans une image, mais ne l'identifie pas
  2. Pour extraire les vecteurs de caractéristiques 128-d (appelés "embeddings") qui quantifient chaque visage dans une image

J'ai déjà expliqué comment fonctionne la détection de visage d'OpenCV , veuillez donc vous y référer si vous n'avez pas détecté de visages auparavant.

Le modèle responsable de la quantification réelle de chaque visage dans une image provient du projet OpenFace , une implémentation Python et Torch de la reconnaissance faciale avec apprentissage en profondeur. Cette implémentation provient de la publication CVPR 2015 de Schroff et al., FaceNet: A Unified Embedding for Face Recognition and Clustering .

L'examen de l'ensemble de la mise en œuvre de FaceNet n'entre pas dans le cadre de ce didacticiel, mais l'essentiel du pipeline peut être vu dans la figure 1 ci-dessus.

Tout d'abord, nous entrons une image ou une image vidéo dans notre pipeline de reconnaissance faciale. Étant donné l'image d'entrée, nous appliquons la détection de visage pour détecter l'emplacement d'un visage dans l'image.

En option, nous pouvons calculer des repères faciaux , ce qui nous permet de prétraiter et d'aligner le visage .

L'alignement des visages, comme son nom l'indique, consiste à (1) identifier la structure géométrique des visages et (2) tenter d'obtenir un alignement canonique du visage basé sur la translation, la rotation et l'échelle.

Bien qu'il soit facultatif, il a été démontré que l'alignement des visages augmente la précision de la reconnaissance faciale dans certains pipelines.

Après avoir (éventuellement) appliqué l'alignement et le recadrage des visages, nous passons le visage d'entrée à travers notre réseau de neurones profond :

Figure 2 : Comment le modèle de reconnaissance faciale d'apprentissage en profondeur calcule l'intégration du visage.

Le modèle d'apprentissage en profondeur FaceNet calcule une incorporation de 128 d qui quantifie le visage lui-même.

Mais comment le réseau calcule-t-il réellement l'intégration du visage ?

La réponse réside dans le processus de formation lui-même, notamment :

  1. Les données d'entrée sur le réseau
  2. La fonction de perte de triplet

Pour entraîner un modèle de reconnaissance faciale avec le deep learning, chaque lot de données d'entrée comprend trois images :

  1. L' ancre
  2. L' image positive
  3. L' image négative

L'ancre est notre visage actuel et a l'identité A .

La deuxième image est notre image positive — cette image contient également un visage de la personne A .

L'image négative, en revanche, n'a pas la même identité , et pourrait appartenir à la personne B , C , ou même Y !

Le fait est que l'ancre et l'image positive appartiennent toutes deux à la même personne/visage alors que l'image négative ne contient pas le même visage.

Le réseau de neurones calcule les incorporations 128-d pour chaque face, puis ajuste les poids du réseau (via la fonction de perte de triplet) de telle sorte que :

  1. Les plongements 128-d de l'ancre et de l'image positive sont plus proches l'un de l'autre
  2. Tout en repoussant les intégrations du père de l'image négative

De cette manière, le réseau est capable d'apprendre à quantifier les visages et de renvoyer des incorporations très robustes et discriminantes adaptées à la reconnaissance faciale.

Et de plus, nous pouvons réellement réutiliser le modèle OpenFace pour nos propres applications sans avoir à le former explicitement !

Même si le modèle d'apprentissage en profondeur que nous utilisons aujourd'hui n'a (très probablement) jamais vu les visages que nous sommes sur le point de traverser, le modèle sera toujours capable de calculer les intégrations pour chaque visage - idéalement, ces intégrations de visage seront suffisamment différent de sorte que nous pouvons former un classificateur d'apprentissage automatique "standard" (SVM, classificateur SGD, Random Forest, etc.) au-dessus des incorporations de visage, et donc obtenir notre pipeline de reconnaissance faciale OpenCV.

Si vous souhaitez en savoir plus sur les détails entourant la perte de triplets et sur la façon dont elle peut être utilisée pour former un modèle d'intégration de visage, assurez-vous de vous référer à mon article de blog précédent ainsi qu'au Schroff et al. parution .

Notre ensemble de données de reconnaissance faciale

Figure 3 : Un petit exemple de jeu de données de visage pour la reconnaissance faciale avec OpenCV.

L'ensemble de données que nous utilisons aujourd'hui contient trois personnes :

  • Moi-même
  • Trisha (ma femme)
  • "Inconnu", qui est utilisé pour représenter les visages de personnes que nous ne connaissons pas et que nous souhaitons étiqueter comme tels (ici, je viens d'échantillonner des visages du film Jurassic Park que j'ai utilisé dans un post précédent - vous pouvez insérer votre propre "inconnu " base de données).

Comme je l'ai mentionné dans l'introduction du message de reconnaissance faciale d'aujourd'hui, je viens de me marier le week-end, donc ce message est un "cadeau" pour ma nouvelle femme ?.

Chaque classe contient un total de six images.

Si vous construisez votre propre ensemble de données de reconnaissance faciale , idéalement, je suggérerais d'avoir 10 à 20 images par personne que vous souhaitez reconnaître - assurez-vous de vous référer à la section "Inconvénients, limites et comment obtenir une plus grande précision de reconnaissance faciale" de ce article de blog pour plus de détails.

Structuration du projet

Une fois que vous avez récupéré le zip dans la section "Téléchargements" de cet article, allez-y, décompressez l'archive et naviguez dans le répertoire.

De là, vous pouvez utiliser le

arbre
commande pour que la structure du répertoire soit imprimée dans votre terminal :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
$ arbre --dirsfirst
.
├── jeu de données
│ ├── adrien [ 6 images]
│ ├── trisha [ 6 images]
│ └── inconnu [ 6 images]
├── images
│ ├── adrien.jpg
│ ├── patrick_bateman.jpg
│ └── trisha_adrian.jpg
├── face_detection_model
│ ├── déployer.prototxt
│ └── res10_300x300_ssd_iter_140000.caffemodel
├── sortie
│ ├── enrobages.pickle
│ ├── le .pickle
│ └── Reconnaître.pickle
├── extract_embeddings.py
├── openface_nn4.small2.v1.t7
├── train_model.py
├── reconnaître.py
└──reconnaître_vidéo.py
7 répertoires, 31 fichiers

Il y a pas mal de parties mobiles pour ce projet — prenez le temps maintenant de lire attentivement cette section afin de vous familiariser avec tous les fichiers du projet d'aujourd'hui.

Notre projet a quatre répertoires dans le dossier racine :

  • base de données/
    : Contient nos images de visage organisées en sous-dossiers par nom.
  • images/
    : Contient trois images de test que nous utiliserons pour vérifier le fonctionnement de notre modèle.
  • face_detection_model/
    : Contient un modèle d'apprentissage en profondeur Caffe pré-formé fourni par OpenCV pour détecter les visages. Ce modèle détecte et localise les visages dans une image.
  • production/
    : Contient mes fichiers pickle de sortie. Si vous travaillez avec votre propre jeu de données, vous pouvez également y stocker vos fichiers de sortie. Les fichiers de sortie incluent :
    • encastrements.pickle
      : Un fichier sérialisé d'incrustations faciales. Les plongements ont été calculés pour chaque face du jeu de données et sont stockés dans ce fichier.
    • le.pickle
      : Notre encodeur d'étiquettes. Contient les étiquettes de nom des personnes que notre modèle peut reconnaître.
    • Reconnaître.pickle
      : Notre modèle de Machine à Vecteur de Support Linéaire (SVM). Il s'agit d'un modèle d'apprentissage automatique plutôt que d'un modèle d'apprentissage en profondeur et il est responsable de la reconnaissance réelle des visages.

Résumons les cinq fichiers du répertoire racine :

  • extract_embeddings.py
     : Nous examinerons ce fichier à l' étape 1 , qui est responsable de l'utilisation d'un extracteur de fonctionnalités d'apprentissage en profondeur pour générer un vecteur 128-D décrivant un visage. Tous les visages de notre ensemble de données passeront par le réseau de neurones pour générer des incorporations.
  • openface_nn4.small2.v1.t7
    : Un modèle d'apprentissage en profondeur Torch qui produit les incorporations faciales 128-D. Nous utiliserons ce modèle d'apprentissage en profondeur dans les étapes 1, 2 et 3 , ainsi que dans la section Bonus .
  • train_model.py
     : Notre modèle SVM linéaire sera entraîné par ce script à l' étape 2 . Nous allons détecter les visages, extraire les intégrations et ajuster notre modèle SVM aux données d'intégration.
  • reconnaître.py
    : À l'étape 3 , nous reconnaîtrons les visages dans les images. Nous allons détecter les visages, extraire les représentations incorporées et interroger notre modèle SVM pour déterminer qui se trouve dans une image. Nous allons dessiner des cadres autour des visages et annoter chaque cadre avec un nom.
  • Reconnaître_vidéo.py
     : Notre section Bonus décrit comment reconnaître qui se trouve dans les images d'un flux vidéo, tout comme nous l'avons fait à l' étape 3 sur les images statiques.

Passons à la première étape !

Étape 1 : Extraire les représentations vectorielles continues de l'ensemble de données de visage

Maintenant que nous comprenons le fonctionnement de la reconnaissance faciale et que nous avons examiné la structure de notre projet, commençons à créer notre pipeline de reconnaissance faciale OpenCV.

Ouvrez le

extract_embeddings.py
 fichier et insérez le code suivant :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# importer les packages nécessaires
à partir des chemins d' importation imutils
importer numpy en tant que np
importer l'analyse d' arguments
importer des imutils
importer des cornichons
importer cv2
importer le système d' exploitation
# construire l'analyseur d'arguments et analyser les arguments
ap = analyse d'arguments. Analyseur d'argument ()
ap. add_argument ( "-i" , "--dataset" , requis= Vrai ,
help= "chemin vers le répertoire d'entrée des visages + images" )
ap. add_argument ( "-e" , "--embeddings" , requis= Vrai ,
help= "chemin vers la sortie de la base de données sérialisée des intégrations faciales" )
ap. add_argument ( "-d" , "--detector" , requis= Vrai ,
help= "chemin vers le détecteur de visage d'apprentissage en profondeur d'OpenCV" )
ap. add_argument ( "-m" , "--embedding-model" , requis= Vrai ,
help= "chemin vers le modèle d'intégration de visage d'apprentissage en profondeur d'OpenCV" )
ap. add_argument ( "-c" , "--confidence" , type=float, default= 0.5 ,
help= "probabilité minimale pour filtrer les détections faibles" )
args = vars ( ap. parse_args ())

Nous importons nos packages requis sur les lignes 2-8 . Vous aurez besoin d'OpenCV et

imutils
 installée. Pour installer OpenCV, suivez simplement l'un de mes guides (je recommande OpenCV 3.4.2, alors assurez-vous de télécharger la bonne version pendant que vous suivez). Mon package imutils peut être installé avec pip :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
$ pip install --upgrade imutils

Ensuite, nous traitons nos arguments de ligne de commande :

  • --base de données
    : Le chemin d'accès à notre ensemble de données d'entrée d'images de visage.
  • --encastrements
    : Le chemin d'accès à notre fichier d'incorporations de sortie. Notre script calculera les incorporations de visages que nous sérialiserons sur le disque.
  • --détecteur
    : Chemin vers le détecteur de visage d'apprentissage en profondeur basé sur Caffe d'OpenCV utilisé pour localiser réellement les visages dans les images.
  • --embedding-model
    : Chemin d'accès au modèle d'intégration OpenCV Deep Learning Torch. Ce modèle nous permettra d' extraire un vecteur d'incorporation faciale 128-D.
  • --confiance
    : Seuil facultatif pour filtrer les détections de visages de la semaine.

Maintenant que nous avons importé nos packages et analysé les arguments de la ligne de commande, chargeons le détecteur de visage et l'intégrateur depuis le disque :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# charger notre détecteur de visage sérialisé à partir du disque
print ( "[INFO] chargement du détecteur de visage..." )
protoPath = os.path.sep. join ([ args [ "detector" ] , "deploy.prototxt" ])
modelPath = os.path.sep. joindre ([ args [ "détecteur" ] ,
"res10_300x300_ssd_iter_140000.caffemodel" ])
détecteur = cv2.dnn. readNetFromCaffe ( protoPath, modelPath )
# charger notre modèle d'intégration de visage sérialisé à partir du disque
print ( "[INFO] chargement de la reconnaissance faciale..." )
intégrateur = cv2.dnn. readNetFromTorch ( args [ "embedding_model" ])

Ici, nous chargeons le détecteur de visage et l'intégrateur :

  • détecteur
    : Chargé via les lignes 26-29 . Nous utilisons un détecteur de visage DL basé sur Caffe pour localiser les visages dans une image.
  • enrober
    : Chargé sur la ligne 33 . Ce modèle est basé sur Torch et est responsable de l' extraction des intégrations faciales via l'extraction de fonctionnalités d'apprentissage en profondeur.

Notez que nous utilisons le respectif

cv2.dnn
 fonctions pour charger les deux modèles séparés. La
dnn
 Le module n'a pas été rendu disponible comme ça avant OpenCV 3.3 , mais je vous recommande d' utiliser OpenCV 3.4.2 ou supérieur pour ce billet de blog.

À l'avenir, récupérons nos chemins d'image et effectuons des initialisations :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# saisir les chemins vers les images d'entrée dans notre jeu de données
print ( "[INFO] quantification des visages..." )
imagePaths = list ( chemins. list_images ( args [ "dataset" ]))
# initialiser nos listes d'incrustations faciales extraites et
# noms de personnes correspondants
Embeddings connus = []
noms connus = []
# initialise le nombre total de visages traités
somme = 0

La

ImagePaths
 list , construite sur la ligne 37 , contient le chemin d'accès à chaque image du jeu de données. J'ai rendu cela facile via mon
imutils
 fonction,
chemins.list_images
.

Nos imbrications et noms correspondants seront tenus dans deux listes :

Embeddingsconnus
 et
Nomsconnus
 ( Lignes 41 et 42 ).

Nous garderons également une trace du nombre de visages que nous avons traités via une variable appelée

total
 ( Ligne 45 ).

Commençons à boucler sur les chemins d'image - cette boucle sera responsable de l'extraction des incorporations des visages trouvés dans chaque image :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# boucle sur les chemins de l'image
for ( i, imagePath ) in enumerate ( imagePaths ) :
# extraire le nom de la personne du chemin de l'image
print ( "[INFO] image de traitement {}/{}" . format ( i + 1 ,
len ( chemin d'image )))
nom = imagePath. diviser ( os.path.sep )[ -2 ]
# charger l'image, la redimensionner pour avoir une largeur de 600 pixels (tout en
# en maintenant le rapport d'aspect), puis saisissez l'image
# dimension
image=cv2. imread ( chemin de l'image )
image = imutils. redimensionner ( image, largeur = 600 )
( h, w ) = image.forme [ : 2 ]

Nous commençons à boucler

ImagePaths
 sur la ligne 48 .

Dans un premier temps, nous extrayons le

Nom
 de la personne du chemin ( Ligne 52 ). Pour expliquer comment cela fonctionne, considérons l'exemple suivant dans mon shell Python :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
$ python
>>> à partir des chemins d'importation imutils
>>> importer le système d'exploitation
>>> imagePaths = list(paths.list_images( "dataset" ))
>>> imagePath = imagePaths[ 0 ]
>>> chemin de l'image
'ensemble de données/adrien/00004.jpg'
>>> imagePath.split(os.path.sep)
['ensemble de données', 'adrien', '00004.jpg']
>>> imagePath.split(os.path.sep)[ -2 ]
'adrien'
>>>

Remarquez comment en utilisant

imagePath.split
 et en fournissant le caractère fractionné (le séparateur de chemin du système d'exploitation - "/" sous Unix et "\" sous Windows), la fonction produit une liste de noms de dossiers/fichiers (chaînes) qui parcourent l'arborescence des répertoires. On saisit l'avant-dernier index, les personnes
Nom
, qui dans ce cas est
'adrien'
.

Enfin, nous terminons le bloc de code ci-dessus en chargeant le

image
 et
redimensionner
 à un connu
largeur
 ( Lignes 57 et 58 ).

Détectons et localisons les visages :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# construire un blob à partir de l'image
imageBlob = cv2.dnn. blobFromImage (
cv2. redimensionner ( image, ( 300 , 300 )) , 1.0 , ( 300 , 300 ) ,
( 104.0 , 177.0 , 123.0 ) , swapRB= Faux , recadrage= Faux )
# appliquer le détecteur de visage basé sur l'apprentissage en profondeur d'OpenCV pour localiser
# visages dans l'image d'entrée
détecteur. setInput ( imageBlob )
détections = détecteur. avant ()

Aux lignes 62-64 , nous construisons un blob. Pour en savoir plus sur ce processus, veuillez lire Deep learning: How OpenCV's blobFromImage works .

De là, nous détectons les visages dans l'image en passant le

imageBlob
 à travers le
détecteur
 réseau ( Lignes 68 et 69 ).

Traitons le

détections
:

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# s'assurer qu'au moins un visage a été trouvé
si len ( détections ) > 0 :
# nous partons du principe que chaque image n'en a qu'UNE
# face, donc trouvez la boîte englobante avec la plus grande probabilité
je = np. argmax ( détections [ 0 , 0 , :, 2 ])
confiance = détections [ 0 , 0 , i, 2 ]
# s'assurer que la détection avec la plus grande probabilité
# signifie notre test de probabilité minimum (aidant ainsi à filtrer
# détections faibles)
if confiance > args [ "confiance" ] :
# calcule les coordonnées (x, y) de la boîte englobante pour
# la face
case = détections [ 0 , 0 , i, 3 : 7 ] * np. tableau ([ l, h, l, h ])
( débutX, débutY, finX, finY ) = boîte. astype ( "entier" )
# extraire le ROI du visage et saisir les dimensions du ROI
visage = image [ débutY:finY, débutX:finX ]
( fH, fW ) = visage.forme [ : 2 ]
# assurez-vous que la largeur et la hauteur du visage sont suffisamment grandes
si fW < 20 ou fH < 20 :
Continuez

La

détections
 list contient des probabilités et des coordonnées pour localiser les visages dans une image.

En supposant que nous ayons au moins une détection, nous allons passer au corps de l'instruction if ( Ligne 72 ).

Nous faisons l'hypothèse qu'il n'y a qu'un seul visage dans l'image, nous extrayons donc la détection avec le plus haut

confiance
 et vérifiez que la confiance respecte le seuil de probabilité minimum utilisé pour filtrer les détections faibles ( Lignes 75-81 ).

En supposant que nous avons atteint ce seuil, nous extrayons le

Visage
 Retour sur investissement et saisie/vérification des dimensions pour s'assurer que
Visage
 Le retour sur investissement est suffisamment important ( lignes 84-93 ).

À partir de là, nous profiterons de notre

enrober
 CNN et extrayez les incrustations de visage :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# construire un blob pour le retour sur investissement du visage, puis passer le blob
# à travers notre modèle d'incorporation de visage pour obtenir le 128-d
# quantification du visage
faceBlob = cv2.dnn. blobFromImage ( visage, 1.0 / 255 ,
( 96 , 96 ) , ( 0 , 0 , 0 ) , swapRB= Vrai , recadrage= Faux )
encastrer. setInput ( faceBlob )
vec = enrobage. avant ()
# ajouter le nom de la personne + le visage correspondant
# intégration à leurs listes respectives
noms connus. ajouter ( nom )
Embeddings connus. ajouter ( vec. aplatir ())
somme += 1

Nous construisons un autre blob, cette fois à partir du ROI du visage (pas de l'image entière comme nous l'avons fait auparavant) sur les lignes 98 et 99 .

Par la suite, nous passons le

faceBlob
 via l'embedder CNN ( Lignes 100 et 101 ). Cela génère un vecteur 128-D (
vec
) qui décrit le visage. Nous tirerons parti de ces données pour reconnaître de nouveaux visages via l'apprentissage automatique.

Et puis nous ajoutons simplement le

Nom
 et incorporation
vec
 à
Nomsconnus
 et
Embeddingsconnus
, respectivement ( lignes 105 et 106 ).

Nous ne pouvons pas non plus oublier la variable que nous avons définie pour suivre le

total
 nombre de faces non plus - nous allons de l'avant et incrémentons la valeur sur la ligne 107 .

Nous poursuivons ce processus de boucle sur les images, de détection des visages et d'extraction des incorporations de visage pour chaque image de notre ensemble de données.

À la fin de la boucle, il ne reste plus qu'à vider les données sur le disque :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# vider les incorporations faciales + les noms sur le disque
print ( "[INFO] sérialisation {} encodages..." . format ( total ))
data = { "embeddings" : embeddings connus, "names" : noms connus }
f = ouvert ( args [ "embeddings" ] , "wb" )
F. écrire ( pickle. dumps ( données ))
F. fermer ()

Nous ajoutons le nom et les données d'intégration à un dictionnaire, puis sérialisons le

Les données
 dans un fichier cornichon aux lignes 110-114 .

À ce stade, nous sommes prêts à extraire les représentations incorporées en exécutant notre script.

Pour suivre ce didacticiel de reconnaissance faciale, utilisez la section "Téléchargements" du message pour télécharger le code source, les modèles OpenCV et un exemple d'ensemble de données de reconnaissance faciale.

À partir de là, ouvrez un terminal et exécutez la commande suivante pour calculer les incorporations de visage avec OpenCV :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
$ python extract_embeddings.py --dataset jeu de données \
--embeddings sortie/embeddings.pickle \
--detector face_detection_model \
--embedding-model openface_nn4.small2.v1.t7
[INFO] chargement du détecteur de visage...
[INFO] chargement de la reconnaissance faciale...
[INFO] quantification des visages...
[INFO] traitement image 1 / 18
[INFO] traitement de l'image 2 / 18
[INFO] traitement de l'image 3 / 18
[INFO] traitement de l'image 4 / 18
[INFO] traitement d'image 5 / 18
[INFO] traitement de l'image 6 / 18
[INFO] traitement d'image 7 / 18
[INFO] traitement d'image 8 / 18
[INFO] traitement de l'image 9 / 18
[INFO] traitement d'image 10 / 18
[INFO] traitement d'image 11 / 18
[INFO] traitement de l'image 12 / 18
[INFO] traitement d'image 13 / 18
[INFO] traitement image 14 / 18
[INFO] traitement de l'image 15 / 18
[INFO] traitement image 16 / 18
[INFO] traitement image 17 / 18
[INFO] traitement image 18 / 18
[INFO] sérialisation de 18 encodages...

Ici, vous pouvez voir que nous avons extrait 18 incorporations de visage, une pour chacune des images (6 par classe) dans notre ensemble de données de visage d'entrée.

Étape 2 : Entraînez le modèle de reconnaissance faciale

À ce stade, nous avons extrait des intégrations 128-d pour chaque visage - mais comment reconnaissons-nous réellement une personne sur la base de ces intégrations ? La réponse est que nous devons former un modèle d'apprentissage automatique "standard" (tel qu'un SVM, un classificateur k-NN, une forêt aléatoire, etc.) en plus des incorporations.

Dans mon précédent didacticiel sur la reconnaissance faciale, nous avons découvert comment une version modifiée de k-NN peut être utilisée pour la reconnaissance faciale sur des intégrations 128-d créées via les bibliothèques dlib et face_recognition .

Aujourd'hui, je souhaite partager comment nous pouvons créer un classificateur plus puissant en plus des incorporations - vous pourrez également utiliser cette même méthode dans vos pipelines de reconnaissance faciale basés sur dlib si vous le souhaitez.

Ouvrez le

train_model.py
 fichier et insérez le code suivant :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# importer les packages nécessaires
de sklearn.preprocessing importer LabelEncoder
depuis sklearn.svm importer SVC
importer l'analyse d' arguments
importer des cornichons
# construire l'analyseur d'arguments et analyser les arguments
ap = analyse d'arguments. Analyseur d'argument ()
ap. add_argument ( "-e" , "--embeddings" , requis= Vrai ,
help= "chemin vers la base de données sérialisée des intégrations faciales" )
ap. add_argument ( "-r" , "--recognizer" , requis= Vrai ,
help= "chemin vers le modèle de sortie formé pour reconnaître les visages" )
ap. add_argument ( "-l" , "--le" , requis= Vrai ,
help= "chemin vers l'encodeur d'étiquette de sortie" )
args = vars ( ap. parse_args ())

Nous aurons besoin de scikit-learn , une bibliothèque d'apprentissage automatique, installée dans notre environnement avant d'exécuter ce script. Vous pouvez l'installer via pip :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
$ pip install scikit-learn

Nous importons nos packages et modules sur les lignes 2-5 . Nous utiliserons l'implémentation de scikit-learn de Support Vector Machines (SVM), un modèle d'apprentissage automatique courant.

À partir de là, nous analysons nos arguments de ligne de commande :

  • --encastrements
    : Le chemin vers les représentations vectorielles continues sérialisées (nous l'avons exporté en exécutant le précédent
    extract_embeddings.py
     scénario).
  • --recognizer
    : Ce sera notre modèle de sortie qui reconnaît les visages. Il est basé sur SVM. Nous allons l'enregistrer afin de pouvoir l'utiliser dans les deux prochains scripts de reconnaissance.
  • --le
    : chemin du fichier de sortie de notre encodeur d'étiquettes. Nous sérialiserons notre encodeur d'étiquettes sur disque afin de pouvoir l'utiliser ainsi que le modèle de reconnaissance dans nos scripts de reconnaissance faciale image/vidéo.

Chacun de ces arguments est obligatoire .

Chargeons nos incorporations faciales et encodons nos étiquettes :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# charger les incrustations de visage
print ( "[INFO] chargement des incrustations de visage..." )
données = cornichon. charges ( open ( args [ "embeddings" ] , "rb" ) . read ())
# encoder les étiquettes
print ( "[INFO] étiquettes d'encodage..." )
le = LabelEncoder ()
étiquettes = le. fit_transform ( données [ "noms" ])

Ici, nous chargeons nos incorporations de l' étape 1 sur la ligne 19 . Nous ne générerons aucune représentation vectorielle continue dans ce script de formation de modèle ; nous utiliserons les représentations vectorielles continues précédemment générées et sérialisées.

Ensuite, nous initialisons notre scikit-learn

LabelEncoder
 et encoder notre nom
Étiquettes
 ( Lignes 23 et 24 ).

Il est maintenant temps d'entraîner notre modèle SVM pour la reconnaissance des visages :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# former le modèle utilisé pour accepter les plongements 128-d du visage et
# puis produire la reconnaissance faciale réelle
print ( "[INFO] modèle d'entraînement..." )
reconnaisseur = SVC ( C= 1.0 , noyau= "linéaire" , probabilité= Vrai )
reconnaisseur. fit ( données [ "incorporations" ] , étiquettes )

Sur la ligne 29, nous initialisons notre modèle SVM, et sur la ligne 30, nous

adapter
 le modèle (également connu sous le nom de « formation du modèle »).

Ici, nous utilisons une machine à vecteurs de support linéaire (SVM), mais vous pouvez essayer d'expérimenter d'autres modèles d'apprentissage automatique si vous le souhaitez.

Après avoir entraîné le modèle, nous produisons le modèle et l'encodeur d'étiquettes sur le disque sous forme de fichiers pickle.

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# écrire le modèle de reconnaissance faciale réel sur le disque
f = ouvert ( args [ "recognizer" ] , "wb" )
F. écrire ( pickle. dumps ( reconnaissance ))
F. fermer ()
# écrire l'encodeur d'étiquette sur le disque
f = ouvrir ( args [ "le" ] , "wb" )
F. écrire ( pickle. dumps ( le ))
F. fermer ()

Nous écrivons deux fichiers pickle sur le disque dans ce bloc — le modèle de reconnaissance faciale et l' encodeur d'étiquettes .

À ce stade, assurez-vous d'avoir exécuté le code de l' étape 1 en premier. Vous pouvez récupérer le zip contenant le code et les données dans la section "Téléchargements" .

Maintenant que nous avons fini de coder

train_model.py
 appliquons-le également à nos incorporations de visage extraites :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
$ python train_model.py --embeddings output/embeddings.pickle \
--recognizer output/recognizer.pickle \
-- le output/ le .pickle
[INFO] chargement des incorporations de visage...
[INFO] étiquettes d'encodage...
[INFO] modèle de formation...
$ ls sortie/
embeddings.pickle le .pickle identifier.pickle

Ici, vous pouvez voir que notre SVM a été formé sur les intégrations et que (1) le SVM lui-même et (2) le codage d'étiquette ont été écrits sur le disque, ce qui nous permet de les appliquer aux images et vidéos d'entrée.

Étape 3 : Reconnaître les visages avec OpenCV

Nous sommes maintenant prêts à effectuer la reconnaissance faciale avec OpenCV !

Nous commencerons par reconnaître les visages dans les images dans cette section, puis passerons à la reconnaissance des visages dans les flux vidéo dans la section suivante.

Ouvrez le

reconnaître.py
 fichier dans votre projet et insérez le code suivant :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# importer les packages nécessaires
importer numpy en tant que np
importer l'analyse d' arguments
importer des imutils
importer des cornichons
importer cv2
importer le système d' exploitation
# construire l'analyseur d'arguments et analyser les arguments
ap = analyse d'arguments. Analyseur d'argument ()
ap. add_argument ( "-i" , "--image" , requis= Vrai ,
help= "chemin vers l'image d'entrée" )
ap. add_argument ( "-d" , "--detector" , requis= Vrai ,
help= "chemin vers le détecteur de visage d'apprentissage en profondeur d'OpenCV" )
ap. add_argument ( "-m" , "--embedding-model" , requis= Vrai ,
help= "chemin vers le modèle d'intégration de visage d'apprentissage en profondeur d'OpenCV" )
ap. add_argument ( "-r" , "--recognizer" , requis= Vrai ,
help= "chemin vers le modèle formé pour reconnaître les visages" )
ap. add_argument ( "-l" , "--le" , requis= Vrai ,
help= "chemin vers l'encodeur d'étiquettes" )
ap. add_argument ( "-c" , "--confidence" , type=float, default= 0.5 ,
help= "probabilité minimale pour filtrer les détections faibles" )
args = vars ( ap. parse_args ())

Nous

importer
 nos forfaits requis sur les lignes 2 à 7 . À ce stade, chacun de ces packages doit être installé.

Nos six arguments de ligne de commande sont analysés sur les lignes 10-23 :

  • --image
    : chemin d'accès à l'image d'entrée. Nous allons essayer de reconnaître les visages sur cette image.
  • --détecteur
    : Le chemin vers le détecteur de visage d'apprentissage en profondeur d'OpenCV. Nous utiliserons ce modèle pour détecter où se trouvent les ROI du visage dans l'image.
  • --embedding-model
    : Le chemin vers le modèle d'intégration de visage d'apprentissage en profondeur d'OpenCV. Nous utiliserons ce modèle pour extraire l'intégration du visage 128-D de la ROI du visage - nous transmettrons les données au module de reconnaissance.
  • --recognizer
    : Le chemin vers notre modèle de reconnaissance. Nous avons formé notre module de reconnaissance SVM à l' étape 2 . C'est ce qui déterminera réellement qui est un visage.
  • --le
    : Le chemin vers notre encodeur d'étiquettes. Celui-ci contient nos étiquettes faciales telles que
    'adrien'
     ou
    'tricha'
    .
  • --confiance
    : Le seuil facultatif pour filtrer les détections de visage faibles .

Assurez-vous d'étudier ces arguments de ligne de commande - il est important de connaître la différence entre les deux modèles d'apprentissage en profondeur et le modèle SVM. Si vous vous trouvez confus plus tard dans ce script, vous devriez vous référer ici.

Maintenant que nous avons géré nos importations et nos arguments de ligne de commande, chargeons les trois modèles du disque en mémoire :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# charger notre détecteur de visage sérialisé à partir du disque
print ( "[INFO] chargement du détecteur de visage..." )
protoPath = os.path.sep. join ([ args [ "detector" ] , "deploy.prototxt" ])
modelPath = os.path.sep. joindre ([ args [ "détecteur" ] ,
"res10_300x300_ssd_iter_140000.caffemodel" ])
détecteur = cv2.dnn. readNetFromCaffe ( protoPath, modelPath )
# charger notre modèle d'intégration de visage sérialisé à partir du disque
print ( "[INFO] chargement de la reconnaissance faciale..." )
intégrateur = cv2.dnn. readNetFromTorch ( args [ "embedding_model" ])
# charger le modèle de reconnaissance faciale réel avec l'encodeur d'étiquettes
reconnaisseur = cornichon. charges ( open ( args [ "recognizer" ] , "rb" ) . read ())
le = cornichon. charges ( open ( args [ "le" ] , "rb" ) . read ())

Nous chargeons trois modèles dans ce bloc. Au risque d'être redondant, je tiens à rappeler explicitement les différences entre les modèles :

  1. détecteur
    : Un modèle Caffe DL pré-formé pour détecter où se trouvent les visages dans l'image ( Lignes 27-30 ).
  2. enrober
    : Un modèle Torch DL pré-entraîné pour calculer nos plongements de visage 128-D ( Ligne 34 ).
  3. reconnaisseur
    : Notre modèle de reconnaissance faciale linéaire SVM ( Line 37 ). Nous avons formé ce modèle à l' étape 2 .

Les deux 1 et 2 sont pré-formés , ce qui signifie qu'ils vous sont fournis tels quels par OpenCV. Ils sont enterrés dans le projet OpenCV sur GitHub, mais je les ai inclus pour votre commodité dans la section "Téléchargements" de l'article d'aujourd'hui. J'ai également numéroté les modèles dans l'ordre dans lequel nous les appliquerons pour reconnaître les visages avec OpenCV.

Nous chargeons également notre encodeur d'étiquettes qui contient les noms des personnes que notre modèle peut reconnaître ( Ligne 38 ).

Maintenant, chargeons notre image et détectons les visages :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# charger l'image, la redimensionner pour avoir une largeur de 600 pixels (tout en
# en maintenant le rapport d'aspect), puis saisissez les dimensions de l'image
image=cv2. imread ( args [ "image" ])
image = imutils. redimensionner ( image, largeur = 600 )
( h, w ) = image.forme [ : 2 ]
# construire un blob à partir de l'image
imageBlob = cv2.dnn. blobFromImage (
cv2. redimensionner ( image, ( 300 , 300 )) , 1.0 , ( 300 , 300 ) ,
( 104.0 , 177.0 , 123.0 ) , swapRB= Faux , recadrage= Faux )
# appliquer le détecteur de visage basé sur l'apprentissage en profondeur d'OpenCV pour localiser
# visages dans l'image d'entrée
détecteur. setInput ( imageBlob )
détections = détecteur. avant ()

Ici, nous :

  • Chargez l'image en mémoire et construisez un blob ( Lignes 42-49 ). En savoir plus
    cv2.dnn.blobFromImage
     ici .
  • Localisez les visages dans l'image via notre
    détecteur
     ( Lignes 53 et 54 ).

Compte tenu de notre nouveau

détections
, reconnaissons les visages dans l'image. Mais nous devons d'abord filtrer les faibles
détections
 et extraire le
Visage
 RSI :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# boucle sur les détections
for i in range ( 0 , detections.shape [ 2 ]) :
# extraire la confiance (c'est-à-dire la probabilité) associée à la
# prédiction
confiance = détections [ 0 , 0 , i, 2 ]
# filtrer les détections faibles
if confiance > args [ "confiance" ] :
# calcule les coordonnées (x, y) de la boîte englobante pour le
# Visage
case = détections [ 0 , 0 , i, 3 : 7 ] * np. tableau ([ l, h, l, h ])
( débutX, débutY, finX, finY ) = boîte. astype ( "entier" )
# extraire le ROI du visage
visage = image [ débutY:finY, débutX:finX ]
( fH, fW ) = visage.forme [ : 2 ]
# assurez-vous que la largeur et la hauteur du visage sont suffisamment grandes
si fW < 20 ou fH < 20 :
Continuez

Vous reconnaîtrez ce bloc à partir de l' étape 1 . Je vais l'expliquer ici une fois de plus:

  • On boucle sur le
    détections
     sur la ligne 57 et extrayez le
    confiance
     de chacun sur la ligne 60 .
  • Puis on compare le
    confiance
     au seuil minimum de détection de probabilité contenu dans notre ligne de commande
    arguments
     dictionnaire, en veillant à ce que la probabilité calculée soit supérieure à la probabilité minimale ( Ligne 63 ).
  • De là, on extrait le
    Visage
     ROI ( Lignes 66-70 ) et assurez-vous que ses dimensions spatiales sont suffisamment grandes ( Lignes 74 et 75 ).

Reconnaissant le nom du

Visage
 Le retour sur investissement ne nécessite que quelques étapes :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# construire un blob pour le retour sur investissement du visage, puis passer le blob
# à travers notre modèle d'incorporation de visage pour obtenir le 128-d
# quantification du visage
faceBlob = cv2.dnn. blobFromImage ( visage, 1.0 / 255 , ( 96 , 96 ) ,
( 0 , 0 , 0 ) , swapRB= Vrai , recadrage= Faux )
encastrer. setInput ( faceBlob )
vec = enrobage. avant ()
# effectuer une classification pour reconnaître le visage
preds = reconnaissance. prédire_proba ( vec )[ 0 ]
j = np. argmax ( preds )
probabilité = preds [ j ]
nom = le.classes_ [ j ]

Dans un premier temps, nous construisons un

faceBlob
 (du
Visage
 ROI) et le faire passer par le
enrober
 pour générer un vecteur 128-D qui décrit le visage ( Lignes 80-83 )

Ensuite, nous passons le

vec
 grâce à notre modèle de reconnaissance SVM ( Ligne 86 ), dont le résultat est nos prédictions pour qui est dans le ROI du visage.

Nous prenons l'indice de probabilité le plus élevé ( Ligne 87 ) et interrogeons notre encodeur d'étiquettes pour trouver le

Nom
 ( Ligne 89 ). Entre les deux, j'extrait la probabilité sur la ligne 88 .

Remarque : vous pouvez filtrer davantage les reconnaissances faciales faibles en appliquant un test de seuil supplémentaire sur la probabilité. Par exemple, en insérant

si probabilité < T
 (où
J
 est une variable que vous définissez) peut fournir une couche supplémentaire de filtrage pour s'assurer qu'il y a moins de reconnaissances faciales faussement positives.

Maintenant, affichons les résultats de la reconnaissance faciale OpenCV :

Reconnaissance faciale OpenCV
# dessine la boîte englobante de la face avec l'associé
# probabilité
text = "{} : {:.2f}%" . format ( nom, proba * 100 )
y = débutY - 10 si débutY - 10 > 10 sinon débutY + 10
cv2. rectangle ( image, ( débutX, débutY ) , ( finX, finY ) ,
( 0 , 0 , 255 ) , 2 )
cv2. putText ( image, texte, ( startX, y ) ,
cv2.FONT_HERSHEY_SIMPLEX, 0.45 , ( 0 , 0 , 255 ) , 2 )
# afficher l'image de sortie
cv2. imshow ( "Image" , image )
cv2. waitKey ( 0 )

Pour chaque visage que nous reconnaissons dans la boucle (y compris les personnes "inconnues") :

  • Nous construisons un
    texte
     chaîne contenant le
    Nom
     et probabilité sur la ligne 93 .
  • Et puis nous dessinons un rectangle autour du visage et plaçons le texte au-dessus de la boîte ( Lignes 94-98 ).

Et puis enfin on visualise les résultats à l'écran jusqu'à ce qu'une touche soit enfoncée ( Lignes 101 et 102 ).

Il est temps de reconnaître les visages dans les images avec OpenCV !

Pour appliquer notre pipeline de reconnaissance faciale OpenCV à mes images fournies (ou à votre propre ensemble de données + images de test), assurez-vous d'utiliser la section "Téléchargements" du billet de blog pour télécharger le code, les modèles formés et les exemples d'images.

De là, ouvrez un terminal et exécutez la commande suivante :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
$ python reconnaît.py --detector face_detection_model \
--embedding-model openface_nn4.small2.v1.t7 \
--recognizer output/recognizer.pickle \
-- le résultat/ le .pickle \
--image images/adrien.jpg
[INFO] chargement du détecteur de visage...
[INFO] chargement de la reconnaissance faciale...
Figure 4 : La reconnaissance faciale OpenCV m'a reconnu lors de la projection du film Jurassic World : Fallen Kingdom .

Ici, vous pouvez me voir en train de siroter une bière et de porter l'un de mes t-shirts préférés de Jurassic Park , ainsi qu'un verre à pinte spécial Jurassic World et un livre commémoratif. Ma prédiction de visage n'a qu'une confiance de 47,15 % ; cependant, cette confiance est plus élevée que la classe « Inconnu » .

Essayons un autre exemple de reconnaissance faciale OpenCV :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
$ python reconnaît.py --detector face_detection_model \
--embedding-model openface_nn4.small2.v1.t7 \
--recognizer output/recognizer.pickle \
-- le résultat/ le .pickle \
--image images/trisha_adrian.jpg
[INFO] chargement du détecteur de visage...
[INFO] chargement de la reconnaissance faciale...
Figure 5 : Ma femme, Trisha, et moi sommes reconnus sur une photo de selfie dans un avion avec OpenCV + reconnaissance faciale d'apprentissage en profondeur.

Voici Trisha et moi, prêts à commencer nos vacances !

Dans un dernier exemple, regardons ce qui se passe lorsque notre modèle est incapable de reconnaître le visage réel :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
$ python reconnaît.py --detector face_detection_model \
--embedding-model openface_nn4.small2.v1.t7 \
--recognizer output/recognizer.pickle \
-- le résultat/ le .pickle \
--image images/patrick_bateman.jpg
[INFO] chargement du détecteur de visage...
[INFO] chargement de la reconnaissance faciale...
Figure 6 : La reconnaissance faciale avec OpenCV a déterminé que cette personne est « inconnue ».

La troisième image est un exemple d'une personne "inconnue" qui est en fait Patrick Bateman d' American Psycho - croyez-moi, ce n'est pas une personne que vous voudriez voir apparaître dans vos images ou flux vidéo !

BONUS : Reconnaître les visages dans les flux vidéo

En bonus, j'ai décidé d'inclure une section dédiée à la reconnaissance faciale OpenCV dans les flux vidéo !

Le pipeline lui-même est presque identique à la reconnaissance des visages dans les images, avec seulement quelques mises à jour que nous examinerons en cours de route.

Ouvrez le

Reconnaître_vidéo.py
 fichier et commençons :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# importer les packages nécessaires
depuis imutils.video importer VideoStream
depuis imutils.video importer FPS
importer numpy en tant que np
importer l'analyse d' arguments
importer des imutils
importer des cornichons
temps d'importation
importer cv2
importer le système d' exploitation
# construire l'analyseur d'arguments et analyser les arguments
ap = analyse d'arguments. Analyseur d'argument ()
ap. add_argument ( "-d" , "--detector" , requis= Vrai ,
help= "chemin vers le détecteur de visage d'apprentissage en profondeur d'OpenCV" )
ap. add_argument ( "-m" , "--embedding-model" , requis= Vrai ,
help= "chemin vers le modèle d'intégration de visage d'apprentissage en profondeur d'OpenCV" )
ap. add_argument ( "-r" , "--recognizer" , requis= Vrai ,
help= "chemin vers le modèle formé pour reconnaître les visages" )
ap. add_argument ( "-l" , "--le" , requis= Vrai ,
help= "chemin vers l'encodeur d'étiquettes" )
ap. add_argument ( "-c" , "--confidence" , type=float, default= 0.5 ,
help= "probabilité minimale pour filtrer les détections faibles" )
args = vars ( ap. parse_args ())

Nos importations sont les mêmes que celles de l' étape 3 ci-dessus, à l'exception des lignes 2 et 3 où nous utilisons le

imutils.vidéo
 module. Nous utiliserons
Flux vidéo
 pour capturer des images de notre appareil photo et
FPS
 pour calculer les statistiques d'images par seconde.

Les arguments de la ligne de commande sont également les mêmes, sauf que nous ne transmettons pas de chemin vers une image statique via la ligne de commande. Au lieu de cela, nous allons saisir une référence à notre webcam, puis traiter la vidéo. Reportez-vous à l' étape 3 si vous avez besoin de revoir les arguments.

Nos trois modèles et l'encodeur d'étiquettes sont chargés ici :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# charger notre détecteur de visage sérialisé à partir du disque
print ( "[INFO] chargement du détecteur de visage..." )
protoPath = os.path.sep. join ([ args [ "detector" ] , "deploy.prototxt" ])
modelPath = os.path.sep. joindre ([ args [ "détecteur" ] ,
"res10_300x300_ssd_iter_140000.caffemodel" ])
détecteur = cv2.dnn. readNetFromCaffe ( protoPath, modelPath )
# charger notre modèle d'intégration de visage sérialisé à partir du disque
print ( "[INFO] chargement de la reconnaissance faciale..." )
intégrateur = cv2.dnn. readNetFromTorch ( args [ "embedding_model" ])
# charger le modèle de reconnaissance faciale réel avec l'encodeur d'étiquettes
reconnaisseur = cornichon. charges ( open ( args [ "recognizer" ] , "rb" ) . read ())
le = cornichon. charges ( open ( args [ "le" ] , "rb" ) . read ())

Ici, nous chargeons le visage

détecteur
, Visage
enrober
 modèle, visage
reconnaisseur
 modèle (Linear SVM) et encodeur d'étiquettes.

Encore une fois, assurez-vous de vous référer à l' étape 3 si vous êtes confus au sujet des trois modèles ou de l'encodeur d'étiquettes.

Initialisons notre flux vidéo et commençons à traiter les images :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# initialiser le flux vidéo, puis laisser chauffer le capteur de la caméra
print ( "[INFO] démarrage du flux vidéo..." )
vs = VideoStream ( src= 0 ) . commencer ()
temps. dormir ( 2.0 )
# démarrer l'estimateur de débit FPS
fps = FPS () . commencer ()
# boucle sur les images du flux de fichiers vidéo
tandis que Vrai :
# saisir l'image du flux vidéo fileté
cadre = vs lire ()
# redimensionne le cadre pour avoir une largeur de 600 pixels (tandis que
# en maintenant le rapport d'aspect), puis saisissez l'image
# dimension
frame = imutils. redimensionner ( cadre, largeur = 600 )
( h, w ) = cadre.forme [ : 2 ]
# construire un blob à partir de l'image
imageBlob = cv2.dnn. blobFromImage (
cv2. redimensionner ( cadre, ( 300 , 300 )) , 1.0 , ( 300 , 300 ) ,
( 104.0 , 177.0 , 123.0 ) , swapRB= Faux , recadrage= Faux )
# appliquer le détecteur de visage basé sur l'apprentissage en profondeur d'OpenCV pour localiser
# visages dans l'image d'entrée
détecteur. setInput ( imageBlob )
détections = détecteur. avant ()

Notre

Flux vidéo
 objet est initialisé et démarré à la ligne 43 . Nous attendons que le capteur de la caméra se réchauffe sur la ligne 44 .

Nous initialisons également notre compteur d' images par seconde ( ligne 47 ) et commençons à boucler sur les images de la ligne 50 . Nous attrapons un

Cadre
 de la webcam sur la ligne 52 .

À partir de là, tout est identique à l' étape 3 . Nous

redimensionner
 le cadre ( ligne 57 ) puis nous construisons un blob à partir du cadre + détectons où se trouvent les visages ( lignes 61-68 ).

Traitons maintenant les détections :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# boucle sur les détections
for i in range ( 0 , detections.shape [ 2 ]) :
# extraire la confiance (c'est-à-dire la probabilité) associée à
# la prédiction
confiance = détections [ 0 , 0 , i, 2 ]
# filtrer les détections faibles
if confiance > args [ "confiance" ] :
# calcule les coordonnées (x, y) de la boîte englobante pour
# la face
case = détections [ 0 , 0 , i, 3 : 7 ] * np. tableau ([ l, h, l, h ])
( débutX, débutY, finX, finY ) = boîte. astype ( "entier" )
# extraire le ROI du visage
visage = cadre [ débutY:finY, débutX:finX ]
( fH, fW ) = visage.forme [ : 2 ]
# assurez-vous que la largeur et la hauteur du visage sont suffisamment grandes
si fW < 20 ou fH < 20 :
Continuez

Tout comme dans la section précédente, nous commençons à boucler

détections
 et filtrez les plus faibles ( Lignes 71-77 ). Puis on extrait le
Visage
 ROI et assurez-vous que les dimensions spatiales sont suffisamment grandes pour les prochaines étapes ( Lignes 84-89 ).

Il est maintenant temps d'effectuer la reconnaissance faciale OpenCV :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# construire un blob pour le retour sur investissement du visage, puis passer le blob
# à travers notre modèle d'incorporation de visage pour obtenir le 128-d
# quantification du visage
faceBlob = cv2.dnn. blobFromImage ( visage, 1.0 / 255 ,
( 96 , 96 ) , ( 0 , 0 , 0 ) , swapRB= Vrai , recadrage= Faux )
encastrer. setInput ( faceBlob )
vec = enrobage. avant ()
# effectuer une classification pour reconnaître le visage
preds = reconnaissance. prédire_proba ( vec )[ 0 ]
j = np. argmax ( preds )
probabilité = preds [ j ]
nom = le.classes_ [ j ]
# dessine la boîte englobante du visage avec le
# probabilité associée
text = "{} : {:.2f}%" . format ( nom, proba * 100 )
y = débutY - 10 si débutY - 10 > 10 sinon débutY + 10
cv2. rectangle ( cadre, ( débutX, débutY ) , ( finX, finY ) ,
( 0 , 0 , 255 ) , 2 )
cv2. putText ( cadre, texte, ( startX, y ) ,
cv2.FONT_HERSHEY_SIMPLEX, 0.45 , ( 0 , 0 , 255 ) , 2 )
# mettre à jour le compteur FPS
ips. mettre à jour ()

Ici, nous :

  • Construire le
    faceBlob
     ( Lignes 94 et 95 ) et calculez les incorporations faciales via le deep learning ( Lignes 96 et 97 ).
  • Reconnaître le plus probable
    Nom
     du visage lors du calcul de la probabilité ( Ligne 100-103 ).
  • Dessinez une boîte englobante autour du visage et de la personne
    Nom
     + probabilité ( Lignes 107 -112 ).

Notre

ips
 compteur est mis à jour sur la ligne 115 .

Affichons les résultats et nettoyons :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
# affiche le cadre de sortie
cv2. imshow ( "Cadre" , cadre )
clé = cv2. waitKey ( 1 ) & 0xFF
# si la touche `q` a été enfoncée, sort de la boucle
si clé == ord ( "q" ) :
Pause
# arrêter le chronomètre et afficher les informations FPS
ips. arrêter ()
print ( "[INFO] temps écoulé : {:.2f}" . format ( fps. écoulé ()))
print ( "[INFO] approx. FPS : {:.2f}" . format ( fps. fps ()))
# faire un peu de ménage
cv2. détruiretouteslesfenêtres ()
vs arrêt ()

Pour clôturer le script, nous :

  • Afficher les annotés
    Cadre
     ( Ligne 118 ) et attendez que la touche "q" soit enfoncée à quel point nous sortons de la boucle ( Lignes 119-123 ).
  • Arrêtez notre
    ips
     compteur et imprimer les statistiques dans le terminal ( Lignes 126-128 ).
  • Nettoyage en fermant les fenêtres et en relâchant les pointeurs ( Lignes 131 et 132 ).

Pour exécuter notre pipeline de reconnaissance faciale OpenCV sur un flux vidéo, ouvrez un terminal et exécutez la commande suivante :

 → Lancer Jupyter Notebook sur Google Colab
Reconnaissance faciale OpenCV
$ python reconnaît_vidéo.py --detector face_detection_model \
--embedding-model openface_nn4.small2.v1.t7 \
--recognizer output/recognizer.pickle \
-- le output/ le .pickle
[INFO] chargement du détecteur de visage...
[INFO] chargement de la reconnaissance faciale...
[INFO] démarrage du flux vidéo...
[INFO] temps écoulé : 12. 52
[INFOS] env. FPS : 16. 13

Figure 7 : Reconnaissance faciale en vidéo avec OpenCV.

Comme vous pouvez le voir, Trisha et mon visage sont correctement identifiés ! Notre pipeline de reconnaissance faciale OpenCV obtient également ~ 16 FPS sur mon iMac. Sur mon MacBook Pro, j'obtenais un débit d'environ 14 FPS.

Inconvénients, limites et comment obtenir une plus grande précision de reconnaissance faciale

Figure 8 : Tous les systèmes de reconnaissance faciale sont sujets aux erreurs. Il n'y aura jamais de système de reconnaissance faciale précis à 100 %.

Inévitablement, vous vous retrouverez dans une situation où OpenCV ne reconnaît pas correctement un visage.

Que faites-vous dans ces situations ?

Et comment améliorez-vous la précision de votre reconnaissance faciale OpenCV ? Dans cette section, je détaillerai quelques-unes des méthodes suggérées pour augmenter la précision de votre pipeline de reconnaissance faciale

Vous aurez peut-être besoin de plus de données

Figure 9 : La plupart des gens ne forment pas leurs modèles de reconnaissance faciale OpenCV avec suffisamment de données. 

Ma première suggestion est probablement la plus évidente, mais elle vaut la peine d'être partagée.


Commentaires

Posts les plus consultés de ce blog

Comment fonctionne l'optimise d'Adam

RESEAU DE NEURONE CONVOLUTIF

Comment utiliser les diagrammes PlantUML dans Visual Studio Code pour Windows 10