Détection faciale avec OpenCV 5   Mise à jour récente !


OpenCV ?

La reconnaissance de visage est aujourd’hui un domaine mature qui fait d’ailleurs l’objet de plusieurs librairies, framework mais aussi et surtout de services cognitifs (Microsoft, Google, etc.). Je vous propose aujourd’hui de découvrir comment utiliser la librairie OpenCV (Open Source bien sûr) pour effectuer ce genre d’opération.

Pour information :

OpenCV (pour Open Computer Vision) est une bibliothèque graphique libre, initialement développée par Intel, spécialisée dans le traitement d’images en temps réel. La société de robotique Willow Garage et la société ItSeez se sont succédé au support de cette bibliothèque. Depuis 2016 et le rachat de ItSeez par Intel, le support est de nouveau assuré par Intel. Cette bibliothèque est distribuée sous licence BSD.

Wikipédia

Nous reviendrons régulièrement sur cette librairie car au delà de la détection faciale que nous allons aborder dans cet article elle permet aussi de retravailler les images et les vidéos, elle propose des fonctions de calcul matriciels très utiles quand on traite des données multimédia et bien sur embarque des algorithmes d’apprentissages. Bref, c’est une petite pépite pour ceux qui veulent traiter des données multimédia !

Pour cet article, j’utiliserai Python 3.7, il faudra juste veiller à installer la librairie OpenCV 4.2.0 bien sur. Pour cela le site d’OpenCV vous guide de manière assez bien détaillée.

Si vous êtes comme moi sur linux tapez simplement en ligne de commande :

PowerShell
pip install opencv-python

Avant toute chose il faut récupérer les modèles pré-configurés sur le site OpenCV. Pour cela allez sur https://github.com/opencv/opencv/tree/3.4/data/haarcascades et copiez localement le contenu du répertoire ./opencv/. Ou alors, si comme moi vous utilisez google colab, tapez ces deux lignes de code afin de récupérer sur le site d’OpenCV les modèles que nous allons utiliser.

Python
!wget https://github.com/opencv/opencv/raw/master/data/haarcascades/haarcascade_frontalface_default.xml
!wget https://github.com/opencv/opencv/raw/master/data/haarcascades/haarcascade_frontalface_alt.xml

Note: Vous trouverez plus d’informations sur ces modèles ici : https://docs.opencv.org/3.4/db/d28/tutorial_cascade_classifier.html

Premier test

Pour ce premier test nous allons utiliser une photo :

Nous allons dans un premier temps utiliser le modèle pré-configuré haarcascade_frontalface_default.xml.

Python
import cv2
import sys
from matplotlib import pyplot as plt

imagePath = r'marathon.jpeg'
# Récupération de fichiers préconfigurés : https://github.com/opencv/opencv/tree/3.4/data/haarcascades
cascadefile = "haarcascade_frontalface_default.xml"
classCascade = cv2.CascadeClassifier(cascadefile)
if classCascade.empty():
    print("Erreur : le fichier cascade n'a pas pu être chargé.")

Ces lignes de commandes initialisent OpenCV (enfin surtout le classifier avec le modèle préconfiguré) et affichent l’image précédente.

Si on affiche l’image directement comme ceci:

Python
image = cv2.imread(imagePath)
plt.imshow(image)

Maintenant nous devons convertir l’image en niveau de gris afin de pouvoir utiliser la fonction de détection faciale. La conversion en niveau de gris est une transformations dans l’espace RVB (Rouge/Vert/Bleu) comme l’ajout / la suppression du canal alpha, l’inversion de l’ordre des canaux, la conversion vers / depuis la couleur RVB 16 bits (R5: G6: B5 ou R5: G5: B5), ainsi que la conversion vers / depuis l’échelle de gris.

Une ligne en Python suffit pour cela :

Python
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
plt.imshow(gray)

Voilà le résultat de la transformation opéré par OpenCV :

Maintenant nous pouvons lancer l’opération de détection de visage :

Python
faces = classCascade.detectMultiScale(
    gray,
    scaleFactor=1.1,
    minNeighbors=5,
    minSize=(30, 30),
    flags = cv2.CASCADE_SCALE_IMAGE
)
print("Il y a {0} visage(s).".format(len(faces)))

