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.

Reconnaissance faciale avec le deep learning

Mis à jour le May 7, 2024, 6:57 a.m.

Niveau: Expert

 

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


1 - Installation du module

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'):
        break

Super, 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 ?

4-Allons plus loin avec une analyse sur video

 

Conclusion

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. 


Références

https://github.com/ageitgey/face_recognition

 



Introduction à l'utilisation d'OpenCV: les fondamentaux


Introduction à l'utilisation d'OpenCV: Manipulations sur image


Introduction à l'utilisation d'OpenCV: Reconnaissance faciale, old school style!


Introduction à l'utilisation d'OpenCV: detection faciale avec le deep learning


Introduction à l'utilisation d'OpenCV: detection et reconnaissance d'objet avec YOLO


Reconnaissance faciale avec le deep learning

Vous êtes sur ce tutoriel

Commentaires

Aucun commentaire pour cet article.

Bienvenue sur Pythonia, pour ceux qui veulent réellement maîtriser la programmation et l'intelligence artificielle.

Rejoignez notre communauté de professionnels et de passionnés, pour rester à la pointe des dernières actualités.

Laissez un commentaire