Vous êtes sur la page 1sur 22

PROJET

TRAITEMENT
DE L’IMAGE
FACE DETECTION AVEC
TENSOFLOW ET OPENCV

BILAL EL MAFTOUHI
NABIL KACHAR

ENCADRÉ PAR
MR. LACHKAR ABDELMONAIME
1. INTRODUCTION

La détection de visages est une technologie clé dans de


nombreuses applications modernes, allant de la sécurité aux
réseaux sociaux, en passant par la photographie numérique et les
systèmes de reconnaissance biométrique. Elle permet d'identifier et
de localiser les visages humains dans des images ou des vidéos,
fournissant ainsi une base essentielle pour des applications plus
complexes telles que la reconnaissance faciale, l'analyse des
expressions et l'authentification.

2. OBJECTIF DU PROJET

L'objectif de ce projet est de créer une application capable de


détecter les visages en temps réel en utilisant les bibliothèques
OpenCV et TensorFlow. Cette application vise à offrir une solution
rapide et précise pour la détection de visages dans divers
environnements et conditions. Nous aborderons les étapes de
développement de l'application, les défis rencontrés, et les solutions
mises en œuvre pour optimiser la performance et la précision de la
détection en temps réel.

3. Technologies Utilisées
OpenCV : OpenCV (Open Source Computer Vision Library) est
une bibliothèque logicielle contenant plus de 2500 algorithmes
de vision par ordinateur. Elle est largement utilisée pour des
tâches telles que la reconnaissance d'objets, le suivi de
mouvements et la détection de visages. Dans ce projet, OpenCV
sera utilisé pour traiter les images et vidéos en temps réel, et
pour implémenter des algorithmes de détection de visages tels
que Haar Cascade.
TensorFlow : TensorFlow est une bibliothèque open-source de
machine learning, développée par l'équipe Google Brain. Elle
est utilisée pour des applications allant de la reconnaissance
d'images à la modélisation de la parole. Pour la détection de
visages en temps réel, nous utiliserons des modèles de réseaux
de neurones convolutifs (CNN), notamment le modèle MTCNN
(Multi-task Cascaded Convolutional Networks), connu pour sa
précision et sa capacité à gérer des visages dans des
orientations variées.

4. MÉTHODOLOGIE
1. CONFIGURATION ET OBTENTION DES DONNÉES

Ce segment de code utilise OpenCV pour capturer des images


en temps réel à partir de la webcam. Il initialise la capture vidéo,
lit les images, les redimensionne, et les enregistre avec des
noms de fichiers uniques. Chaque image est affichée et la
capture continue jusqu'à ce que l'utilisateur appuie sur la
touche 'q' pour quitter. Enfin, la capture est libérée et les
fenêtres sont fermées proprement.
LabelMe est un outil open-source largement utilisé pour
l'annotation d'images. Il permet aux utilisateurs de créer des
annotations précises en dessinant des polygones autour des objets
d'intérêt dans les images. Ces annotations sont ensuite
enregistrées au format JSON, facilitant leur utilisation ultérieure
pour l'entraînement et l'évaluation des modèles de machine
learning. LabelMe est particulièrement utile pour les projets de
vision par ordinateur nécessitant des jeux de données annotés de
haute qualité.

2. EXAMINER LE JEU DE DONNÉES ET CRÉER UNE FONCTION DE


CHARGEMENT D'IMAGES
Cette section du projet se concentre sur l'examen du jeu de
données et la création d'une fonction de chargement d'images à
l'aide de TensorFlow. Nous commençons par configurer la gestion
de la mémoire GPU pour éviter les erreurs de dépassement de
mémoire. Ensuite, nous modifions les permissions du répertoire
des images pour assurer l'accès en lecture. Nous listons les fichiers
d'images et les chargeons dans un jeu de données TensorFlow.
Une fonction load_image est définie pour lire et décoder chaque
image JPEG. Les images sont ensuite mappées à cette fonction et
regroupées par lots de quatre pour faciliter l'affichage et le
traitement. Enfin, nous visualisons les images dans une grille à
l'aide de Matplotlib, ce qui permet de vérifier visuellement le
contenu et la qualité du jeu de données. Cette étape est cruciale
pour nous assurer que les images sont correctement chargées et
prétraitées avant d'être utilisées dans les étapes ultérieures du
projet.

3. PARTITIONNER LES DONNÉES NON AUGMENTÉES


3.1 Diviser manuellement les données en ensembles
d'entraînement, de test et de validation

Dans cette étape, nous divisons manuellement notre jeu de


