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 :
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.
!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.
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:
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 :
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 :
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) :
# 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
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 :
# 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.
Pingback: Analyse d'une carte d'identité - Data Corner
Pingback: Reconnaissance faciale avec OpenCV - datacorner par Benoit Cayla
C’est de la détection de visage et pas de la reconnaissance faciale facial .
Bonjour,
Vous avez raison, soyons puriste: il s’agit bien de détection faciale dans la mesure où l’on n’est pas capable dans cet exemple de différencier deux personnes différentes.
Je vais changer le titre, merci de votre retour.
Bien à vous.
Bonjour coach,
J’ai fait une application de reconnaissance faciale (python, opencv, dlib, face_recognition), qui fait la présence. Mais l’application confond certains visages, mais du moins à 99%. Et si une personne se présente avec une photo. L’application marquera sa présence. Comment puis-je contourner cela? en détectant si c’est une personne physique qui est devant la caméra. Ou, c’est une photo.
Votre réponse, pourra m’aider à enrichir mon application.