Tutoriels de Pythonia
Guides, IA, tutos et newsletter pour devenir une bête en programmation
🔔 Ne manquez pas la suite de cette série !
Inscrivez-vous pour être informé des prochains tutoriels.
Inscrivez-vous pour être informé des prochains tutoriels.
Mis à jour le May 7, 2024, 6:57 a.m.
Bienvenue dans cet article dédié aux à la reconnaissance faciale avec OpenCV et le module face_recognition.
Avec les avancées computer vision, en machine learning et en deep learning, la reconnaissance faciale est devenue un sujet très populaire. Elle peut être utilisée dans plein de domaines, comme la prévention de la criminalité, la surveillance, les enquêtes, la biométrie, et même les réseaux sociaux. Bien sûr, il y a des défis, comme les visages partiellement cachés, les variations d'apparence, les expressions, le vieillissement et les différences d'échelle. Grâce à leur succès en reconnaissance d'objets, les réseaux de neurones convolutifs (CNN) sont maintenant très utilisés pour la reconnaissance faciale.
Dans ce chapitre, on va voir ce que le module face_recognition propose pour la reconnaissance faciale et découvrir quelques approches de deep learning. Ces techniques peuvent facilement s'intégrer à vos projets de vision par ordinateur pour obtenir des résultats de reconnaissance faciale ultra-performants.
1-Installation des modules
2-Reconnaissance faciale sur une image
3-Reconnaissance faciale en temps réel sur webcam
Conclusion
La bibliothèque face_recognition simplifie énormément l'implémentation de la reconnaissance faciale en utilisant dlib pour deux tâches essentielles : l'encodage des visages et le calcul des distances entre les visages encodés. Grâce à cela, vous n'avez pas besoin de coder les fonctions face_encodings() et compare_faces(), vous pouvez simplement les utiliser directement.
Par exemple, le script encode_face_fr.py vous montre comment créer un descripteur 128D. Voici comment procéder :
Chargement de l'image : importez une image contenant les visages que vous souhaitez encoder.
Détection des visages : utilisez face_recognition pour détecter les visages dans l'image.
Encodage des visages : appliquez la fonction face_encodings() pour obtenir les descripteurs 128D pour chaque visage détecté.
pip install face_recognition
Voilà la structure du projet:
Visages_connus
image quelconque
main.py
Dans Visages_connus, on a plusieurs dossiers contenant chacun plusieurs images du sujet en question, par exemple, alexandre, pierre, paul, jacques.
Mettre quelques images dans 'images quelconque'.
Comment fonctionne le module face_recognition?
2 - Reconnaissance faciale sur une image
Comme précedemment détectons un visage sur une image pour commencer. Je prends l'image suivante sur ce site web et je la sauvegarde sous le nom de girl.jpg.
Il nous reste à définir nos variables.
Tolerance: 0.6
Model = cnn ou HOG que l'on a vu dans les précédents tutoriels
Bon maintenant, chargeons nos visages. Que va t il se passer lors de ce script? On va charger une image. Pour chaque image nous allons essayer de detecter un visage. Pour chaque visages detectés nous allons faire une comparaison avec les visages que nous possédons.
On commence par charger nos "visage connus"
import face_recognition
import os
import cv2
KNOWN_FACES_DIR = 'visages_connus'
UNKNOWN_FACES_DIR = 'inconnus'
TOLERANCE = 0.6
FRAME_THICKNESS = 3
FONT_THICKNESS = 2
MODEL = 'cnn' # default: 'hog', other one can be 'cnn' - CUDA accelerated (if available) deep-learning pretrained model
print('Loading known faces...')
known_faces = []
known_names = []
# We oranize known faces as subfolders of KNOWN_FACES_DIR
# Each subfolder's name becomes our label (name)
for name in os.listdir(KNOWN_FACES_DIR):
# Next we load every file of faces of known person
for filename in os.listdir(f'{KNOWN_FACES_DIR}/{name}'):
# Load an image
image = face_recognition.load_image_file(f'{KNOWN_FACES_DIR}/{name}/{filename}')
# Get 128-dimension face encoding
# Always returns a list of found faces, for this purpose we take first face only (assuming one face per image as you can't be twice on one image)
encoding = face_recognition.face_encodings(image)[0]
# Append encodings and name
known_faces.append(encoding)
known_names.append(name)
print('Processing unknown faces...')
# Now let's loop over a folder of faces we want to label
for filename in os.listdir(UNKNOWN_FACES_DIR):
# Load image
print(f'Filename {filename}', end='')
image = face_recognition.load_image_file(f'{UNKNOWN_FACES_DIR}/{filename}')
# This time we first grab face locations - we'll need them to draw boxes
locations = face_recognition.face_locations(image, model=MODEL)
print("locations: ", locations)
# Now since we know locations, we can pass them to face_encodings as second argument
# Without that it will search for faces once again slowing down whole process
encodings = face_recognition.face_encodings(image, locations)
# We passed our image through face_locations and face_encodings, so we can modify it
# First we need to convert it from RGB to BGR as we are going to work with cv2
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
# But this time we assume that there might be more faces in an image - we can find faces of dirrerent people
print(f', found {len(encodings)} face(s)')
for face_encoding, face_location in zip(encodings, locations):
# We use compare_faces (but might use face_distance as well)
# Returns array of True/False values in order of passed known_faces
results = face_recognition.compare_faces(known_faces, face_encoding, TOLERANCE)
# Since order is being preserved, we check if any face was found then grab index
# then label (name) of first matching known face withing a tolerance
match = None
if True in results: # If at least one is true, get a name of first of found labels
match = known_names[results.index(True)]
print(f' - {match} from {results}')
# Each location contains positions in order: top, right, bottom, left
top_left = (face_location[3], face_location[0])
bottom_right = (face_location[1], face_location[2])
# Get color by name using our fancy function
color = (225,225,248)
# Paint frame
cv2.rectangle(image, top_left, bottom_right, color, FRAME_THICKNESS)
# Now we need smaller, filled grame below for a name
# This time we use bottom in both corners - to start from bottom and move 50 pixels down
top_left = (face_location[3], face_location[2])
bottom_right = (face_location[1], face_location[2] + 22)
# Paint frame
#cv2.rectangle(image, top_left, bottom_right, color, cv2.FILLED)
# Wite a name
cv2.putText(image, match, (face_location[3] + 10, face_location[2] + 15),
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2)
#cv2.putText(image, match, (face_location[3] + 10, face_location[2] + 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (200, 200, 200), FONT_THICKNESS)
if False in results:
# Each location contains positions in order: top, right, bottom, left
top_left = (face_location[3], face_location[0])
bottom_right = (face_location[1], face_location[2])
cv2.rectangle(image, top_left, bottom_right, color, FRAME_THICKNESS)
# Wite a name
cv2.putText(image, "Inconnu", (face_location[3] + 10, face_location[2] + 15),
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2)
# Show image
cv2.imshow(filename, image)
cv2.waitKey(0)
cv2.destroyWindow(filename)
3 - Reconnaissance faciale via video
Bon, puisque vous savez à présent faire de la reconnaissance faciale sur une image, je ne vois pas pourquoi ça ne fonctionnerait pas sur une video. Après tout, une video n'est qu'une suite d'images.
Voici le code pour la détection de visage sur votre webcam, c'est un petit peu différent, cette fois-ci on fait appel à opencv pour la lecture.
import face_recognition
import os
import cv2
KNOWN_FACES_DIR = 'visages_connus'
TOLERANCE = 0.6
FRAME_THICKNESS = 3
FONT_THICKNESS = 2
MODEL = 'cnn' # default: 'hog', other one can be 'cnn' - CUDA accelerated (if available) deep-learning pretrained model
print('Loading known faces...')
known_faces = []
known_names = []
# We oranize known faces as subfolders of KNOWN_FACES_DIR
# Each subfolder's name becomes our label (name)
for name in os.listdir(KNOWN_FACES_DIR):
# Next we load every file of faces of known person
for filename in os.listdir(f'{KNOWN_FACES_DIR}/{name}'):
# Load an image
image = face_recognition.load_image_file(f'{KNOWN_FACES_DIR}/{name}/{filename}')
# Get 128-dimension face encoding
# Always returns a list of found faces, for this purpose we take first face only (assuming one face per image as you can't be twice on one image)
encoding = face_recognition.face_encodings(image)[0]
# Append encodings and name
known_faces.append(encoding)
known_names.append(name)
# Now let's loop over a folder of faces we want to label
# Démarrer le flux vidéo de la caméra
print('initialisation du flux video')
cap = cv2.VideoCapture(0)
# Get color by name using our fancy function
color = (225,225,248)
while True:
print("C'est parti!")
ret, image = cap.read()
# S'assurer que la frame a été lue correctement
if not ret:
break
# This time we first grab face locations - we'll need them to draw boxes
locations = face_recognition.face_locations(image, model=MODEL)
print("locations: ", locations)
# Now since we know locations, we can pass them to face_encodings as second argument
# Without that it will search for faces once again slowing down whole process
encodings = face_recognition.face_encodings(image, locations)
# We passed our image through face_locations and face_encodings, so we can modify it
# First we need to convert it from RGB to BGR as we are going to work with cv2
#image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
# But this time we assume that there might be more faces in an image - we can find faces of dirrerent people
print(f', found {len(encodings)} face(s)')
for face_encoding, face_location in zip(encodings, locations):
# We use compare_faces (but might use face_distance as well)
# Returns array of True/False values in order of passed known_faces
results = face_recognition.compare_faces(known_faces, face_encoding, TOLERANCE)
# Since order is being preserved, we check if any face was found then grab index
# then label (name) of first matching known face withing a tolerance
match = None
if True in results: # If at least one is true, get a name of first of found labels
match = known_names[results.index(True)]
print(f' - {match} from {results}')
# Each location contains positions in order: top, right, bottom, left
top_left = (face_location[3], face_location[0])
bottom_right = (face_location[1], face_location[2])
# Paint frame
cv2.rectangle(image, top_left, bottom_right, color, FRAME_THICKNESS)
# Now we need smaller, filled grame below for a name
# This time we use bottom in both corners - to start from bottom and move 50 pixels down
top_left = (face_location[3], face_location[2])
bottom_right = (face_location[1], face_location[2] + 22)
# Paint frame
#cv2.rectangle(image, top_left, bottom_right, color, cv2.FILLED)
# Wite a name
cv2.putText(image, match, (face_location[3] + 10, face_location[2] + 15),
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2)
#cv2.putText(image, match, (face_location[3] + 10, face_location[2] + 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (200, 200, 200), FONT_THICKNESS)
if False in results:
# Each location contains positions in order: top, right, bottom, left
top_left = (face_location[3], face_location[0])
bottom_right = (face_location[1], face_location[2])
cv2.rectangle(image, top_left, bottom_right, color, FRAME_THICKNESS)
# Wite a name
cv2.putText(image, "Inconnu", (face_location[3] + 10, face_location[2] + 15),
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2)
# Show image
cv2.imshow(filename, image)
# Sortir de la boucle si on appuie sur 'q'
if cv2.waitKey(1) & 0xFF == ord('q'):
breakSuper, maintenant vous avez un modele de detection faciale boosté au deep learning. mais ce serait dommage de s'arreter là. Comment faire pour une reconnaissance faciale ?
Nous avons exploré dans cet article les fondamentaux et les techniques avancées pour la détection faciale en utilisant OpenCV et des réseaux de neurones profonds.
https://github.com/ageitgey/face_recognition
Aucun commentaire pour cet article.