Table des matières:

Reconnaissance faciale en temps réel : un projet de bout en bout : 8 étapes (avec photos)
Reconnaissance faciale en temps réel : un projet de bout en bout : 8 étapes (avec photos)

Vidéo: Reconnaissance faciale en temps réel : un projet de bout en bout : 8 étapes (avec photos)

Vidéo: Reconnaissance faciale en temps réel : un projet de bout en bout : 8 étapes (avec photos)
Vidéo: Créer un système de RECONNAISSANCE FACIALE ? Opencv et Python 2024, Juillet
Anonim
Reconnaissance faciale en temps réel: un projet de bout en bout
Reconnaissance faciale en temps réel: un projet de bout en bout

Lors de mon dernier tutoriel explorant OpenCV, nous avons appris le SUIVI D'OBJETS DE VISION AUTOMATIQUE. Nous allons maintenant utiliser notre PiCam pour reconnaître les visages en temps réel, comme vous pouvez le voir ci-dessous:

Image
Image

Ce projet a été réalisé avec cette fantastique "Open Source Computer Vision Library", l'OpenCV. Sur ce tutoriel, nous allons nous concentrer sur Raspberry Pi (donc, Raspbian comme OS) et Python, mais j'ai aussi testé le code sur My Mac et ça marche aussi très bien. OpenCV a été conçu pour l'efficacité de calcul et avec un fort accent sur les applications en temps réel. Il est donc parfait pour la reconnaissance faciale en temps réel à l'aide d'un appareil photo.

Pour créer un projet complet sur Face Recognition, nous devons travailler sur 3 phases bien distinctes:

  1. Détection de visage et collecte de données
  2. Former le Reconnaisseur
  3. Reconnaissance de visage

Le schéma fonctionnel ci-dessous résume ces phases:

Image
Image

Étape 1: BoM - Nomenclature

Parties principales:

  1. Framboise Pi V3 - 32,00 $ US
  2. 5 Mégapixels 1080p Capteur OV5647 Mini Module Vidéo Caméra - 13,00 $ US

Étape 2: Installation du package OpenCV 3

Installation du paquet OpenCV 3
Installation du paquet OpenCV 3

J'utilise un Raspberry Pi V3 mis à jour vers la dernière version de Raspbian (Stretch), donc la meilleure façon d'installer OpenCV est de suivre l'excellent tutoriel développé par Adrian Rosebrock: Raspbian Stretch: Installer OpenCV 3 + Python sur votre Raspberry Pi.

J'ai essayé plusieurs guides différents pour installer OpenCV sur mon Pi. Le tutoriel d'Adrian est le meilleur. Je vous conseille de faire de même, en suivant sa directive étape par étape.

Une fois que vous avez terminé le tutoriel d'Adrian, vous devriez avoir un environnement virtuel OpenCV prêt à exécuter nos expériences sur votre Pi.

Allons dans notre environnement virtuel et vérifions qu'OpenCV 3 est correctement installé.

Adrian recommande d'exécuter la commande "source" chaque fois que vous ouvrez un nouveau terminal pour vous assurer que vos variables système ont été correctement configurées.

source ~/.profil

Ensuite, entrons dans notre environnement virtuel:

travailler sur cv

Si vous voyez le texte (cv) précédant votre invite, alors vous êtes dans l'environnement virtuel cv:

(cv) pi@framboise:~$Adrian attire l'attention sur le fait que l'environnement virtuel cv Python est entièrement indépendant et séquestré de la version Python par défaut incluse dans le téléchargement de Raspbian Stretch. Ainsi, les packages Python du répertoire global site-packages ne seront pas disponibles pour l'environnement virtuel cv. De même, tous les packages Python installés dans les packages de site de cv ne seront pas disponibles pour l'installation globale de Python

Maintenant, entrez dans votre interpréteur Python:

python

et confirmez que vous utilisez la version 3.5 (ou supérieure)

Dans l'interpréteur (le ">>>" apparaîtra), importez la bibliothèque OpenCV:

importer cv2

Si aucun message d'erreur n'apparaît, l'OpenCV est correctement installé SUR VOTRE ENVIRONNEMENT VIRTUEL PYTHON.