données en trois ensembles distincts : l'ensemble
d'entraînement, l'ensemble de test et l'ensemble de validation.
Pour un jeu de données de 30 images, nous allouons environ
70% (21 images) à l'entraînement, 15% (5 images) au test, et 15%
(4 images) à la validation. Cette répartition permet d'assurer
que notre modèle peut être évalué et testé de manière fiable,
en utilisant des données distinctes pour l'entraînement et la
validation.

3.2 Déplacer les labels correspondants

Ensuite, nous veillons à ce que les annotations (labels) des


images soient également correctement réparties dans les
dossiers respectifs. Pour chaque sous-dossier ('train', 'test', 'val'),
nous parcourons les fichiers image et identifions les fichiers
d'annotations correspondants (fichiers JSON) dans le dossier
'labels'. Si le fichier d'annotation existe, nous le déplaçons vers
le sous-dossier approprié en maintenant la structure de
répertoire cohérente. Cette étape est essentielle pour que les
ensembles d'entraînement, de test et de validation contiennent
à la fois les images et leurs annotations correspondantes,
assurant ainsi une formation et une évaluation précises du
modèle.
4. APPLIQUER L'AUGMENTATION D'IMAGES ET DE LABELS EN
UTILISANT ALBUMENTATIONS

4.1 Mettre en place le pipeline de transformation


Albumentations

Pour améliorer la robustesse et la généralisation de notre modèle,


nous appliquons des techniques d'augmentation d'images en
utilisant la bibliothèque Albumentations. Nous configurons un
pipeline de transformations comprenant plusieurs opérations :
recadrage aléatoire (RandomCrop), inversion horizontale
(HorizontalFlip), ajustement aléatoire de la luminosité et du
contraste (RandomBrightnessContrast), modification aléatoire de
la gamme (RandomGamma), décalage des couleurs (RGBShift), et
inversion verticale (VerticalFlip). Ces transformations sont
appliquées de manière aléatoire avec certaines probabilités
définies, ce qui permet de créer des variations artificielles de nos
images d'entraînement. Le paramètre bbox_params est utilisé pour
garantir que les transformations sont appliquées de manière
cohérente aux annotations des boîtes englobantes (bounding
boxes).
4.2 CHARGER UNE IMAGE DE TEST ET UNE ANNOTATION AVEC
OPENCV ET JSON

Pour tester notre pipeline de transformation, nous chargeons une


image d'entraînement et son annotation correspondante. Nous
utilisons OpenCV pour lire l'image à partir du chemin spécifié et la
bibliothèque JSON pour charger l'annotation. Cette annotation
contient des informations sur les objets dans l'image, notamment les
coordonnées des boîtes englobantes. En affichant les points des
boîtes englobantes, nous pouvons visualiser et vérifier les
annotations avant et après l'application des transformations. Cette
étape permet de s'assurer que les augmentations sont correctement
appliquées tant aux images qu'à leurs annotations, ce qui est crucial
pour l'intégrité des données d'entraînement du modèle.

4.3 Extraire les coordonnées et redimensionner pour


correspondre à la résolution de l'image

Dans cette étape, nous extrayons les coordonnées des boîtes


englobantes des annotations et les redimensionnons pour qu'elles
correspondent à la résolution de l'image. Nous commençons par
récupérer les coordonnées des points d'annotation et les stockons
dans une liste coords. Ensuite, nous divisons ces coordonnées par
les dimensions de l'image originale (640x480) pour normaliser les
valeurs entre 0 et 1. Cela nous permet de manipuler facilement les
annotations indépendamment de la taille de l'image et de les
adapter aux transformations appliquées.
5. CONSTRUIRE ET EXÉCUTER LE PIPELINE D'AUGMENTATION

5.1 EXÉCUTER LE PIPELINE D'AUGMENTATION

Cette étape met en œuvre le pipeline d'augmentation


d'images sur les ensembles de données de formation, de test
et de validation. Pour chaque partition, nous parcourons les
images et leurs annotations associées. Les coordonnées des
boîtes englobantes sont extraites et normalisées. Ensuite,
pour chaque image, nous appliquons une série de 60
augmentations en utilisant le pipeline défini précédemment
avec Albumentations. Les images augmentées et leurs
nouvelles annotations sont sauvegardées dans le répertoire
approprié. Si une annotation existe, les nouvelles boîtes
englobantes sont mises à jour en conséquence. Si aucune
boîte englobante n'est générée après augmentation, une
annotation par défaut est ajoutée. Cette procédure permet de
générer un ensemble de données étendu et diversifié,
essentiel pour améliorer la robustesse et la performance du
modèle de détection de visages en augmentant la variabilité
des images d'entraînement.
5.2 CHARGER LES IMAGES AUGMENTÉES DANS LE JEU DE
DONNÉES TENSORFLOW

