====== Note pour la conception d'un atelier sur la « reconnaissance faciale » ======
**Reconnaissance de visage et 68 points de structures faciales sur le visage**
===== Objetifs de cette note =====
* préparer les avant-besoins techniques
* tester un module en ''python'' de longueur raisonnable
* Avancer vers un atelier large publique
* Avec découverte et initiation à la programmation
* Pour mieux comprendre les enjeux
* Mise en oœuvre du //travail du clic//
* Tests avancés sur la subjectivation
* reco faciale
* Capture de l'intimité
* Risques bio-morphologiques
* Mise en conception et tests de stratégie d'auto-défense et de libertés
===== Support tech =====
==== Python et 68 points de contrôle du visage ====
en utilisant ''[[https://github.com/davisking/dlib|dlib]]'', qui contient de base de [[https://github.com/davisking/dlib/tree/master/python_examples|nombreux exemples]] de reconnaissance d'objet avec le langage ''python''.
En suivant la majoration de [[https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/|68 points Multi-PIE]], Pose, Illumination, and Expression Database.
> « //Il existe une relation étroite entre l'avancement des algorithmes de reconnaissance faciale et la disponibilité de bases de données sur les visages, facteurs variables qui affectent l'apparence du visage d'une manière contrôlée. La base de données CMU PIE a été très influente dans l'avancement de la recherche sur la reconnaissance faciale à travers la pose et l'illumination. Malgré son succès, la base de données PIE présente plusieurs lacunes : un nombre limité de sujets, une seule session d'enregistrement et seulement quelques expressions capturées. Pour répondre à ces questions, nous avons collecté la base de données CMU Multi-PIE. Il contient 337 sujets, photographiés sous 15 points de vue et 19 conditions d'éclairage dans un maximum de quatre séances d'enregistrement. Dans cet article, nous présentons la base de données et décrivons la procédure d'enregistrement. Nous présentons en outre les résultats d'expériences de base utilisant des classificateurs PCA et LDA pour mettre en évidence les similitudes et les différences entre PIE et Multi-PIE.// » [[https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2873597|Multi PIE]], nbci, 2009, Ralph Gross, Iain Matthews, Jeff Cohn, Takeo Kanade, and Simon Baker
{{ figure_68_markup.jpg?300 }}
Avec l'aide d' ''[[https://breakthrough.github.io/Installing-OpenCV|OpenCV]]''
==== Pré-requis ====
* python 3
* Dlib
* Cmake
* [[https://github.com/jrosebr1/imutils|Imutils]]
* argparse
===== 4 étapes de construction du code =====
==== 2 objectifs ====
Pour //ficher// un ou plusieurs visages nous devons résoudre 2 procédés logiques
* **procédé 1**: Localiser le visage dans une image
* c’est-à-dire les coordonnées (x, y) du visage dans l’image
* **procédé 2**: Détecter les principales structures faciales sur un visage
* localiser puis étiqueter les régions faciales suivantes :
* Bouche
* Sourcil droit
* Sourcil gauche
* L'œil droit
* Oeil gauche
* Nez
* Mâchoire
=== Contraintes ===
Nous essayons de respecter 2 contraintes :
- Coder ce que nous documentons et non l'inverse
- Rester sous les 50 lignes de code pour cette approche simplifiée et pédagogique
==== Initialiser la démarche ====
nous importons ce dont nous avons besoin :
* imutils pour simplifier les fonctions de traitement d'images
* argparse permet d'écrire facilement des interfaces de ligne de commande
* ''-i'' ou ''--image'' en chemin d'accès à l'image d'entrée sur laquelle nous voulons détecter les points de repère
* cv2 depuis OpenCv
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""delacroix.py
A piece of python for citizen research on freedoms and bio/morphological risks
by XavCC
GNU GENERAL PUBLIC LICENSE Version 3
"""
import argparse
from imutils import face_utils
import imutils
import cv2
import dlib
# build argument parser and analyze arguments
bap = argparse.ArgumentParser()
bap.add_argument('-i', '--image', required=True, help='path to the input image')
args = vars(bap.parse_args())
# initialize the dlib face detector
# (using histogram of oriented gradients HOG)
detector = dlib.get_frontal_face_detector()
# directory of shapes
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
''Detector'' : initialise le détecteur de visage pré-entraîné de ''dlib'' en se basant sur une modification de la méthode [[https://www.learnopencv.com/histogram-of-oriented-gradients/|Histogram of Gradients Oriented]] et [[https://pythonprogramming.net/linear-svc-example-scikit-learn-svm-python/|Linear SVM]] pour la détection d’objets.
''Predictor'' : le répertoire nécessaire pour modèle pré-établi de détection de point de repères, disponible ici
==== Détecter un visage ====
nous visons à :
* charger notre image d'entrée à partir de notre appareil de travail via ''OpenCV''
* pré-traiter l'image en la redimensionnant pour avoir une largeur de 600 pixels
* convertir en niveaux de gris, démarche similaire lors de l'[[atelier:faceblind_facial_reco#python_et_reconnaissance_faciale_automatisee|atelier fdln]]
Nous ajoutons donc à la suite le code suivant :
# load image as input, resize and convert to grayscale
image = cv2.imread(args['image'])
image = imutils.resize(image, width=900)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # detect face
rects = detector(gray, 1)
Le premier paramètre du ''detector'' est notre image envoyée avec niveaux de gris.
Puis le choix opéré de la résolution de l’image d’entrée ''(image, width=900)'':
- avant la détection des visages = avantage de nous permettre de détecter plus de visages
- plus la taille de l’image d’entrée est grande, plus le processus de détection est vorace en demande de puissance de calcul
Le deuxième paramètre est le nombre de couches de [[https://docs.opencv.org/3.4/d4/d1f/tutorial_pyramids.html|pyramide d'image via OpenCV]] à appliquer lors de la mise à l'échelle de l'image avant l'application du détecteur.
* {{rca84.pdf|méthodes pyramidales}} dans le traitement des images
Nous pouvons ensuite demander le détecttion de visage.
==== Détecter les repères faciaux ====
À la suite de notre prédent morceau de code, nous lançons la détection de repères faciaux sur les visages trouvés - par conversion de l'objet de forme provenant de''Dlib'' en un ''array'' provenant de ''[[https://www.numpy.org/|NumPy]]''.
Puis nous amroçons une boucle sur chacune des détections de visage, sur chaune nous appliquons la détection de repères faciaux, ce qui nous donne les 68 coordonnées (x, y) qui correspondent aux caractéristiques faciales spécifiques.
# For each face detected search for marks
for (i, rect) in enumerate(rects):
# determine facial landmarks for the face region, then
# convert the facial landmark (x, y) into a NumPy array
shape = predictor(gray, rect)
shape = face_utils.shape_to_np(shape)
# convert the Dlib rectangle into an OpenCV style selection frame
# draw the selection frame
(x, y, w, h) = face_utils.rect_to_bb(rect)
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 1)
# loop on the coordinates (x, y) for facial landmarks
# and draw them on picture
for (x, y) in shape:
cv2.circle(image, (x, y), 1, (0, 0, 255), -1)
# display output image with face detection and face markers
cv2.imshow('Output', image)
cv2.waitKey(0)
Enfin nous :
* dessinons le cadre en vert de sélection entourant le visage détecté sur l'image
* créons un boucle sur les repères du visage détectés et dessinez chacun d'eux individuellement.
* affichons simplement l'image de sortie sur notre écran.
==== Tester le code ====
Notre code final est
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""delacroix.py
A piece of python for citizen research on freedoms and bio/morphological risks
by XavCC
GNU GENERAL PUBLIC LICENSE Version 3
"""
import argparse
from imutils import face_utils
import imutils
import cv2
import dlib
# build argument parser and analyze arguments
bap = argparse.ArgumentParser()
bap.add_argument('-i', '--image', required=True, help='path to the input image')
args = vars(bap.parse_args())
# initialize the dlib face detector
# (using histogram of oriented gradients HOG)
detector = dlib.get_frontal_face_detector()
# directory of shapes
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
# load image as input, resize and convert to grayscale
image = cv2.imread(args['image'])
image = imutils.resize(image, width=600)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # detect face
rects = detector(gray, 1)
# For each face detected search for marks
for (i, rect) in enumerate(rects):
# determine facial landmarks for the face region, then
# convert the facial landmark (x, y) into a NumPy array
shape = predictor(gray, rect)
shape = face_utils.shape_to_np(shape)
# convert the Dlib rectangle into an OpenCV style selection frame
# draw the selection frame
(x, y, w, h) = face_utils.rect_to_bb(rect)
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 1)
# loop on the coordinates (x, y) for facial landmarks
# and draw them on picture
for (x, y) in shape:
cv2.circle(image, (x, y), 1, (0, 0, 255), -1)
# display output image with face detection with face markers
cv2.imshow('Output', image)
cv2.waitKey(0)
Vérifions l'état de l'art de notre code, sachant que :
* Pylint importe des modules pour identifier efficacement les méthodes et attributs valides. Il a été décidé que l'importation d'extensions ''c'' qui ne font pas partie de la stdlib python est un risque de sécurité et pourrait introduire du code malveillant((ref:https://mail.python.org/pipermail/code-quality/2014-November/000394.html)).
- Désactiver la sécurité en utilisant l'option ''--unsafe-load-any-extension=y'' en ligne de commande. Cette fonctionnalité n'est pas documentée et est classée comme une option cachée (https://mail.python.org/pipermail/code-quality/2014-November/000439.html).
- Désactiver la sécurité en utilisant le paramètre ''pylint.rc'', ''unsafe-load-any-extensions=yes''. Ceci est recommandé par rapport à l'option 1 et inclut la documentation complète dans le fichier ''pylint.rc'' par défaut (créé avec ''--generate-rcfile'').
- Énumérer spécifiquement les noms de paquets ou de modules dont vous pensez qu'ils seront chargés par pylint dans le fichier ''pylint.rc'' en utilisant l'option ''extension-pkg-whitelist=''.
pylint --const-rgx='[a-z\_][a-z0-9\_]{2,30}$' delacroix.py --extension-pkg-whitelist=cv2
************* Module delacroix
delacroix.py:22:11: I1101: Module 'dlib' has no 'get_frontal_face_detector' member, but source is unavailable. Consider adding this module to extension-pkg-whitelist if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member)
delacroix.py:24:12: I1101: Module 'dlib' has no 'shape_predictor' member, but source is unavailable. Consider adding this module to extension-pkg-whitelist if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member)
-------------------------------------------------------------------
Your code has been rated at 10.00/10
Testons maintenant sur une image de grève, par exemple en Inde, que nous nommerons ''india.jpg''
$ python3 delacroix.py -i india.jpg
{{ indian_strike.png }}
Et que se passe t'il maintenant si « La liberté guidant le peuple » était mise sous //reconnaissance faciale//
{{ fucked_freedom_delacroix.png }}
===== Méthode d'atelier =====
- intro rapide, aka //spitch par l'animatrice ou animateur en moins de 5 minutes//
- 2 × 1h de code avec tests de variations et usages d'images photos et vidéo [[https://xavcc.frama.io/geek-bretagne/|pair à pair]] ou mob programming
- 40 minutes de [[https://xavcc.frama.io/casper-sudweb-2018/|cercle samoan]] sur les apprentissages, enjeux induits et piste d'autodéfense
- 1h de pratiques et tests d'autodéfense et documentation
- 5 minutes de clôture pour aller vers un [[wp>World_café]]
====== Pages liées ======
* [[bioprivacy_note-morpho-face-1|Note sur la reconnaissance faciale - Janvier 2019]]
* [[atelier:digital_labor_et_surveillance|Atelier sur le « travail du clic et la surveillance généralisée »]]
* Jeudi 7 février, [[/atelier:faceblind_facial_reco|Atelier reconnaissance faciale et morphologique de masse]], festival des libertés numériques 2019, Bibliotèque INSA de Rennes
====== Ressources externes ======
* LINC Cnil, Elodie Lemaire : « [[https://linc.cnil.fr/fr/elodie-lemaire-la-videosurveillance-nest-pas-une-preuve-ideale|La vidéosurveillance n’est pas une preuve idéale]] »
* Alain Damsio à Rennes au sujet des « [[https://www.c-lab.fr/article/vie-etudiante/alain-damasio-emporte-le-tambour.html|Furtifs]] »
* [[https://www.superdatascience.com/blogs/opencv-face-detection|OpenCv Face Detection]]
* [[https://github.com/ageitgey/face_recognition|Face recognition]]
* [[https://www.paulvangent.com/2016/08/05/emotion-recognition-using-facial-landmarks/|Emotion Recognition using Facial Landmarks, Python, DLib and OpenCV]]