Vous pouvez également vérifier la version d'OpenCV installée:

cv2._version_

La 3.3.0 devrait apparaître (ou une version supérieure qui pourrait sortir dans le futur). Le Terminal PrintScreen ci-dessus montre les étapes précédentes.

Étape 3: Test de votre appareil photo

Test de votre appareil photo
Test de votre appareil photo

Une fois que vous avez installé OpenCV dans votre RPi, testons pour confirmer que votre appareil photo fonctionne correctement.

Je suppose que vous avez déjà installé une PiCam sur votre Raspberry Pi.

Saisissez le code Python ci-dessous sur votre IDE:

importer numpy en tant que np

import cv2 cap = cv2. VideoCapture(0) cap.set(3, 640) # set Width cap.set(4, 480) # set Height while(True): ret, frame = cap.read() frame = cv2. flip(frame, -1) # Retourner la caméra verticalement gray = cv2.cvtColor(frame, cv2. COLOR_BGR2GRAY) cv2.imshow('frame', frame) cv2.imshow('gray', gray) k = cv2.waitKey(30) & 0xff if k == 27: # appuyez sur 'ESC' pour quitter break cap.release() cv2.destroyAllWindows()

Le code ci-dessus capturera le flux vidéo qui sera généré par votre PiCam, affichant les deux, en couleur BGR et en mode gris.

Notez que j'ai fait pivoter mon appareil photo verticalement en raison de la façon dont il est assemblé. Si ce n'est pas votre cas, commentez ou supprimez la ligne de commande "flip".

Vous pouvez également télécharger le code depuis mon GitHub: simpleCamTest.py

Pour exécuter, entrez la commande:

python simpleCamTest.py

Pour terminer le programme, vous devez appuyer sur la touche [ESC] de votre clavier.

Cliquez avec votre souris sur la fenêtre vidéo, avant d'appuyer sur [ESC]

L'image ci-dessus montre le résultat.