Sans grand étonnement on devrait détecter plusieurs visages, trop sans doute !

Il y a 13 visage(s).

Plutôt étonnant n’est-ce pas ? y-aurait-il 2 autres personnes cachées dans cette photo ? regardons de plus près en demandant à OpenCV de marquer via des cadres de couleurs les visages détectés. Opération plutôt simple puisque la fonction de détection de visage renvoit aussi les coordonnées des rectangles contenant ces derniers (ici via l’objet faces) :

Python
# Dessine des rectangles autour des visages trouvés
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x+w, y+h), (255, 0, 0), thickness=10)
plt.imshow(image)

Nous avons bien un soucis, apparemment la détection de forme via le modèle de classification choisi n’est pas assez précise ! Nous avons détecté quelques visages en trop …

Changeons de modèle prédéfini

C’est en fait une opération plutôt simple car il suffit de changer de fichier xml (Cf. les fichiers que vous avez télécharger au préalable). Utilisons à la place du précédent le fichier haarcascade_frontalface_alt.xml

Python
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cascadefile = "haarcascade_frontalface_alt.xml"
classCascade = cv2.CascadeClassifier(cascadefile)
faces = classCascade.detectMultiScale(
    gray,
    scaleFactor=1.1,
    minNeighbors=5,
    minSize=(30, 30),
    flags = cv2.CASCADE_SCALE_IMAGE
)
print("Il y a {0} visage(s).".format(len(faces)))
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x+w, y+h), (255, 0, 0), thickness=10)

plt.imshow(image)

Le résultat semble bien meilleur cette fois-ci car nous n’avons plus que 8 visages détectés:

Et si nous voulions découper notre visage pour enlever les contours inutiles ? rien de plus simple … n’oublions pas qu’une image n’est rien d’autre qu’une matrice :

Python
# Sélectionner le plus grand visage
if len(faces) > 0:
    # Trouver le rectangle correspondant au plus grand visage
    largest_face = max(faces, key=lambda rect: rect[2] * rect[3])  # rect[2]*rect[3] = largeur * hauteur
    x, y, w, h = largest_face
    
    # Découper uniquement le visage
    largest_face_image = image[y:y+h, x:x+w]

    # Afficher le plus grand visage
    plt.imshow(cv2.cvtColor(largest_face_image, cv2.COLOR_BGR2RGB))
    plt.axis('off')  # Supprimer les axes pour une meilleure visualisation
    plt.show()
else:
    print("Aucun visage détecté.")

Conclusion

Nous avons survolé dans cet article comment utiliser les modèles pré-embarqués ainsi que quelques fonctions de retouches d’image fournies en standard par OpenCV. Même si ces fonctions sont très performantes (et vraiment très utiles) on se rend vite compte qu’il faut choisir intelligemment les bons modèles ainsi que les bons paramètres si l’on veut une détection faciale de qualité. La bonne nouvelle c’est que cette librairie regorge d’exemples et de tutoriels qu’il ne faut pas hésiter à parcourir … bien sur nous y reviendrons dans de futurs articles.

Comme d’habitude vous trouverez les codes sources de ce tuto sur GitHub.


A propos de Benoit Cayla

Ingénieur en informatique avec plus de 20 ans d’expérience dans la gestion et l’utilisation de données, Benoit CAYLA a mis son expertise au profit de projets très variés tels que l’intégration, la gouvernance, l’analyse, l’IA, la mise en place de MDM ou de solution PIM pour le compte de diverses entreprises spécialisées dans la donnée (dont IBM, Informatica et Tableau). Ces riches expériences l’ont naturellement conduit à intervenir dans des projets de plus grande envergure autour de la gestion et de la valorisation des données, et ce principalement dans des secteurs d’activités tels que l’industrie, la grande distribution, l’assurance et la finance. Également, passionné d’IA (Machine Learning, NLP et Deep Learning), l’auteur a rejoint Blue Prism en 2019 et travaille aujourd’hui en tant qu’expert data/IA et processus. Son sens pédagogique ainsi que son expertise l’ont aussi amené à animer un blog en français (datacorner.fr) ayant pour but de montrer comment comprendre, analyser et utiliser ses données le plus simplement possible.

Laissez un commentaire

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

5 commentaires sur “Détection faciale avec OpenCV