Dans cette étape, nous chargeons les images augmentées dans des
jeux de données TensorFlow pour les ensembles d'entraînement,
de test et de validation. Nous commençons par lister les fichiers
d'images augmentées dans les répertoires respectifs
('aug_data/train/images', 'aug_data/test/images',
'aug_data/val/images') sans les mélanger pour préserver l'ordre.
Chaque image est ensuite chargée et redimensionnée à une taille
uniforme de 120x120 pixels pour garantir la cohérence des entrées
dans le réseau de neurones. Les valeurs des pixels sont normalisées
entre 0 et 1 en divisant par 255, ce qui est une pratique courante
pour améliorer la performance de l'entraînement des modèles.
Cette préparation des données permet de transformer les images
augmentées en un format adapté pour l'entraînement du modèle
dans TensorFlow, assurant une intégration fluide et efficace dans
le pipeline de machine learning.
6. PRÉPARER LES LABELS

6.1 CRÉER UNE FONCTION DE CHARGEMENT DES LABELS


Nous commençons par définir une fonction load_labels qui prend
en entrée le chemin d'un fichier d'annotation JSON. Cette fonction
ouvre le fichier, le lit et charge les données JSON. Elle renvoie les
classes des objets et les coordonnées des boîtes englobantes
(bounding boxes). Ce processus permet d'extraire les informations
nécessaires à partir des annotations pour chaque image
augmentée.

6.2 CHARGER LES LABELS DANS LE JEU DE DONNÉES


TENSORFLOW
Ensuite, nous chargeons les labels correspondants dans des jeux de
données TensorFlow pour les ensembles d'entraînement, de test et
de validation. Nous listons les fichiers d'annotations JSON dans les
répertoires appropriés sans les mélanger pour conserver l'ordre.
Chaque fichier d'annotation est ensuite chargé en utilisant la
fonction load_labels via tf.py_function, ce qui permet de traiter des
fonctions Python standard dans le contexte de TensorFlow. Les
labels sont extraits et ajoutés aux jeux de données, alignés avec les
images correspondantes.

Ces opérations garantissent que les labels sont correctement


chargés et associés à chaque image, facilitant ainsi l'entraînement
et la validation du modèle de détection de visages.
7. COMBINER LES ÉCHANTILLONS DE LABELS ET D'IMAGES

7.1 VÉRIFIER LES LONGUEURS DES PARTITIONS

Nous commençons par vérifier les longueurs des partitions des jeux
de données d'images et de labels pour nous assurer qu'ils sont
correctement appariés. Cette étape est essentielle pour garantir
que chaque image a une annotation correspondante.

7.2 CRÉER LES ENSEMBLES DE DONNÉES FINAUX


(IMAGES/LABELS)

Nous combinons les échantillons d'images et de labels en utilisant


tf.data.Dataset.zip, créant ainsi des ensembles de données qui
contiennent à la fois les images et leurs annotations
correspondantes. Nous appliquons ensuite un mélange (shuffle), un
découpage en lots (batch), et un préchargement (prefetch) pour
optimiser le pipeline de données.
7.3 VISUALISER LES IMAGES ET LES ANNOTATIONS

Pour vérifier visuellement les données augmentées et leurs


annotations, nous récupérons un lot d'échantillons du jeu de
données d'entraînement. Nous dessinons des rectangles autour des
boîtes englobantes sur les images et affichons ces images annotées
pour inspection.

Cette visualisation nous permet de confirmer que les


augmentations et les annotations sont correctement alignées et
que les boîtes englobantes sont précises. Cela assure que les
ensembles de données sont prêts pour l'entraînement du modèle
de détection de visages.
8. RECONNAISSANCE ET LOCALISATION MULTI-SORTIES -
DEEP LEARNING

Pour ce code, nous avons développé une architecture de modèle


de reconnaissance et de localisation de visages en utilisant le
réseau VGG16. Ce modèle est conçu pour traiter des images en
entrée de taille 120x120 pixels avec 3 canaux de couleur. La
première étape consiste à charger le modèle VGG16 pré-entraîné
sans la couche de classification supérieure.

Ensuite, le modèle est divisé en deux branches distinctes : une