Certains fabricants ont rencontré des problèmes en essayant d'ouvrir l'appareil photo (messages d'erreur "Échec de l'assertion"). Cela pourrait arriver si la caméra n'était pas activée lors de l'installation d'OpenCv et que les pilotes de la caméra ne s'installaient pas correctement. Pour corriger, utilisez la commande:

sudo modprobe bcm2835-v4l2

Vous pouvez également ajouter bcm2835-v4l2 à la dernière ligne du fichier /etc/modules afin que le pilote se charge au démarrage.

Pour en savoir plus sur OpenCV, vous pouvez suivre le tutoriel: loading -video-python-opencv-tutorial

Étape 4: Détection de visage

Détection facial
Détection facial
Détection facial
Détection facial

La tâche la plus élémentaire de la reconnaissance faciale est bien sûr la "détection de visage". Avant toute chose, vous devez "capturer" un visage (Phase 1) afin de le reconnaître, par rapport à un nouveau visage capturé sur le futur (Phase 3).

La façon la plus courante de détecter un visage (ou tout objet) est d'utiliser le "classificateur Haar Cascade"

La détection d'objets à l'aide des classificateurs en cascade Haar est une méthode efficace de détection d'objets proposée par Paul Viola et Michael Jones dans leur article intitulé "Rapid Object Detection using a Boosted Cascade of Simple Features" en 2001. Il s'agit d'une approche basée sur l'apprentissage automatique où un La fonction cascade est entraînée à partir de nombreuses images positives et négatives. Il est ensuite utilisé pour détecter des objets dans d'autres images.

Ici, nous allons travailler avec la détection de visage. Initialement, l'algorithme a besoin de beaucoup d'images positives (images de visages) et négatives (images sans visages) pour entraîner le classificateur. Ensuite, nous devons en extraire des fonctionnalités. La bonne nouvelle est qu'OpenCV est livré avec un entraîneur ainsi qu'un détecteur. Si vous souhaitez former votre propre classificateur pour n'importe quel objet comme une voiture, des avions, etc., vous pouvez utiliser OpenCV pour en créer un. Ses détails complets sont donnés ici: Formation de classificateur en cascade.

Si vous ne souhaitez pas créer votre propre classificateur, OpenCV contient déjà de nombreux classificateurs pré-entraînés pour le visage, les yeux, le sourire, etc. Ces fichiers XML peuvent être téléchargés à partir du répertoire haarcascades.

Assez de théorie, créons un détecteur de visage avec OpenCV !

Téléchargez le fichier: faceDetection.py depuis mon GitHub.

importer numpy en tant que np

import cv2 faceCascade = cv2. CascadeClassifier('Cascades/haarcascade_frontalface_default.xml') cap = cv2. VideoCapture(0) cap.set(3, 640) # set Width cap.set(4, 480) # set Height while True: ret, img = cap.read() img = cv2.flip(img, -1) gray = cv2.cvtColor(img, cv2. COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5, minSize=(20, 20)) pour (x, y, w, h) dans les faces: cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2) roi_gray = gray[y:y+h, x:x+w] roi_color = img[y:y+h, x:x+w] cv2.imshow('video', img) k = cv2.waitKey(30) & 0xff if k == 27: # appuyez sur 'ESC' pour quitter break cap.release() cv2.destroyAllWindows()

Croyez-le ou non, les quelques lignes de code ci-dessus sont tout ce dont vous avez besoin pour détecter un visage, en utilisant Python et OpenCV.

Lorsque vous comparez avec le dernier code utilisé pour tester la caméra, vous vous rendrez compte que peu de pièces y ont été ajoutées. Notez la ligne ci-dessous:

faceCascade = cv2. CascadeClassifier('Cascades/haarcascade_frontalface_default.xml')

C'est la ligne qui charge le "classifier" (qui doit être dans un répertoire nommé "Cascades/", sous le répertoire de votre projet).

Ensuite, nous allons régler notre caméra et à l'intérieur de la boucle, charger notre vidéo d'entrée en mode niveaux de gris (le même que nous avons vu auparavant).

Nous devons maintenant appeler notre fonction classificateur, en lui passant des paramètres très importants, comme le facteur d'échelle, le nombre de voisins et la taille minimale du visage détecté.

faces = faceCascade.detectMultiScale(gris, scaleFactor=1,2, minNeighbors=5, minSize=(20, 20))

Où,

  • gray est l'image en niveaux de gris d'entrée.
  • scaleFactor est le paramètre spécifiant de combien la taille de l'image est réduite à chaque échelle d'image. Il est utilisé pour créer la pyramide à l'échelle.
  • minNeighbors est un paramètre spécifiant le nombre de voisins que chaque rectangle candidat doit avoir pour le conserver. Un nombre plus élevé donne moins de faux positifs.
  • minSize est la taille minimale du rectangle pour être considéré comme un visage.

La fonction détectera les visages sur l'image. Ensuite, il faut "marquer" les visages dans l'image, à l'aide, par exemple, d'un rectangle bleu. Ceci est fait avec cette partie du code:

pour (x, y, w, h) dans les faces:

cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2) roi_gray = gray[y:y+h, x:x+w] roi_color = img[y:y+h, x:x+w]

Si des visages sont trouvés, il renvoie les positions des visages détectés sous la forme d'un rectangle avec le coin supérieur gauche (x, y) et ayant "w" comme largeur et "h" comme hauteur ==> (x, y, w, h). S'il vous plaît voir l'image ci-dessus.

Une fois ces emplacements obtenus, nous pouvons créer un "ROI" (rectangle dessiné) pour le visage et présenter le résultat avec la fonction imshow().

Exécutez le script python ci-dessus sur votre environnement python, à l'aide du terminal Rpi:

python faceDetection.py

Le résultat:

Image
Image

Vous pouvez également inclure des classificateurs pour la "détection des yeux" ou même la "détection du sourire". Dans ces cas, vous incluez la fonction de classificateur et le dessin de rectangle à l'intérieur de la boucle du visage, car il n'aurait aucun sens de détecter un œil ou un sourire à l'extérieur d'un visage.

A noter que sur un Pi, avoir plusieurs classificateurs dans un même code ralentira le traitement, une fois que cette méthode de détection (HaarCascades) utilise une grande puissance de calcul. Sur un ordinateur de bureau, il est plus facile de l'exécuter.

Sur mon GitHub vous trouverez d'autres exemples:

faceEyeDetection.py

faceSmileDetection.py

faceSmileEyeDetection.py

Et dans l'image ci-dessus, vous pouvez voir le résultat.

Vous pouvez également suivre le tutoriel ci-dessous pour mieux comprendre la détection de visage:

Haar Cascade Détection d'objets Visage et œil Tutoriel Python OpenCV

Étape 5: Collecte de données

Collecte de données
Collecte de données
Collecte de données
Collecte de données

Tout d'abord, je dois remercier Ramiz Raja pour son excellent travail sur la reconnaissance faciale sur les photos:

RECONNAISSANCE DES VISAGES À L'AIDE D'OPENCV ET DE PYTHON: GUIDE DU DÉBUTANT

et aussi Anirban Kar, qui a développé un tutoriel très complet en vidéo:

RECONNAISSANCE DU VISAGE - 3 parties

Je vous recommande vraiment de jeter un œil aux deux tutoriels.

Cela dit, commençons la première phase de notre projet. Ce que nous allons faire ici, c'est à partir de la dernière étape (Détection de visage), nous allons simplement créer un ensemble de données, où nous stockerons pour chaque identifiant, un groupe de photos en gris avec la partie qui a été utilisée pour la détection de visage.

Tout d'abord, créez un répertoire dans lequel vous développez votre projet, par exemple, FacialRecognitionProject:

Projet de reconnaissance faciale mkdir

Dans ce répertoire, outre les 3 scripts python que nous allons créer pour notre projet, nous devons y avoir enregistré le Facial Classifier. Vous pouvez le télécharger depuis mon GitHub: haarcascade_frontalface_default.xml

Ensuite, créez un sous-répertoire où nous allons stocker nos échantillons de visage et nommez-le "ensemble de données":

jeu de données mkdir

Et téléchargez le code depuis mon GitHub: 01_face_dataset.py

importer cv2

import os cam = cv2. VideoCapture(0) cam.set(3, 640) # définir la largeur de la vidéo cam.set(4, 480) # définir la hauteur de la vidéo face_detector = cv2. CascadeClassifier('haarcascade_frontalface_default.xml') # Pour chaque personne, entrez un identifiant de visage numérique face_id = input('\n entrez l'identifiant de l'utilisateur et appuyez sur ==> ') print("\n [INFO] Initialisation de la capture de visage. Regardez la caméra et attendez …") # Initialisez le nombre de visages d'échantillonnage individuel = 0 while(True): ret, img = cam.read() img = cv2.flip(img, -1) # retourne l'image vidéo verticalement gray = cv2.cvtColor(img, cv2. COLOR_BGR2GRAY) faces = face_detector.detectMultiScale(gris, 1,3, 5) pour (x, y, w, h) dans les faces: cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2) count += 1 # Enregistrez l'image capturée dans le dossier des ensembles de données cv2.imwrite("dataset/User." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+ h, x:x+w]) cv2.imshow('image', img) k = cv2.waitKey(100) & 0xff # Appuyez sur 'ESC' pour quitter la vidéo si k == 27: break elif count >= 30: # Prenez 30 échantillons de visage et arrêtez la pause vidéo # Faites ab it of cleanup print("\n [INFO] Quitter le programme et nettoyer les choses") cam.release() cv2.destroyAllWindows()

Le code est très similaire au code que nous avons vu pour la détection de visage. Ce que nous avons ajouté, était une "commande d'entrée" pour capturer un identifiant utilisateur, qui devrait être un nombre entier (1, 2, 3, etc.)

face_id = input('\n entrez l'identifiant de l'utilisateur et appuyez sur ==> ')

Et pour chacune des images capturées, nous devons l'enregistrer sous forme de fichier dans un répertoire "dataset":

cv2.imwrite("dataset/User." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+h, x:x+w])

Notez que pour enregistrer le fichier ci-dessus, vous devez avoir importé la bibliothèque "os". Le nom de chaque fichier suivra la structure:

User.face_id.count.jpg

Par exemple, pour un utilisateur avec un face_id = 1, le 4ème exemple de fichier sur le répertoire dataset/ sera quelque chose comme:

Utilisateur.1.4.jpg