pour la classification des visages et une autre pour la localisation
des boîtes englobantes des visages détectés. La branche de
classification utilise une couche de GlobalMaxPooling2D suivie de
couches denses pour extraire des caractéristiques et prédire la
présence d'un visage. D'autre part, la branche de localisation
utilise également une couche de GlobalMaxPooling2D suivie de
couches denses pour prédire les coordonnées des boîtes
englobantes des visages. Cette architecture combinée permet ainsi
de détecter et de localiser les visages dans une image donnée.
8.4 ENTRAÎNEMENT ET UTILISATION DE NOTRE MODEL
Après avoir instancié notre modèle à l'aide de la fonction
build_model(), un résumé de l'architecture du modèle est affiché à
l'aide de la méthode summary().

Ensuite, des données d'entraînement sont préparées à partir d'un


ensemble de données train, et un lot d'images est extrait pour être
utilisé dans l'entraînement du modèle. Les dimensions de ces
données sont confirmées avec X.shape. Enfin, le modèle est utilisé
pour prédire les classes et les coordonnées des boîtes englobantes
des visages dans les images données, résultant en deux tableaux
classes et coords.
9. CONFIGURATION DE L'ENTRAÎNEMENT ET DES FONCTIONS
DE PERTE

Pour configurer l'entraînement et définir les fonctions de perte


nécessaires à la détection et à la localisation de visages, ce code
commence par calculer le nombre de lots par époque, en fonction
de la longueur de l'ensemble d'entraînement train. Ensuite, un
taux de décroissance d'apprentissage est calculé pour ajuster
progressivement le taux d'apprentissage pendant l'entraînement.
L'optimiseur Adam est alors instancié avec un taux d'apprentissage
initial de 0,0001.

Deux fonctions de perte sont définies : classloss, qui utilise la perte


de classification binaire croisée, et regressloss, qui mesure la perte
de localisation en calculant la différence entre les coordonnées
prédites et les coordonnées réelles des boîtes englobantes des
visages. Enfin, des exemples de calcul de ces fonctions de perte
sont fournis pour évaluer la performance du modèle sur les
données d'entraînement.
10 ENTRAÎNEMENT ET VISUALISATION DES PERFORMANCES

Le modèle FaceTracker est conçu pour suivre les visages dans nos
images en utilisant le modèle eyetracker. Pour atteindre cet
objectif, on a définit une classe FaceTracker qui hérite de la classe
Model de TensorFlow. Cette classe comprend des méthodes pour la
compilation du modèle, la définition des étapes d'entraînement et
de test, ainsi que pour l'appel du modèle.
Dans la méthode compile, les fonctions de perte de
classification et de localisation, ainsi que l'optimiseur, sont
spécifiés. Les méthodes train_step et test_step sont
responsables du calcul des pertes de classification et de
localisation pour chaque lot d'entraînement ou de test
respectivement, tandis que la méthode call est utilisée pour
appeler le modèle.

Enfin, le modèle est instancié avec facetracker comme modèle


de suivi de visages, puis compilé avec les fonctions de perte et
l'optimiseur appropriés. Ce code fournit un cadre complet pour
l'entraînement et l'évaluation du modèle de suivi de visages, en
fournissant des métriques de performance telles que les pertes
totales, les pertes de classification et de localisation, visualisées
pour chaque époque d'entraînement.
11 PREDICTION AVEC LE RESEAU DE NEURONS

Ce morceau de code illustre la visualisation des résultats du suivi


de visages sur des échantillons de données de test. Après avoir
extrait un échantillon de données de test et prédit les classes et les
coordonnées des boîtes englobantes des visages à l'aide du modèle
facetracker, chaque image de l'échantillon est traitée
individuellement.

Pour chaque image, si la probabilité prédite de présence de visage


dépasse 0.9, un rectangle est dessiné autour du visage détecté, en
utilisant les coordonnées prédites. Ensuite, les images modifiées,
avec les rectangles dessinés, sont affichées dans une figure avec
quatre sous-graphiques, permettant ainsi de visualiser les
performances du modèle de suivi de visages sur différents
exemples de données de test.
11.3 SUIVI DE VISAGES EN TEMPS RÉEL AVEC LA WEBCAM

Ce script permet de réaliser le suivi de visages en temps réel à partir


d'une webcam. La boucle principale capture continuellement des
images de la webcam, extrait une région d'intérêt rectangulaire de
chaque image, puis redimensionne cette région à une taille de 120x120
pixels pour être compatible avec le modèle de suivi de visages. Le
modèle facetracker est utilisé pour prédire la présence de visages dans
chaque image réduite. Si un visage est détecté avec une probabilité
supérieure à 0,5, un rectangle bleu est dessiné autour du visage et un
label "face" est affiché au-dessus du rectangle.
Cette approche permet un suivi en temps réel des visages à l'aide de
la webcam, fournissant une application pratique pour la détection de
visages.

Vous aimerez peut-être aussi