comme le montre la photo ci-dessus de mon Pi. Sur mon code, je capture 30 échantillons de chaque identifiant. Vous pouvez le changer sur le dernier "elif". Le nombre d'échantillons est utilisé pour rompre la boucle où les échantillons de visage sont capturés.

Exécutez le script Python et capturez quelques identifiants. Vous devez exécuter le script à chaque fois que vous souhaitez agréger un nouvel utilisateur (ou modifier les photos d'un utilisateur déjà existant).

Étape 6: Formateur

Entraîneur
Entraîneur

Sur cette deuxième phase, nous devons prendre toutes les données utilisateur de notre ensemble de données et "former" l'OpenCV Recognizer. Cela se fait directement par une fonction OpenCV spécifique. Le résultat sera un fichier.yml qui sera enregistré dans un répertoire "trainer/".

Commençons donc par créer un sous-répertoire où nous stockerons les données entraînées:

entraîneur mkdir

Téléchargez depuis mon GitHub le deuxième script python: 02_face_training.py

importer cv2

import numpy as np depuis PIL import Image import os # Chemin d'accès à la base de données d'images de visage chemin = 'dataset' reconnaisseur = cv2.face. LBPHFaceRecognizer_create() detecteur = cv2. CascadeClassifier("haarcascade_frontalface_default.xml"); # fonction pour obtenir les images et les données d'étiquette def getImagesAndLabels(path): imagePaths = [os.path.join(path, f) for f in os.listdir(path)] faceSamples= ids = for imagePath in imagePaths: PIL_img = Image.open(imagePath).convert('L') # le convertit en niveaux de gris img_numpy = np.array(PIL_img, 'uint8') id = int(os.path.split(imagePath)[-1]. split(".")[1]) faces = detect.detectMultiScale(img_numpy) pour (x, y, w, h) dans les faces: faceSamples.append(img_numpy[y:y+h, x:x+w]) ids.append(id) return faceSamples, ids print ("\n [INFO] Entraînement des visages. Cela prendra quelques secondes. Attendez …") faces, ids = getImagesAndLabels(path) Recognizer.train(faces, np.array(ids)) # Enregistrer le modèle dans trainer/trainer.yml reconnaissant.write('trainer/trainer.yml') # reconnaître.save() a fonctionné sur Mac, mais pas sur Pi # Imprimer le nombre de visages entraînés et terminer l'impression du programme ("\n [INFO] {0} visages entraînés. Quitter le programme".format(len(np.unique(ids)))))

Confirmez si la bibliothèque PIL est installée sur votre Rpi. Sinon, exécutez la commande ci-dessous dans Terminal:

pip installer oreiller

Nous utiliserons comme outil de reconnaissance, le LBPH (LOCAL BINARY PATTERNS HISTOGRAMS) Face Recognizer, inclus dans le package OpenCV. Nous le faisons dans la ligne suivante:

reconnaissance = cv2.face. LBPHFaceRecognizer_create()

La fonction "getImagesAndLabels (path)", prendra toutes les photos sur le répertoire: "dataset/", renvoyant 2 tableaux: "Ids" et "faces". Avec ces tableaux en entrée, nous allons « entraîner notre reconnaisseur »:

reconnaissant.train(visages, identifiants)

En conséquence, un fichier nommé "trainer.yml" sera enregistré dans le répertoire trainer que nous avons précédemment créé.

C'est ça! J'ai inclus la dernière déclaration d'impression où j'ai affiché pour confirmation, le nombre de visages d'utilisateurs que nous avons entraînés.

Chaque fois que vous effectuez la phase 1, la phase 2 doit également être exécutée

Étape 7: Reconnaissance

Reconnaissance
Reconnaissance
Reconnaissance
Reconnaissance

Maintenant, nous sommes arrivés à la phase finale de notre projet. Ici, nous allons capturer un nouveau visage sur notre appareil photo et si cette personne avait déjà son visage capturé et entraîné, notre reconnaisseur fera une "prédiction" renvoyant son identifiant et un index, montrant à quel point le reconnaisseur est confiant avec ce match.

Téléchargeons le script python de 3ème phase depuis mon GitHub: 03_face_recognition.py.

importer cv2

importer numpy as np importer os reconnaisseur = cv2.face. LBPHFaceRecognizer_create() reconnaissant.read('trainer/trainer.yml') cascadePath = "haarcascade_frontalface_default.xml" faceCascade = cv2. CascadeClassifier(cascadePath); font = cv2. FONT_HERSHEY_SIMPLEX #iniciate id counter id = 0 # noms liés aux identifiants: exemple ==> Marcelo: id=1, etc names = ['None', 'Marcelo', 'Paula', 'Ilza', 'Z ', 'W'] # Initialiser et démarrer la capture vidéo en temps réel cam = cv2. VideoCapture(0) cam.set(3, 640) # définir la largeur de la vidéo cam.set(4, 480) # définir la hauteur de la vidéo # Définir la taille minimale de la fenêtre à reconnaître comme un visage minW = 0.1*cam.get(3) minH = 0.1*cam.get(4) alors que True: ret, img =cam.read() img = cv2.flip(img, -1) # Retourner verticalement gray = cv2.cvtColor(img, cv2. COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale(gray, scaleFactor = 1.2, minNeighbors = 5, minSize = (int(minW), int(minH)),) for(x, y, w, h) dans les visages: cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) id, confidence = reconnaissant.predict(gray[y:y+h, x:x+w]) # Vérifiez si la confiance est inférieure à 100 ==> "0" correspond parfaitement si (confiance < 100): id = names[id] confidence = " {0}% ".format(round(100 - confidence)) else: id = "inconnu" confidence = " {0}%".format(round(100 - conf idence)) cv2.putText(img, str(id), (x+5, y-5), font, 1, (255, 255, 255), 2) cv2.putText(img, str(confidence), (x+5, y+h-5), police, 1, (255, 255, 0), 1) cv2.imshow('camera', img) k = cv2.waitKey(10) & 0xff # Appuyez sur 'ESC' pour quitter la vidéo si k == 27: break # Faire un peu de nettoyage print("\n [INFO] Quitter le programme et nettoyer les trucs") cam.release() cv2.destroyAllWindows()

Nous incluons ici un nouveau tableau, nous afficherons donc des "noms", au lieu d'identifiants numérotés:

noms = ['Aucun', 'Marcelo', 'Paula', 'Ilza', 'Z', 'W']

Ainsi, par exemple: Marcelo sera l'utilisateur avec id = 1; Paula: id=2, etc.

Ensuite, nous allons détecter un visage, comme nous l'avons fait auparavant avec le classificateur haasCascade. Ayant un visage détecté, nous pouvons appeler la fonction la plus importante dans le code ci-dessus:

id, confidence = reconnaitre.predict (partie grise du visage)

Le reconnaisseur.predict(), prendra comme paramètre une portion capturée du visage à analyser et renverra son propriétaire probable, en indiquant son identifiant et le degré de confiance du reconnaisseur par rapport à cette correspondance.

Notez que l'indice de confiance retournera "zéro" s'il est considéré comme une correspondance parfaite

Et enfin, si le reconnaisseur pouvait prédire un visage, nous mettons un texte sur l'image avec l'identifiant probable et quelle est la "probabilité" en % que la correspondance soit correcte ("probabilité" = 100 - indice de confiance). Sinon, une étiquette « inconnu » est apposée sur le visage.

Ci-dessous un-g.webp

Image
Image

Sur la photo ci-dessus, je montre quelques tests effectués avec ce projet, où j'ai également utilisé des photos pour vérifier si le reconnaisseur fonctionne.

Étape 8: Conclusion

Conclusion
Conclusion

Comme toujours, j'espère que ce projet pourra aider d'autres personnes à trouver leur chemin dans le monde passionnant de l'électronique !

Pour plus de détails et le code final, veuillez visiter mon dépôt GitHub: OpenCV-Face-Recognition

Pour plus de projets, veuillez visiter mon blog: MJRoBot.org

Ci-dessous un aperçu d'un futur didacticiel, où nous explorerons « le suivi automatique des visages et d'autres méthodes de détection des visages »:

Image
Image

Salutations du sud du monde !

Rendez-vous dans mon prochain instructable !

Merci, Marcelo

Conseillé: