[PYTHON] Estimer qui est le visage en utilisant OpenCV (Eigenface, Fisherface, LBPH)

Estimation du visage avec OpenCV

La dernière fois, j'ai extrait la zone du visage en utilisant un classificateur de caractéristiques de type Haar (Reconnaissance de visage utilisant OpenCV (classificateur de caractéristiques de type Haar). ). Cette fois, en tant qu'application, l'image du visage extraite par le classificateur d'entités de type Haar a été formée par l'estimateur de visage OpenCV (Eigenface, Fisherface, LBPH), et il y avait des différences dans les expressions faciales, le déguisement et les conditions d'éclairage. Devinons qui est le visage non appris

L'algorithme d'estimation de visage installé dans OpenCV est le suivant. (Cliquez ici pour plus de détails)

  1. Préparez une image pour l'entraînement (mêmes conditions d'éclairage, mise à l'échelle à la position des yeux et du nez, même résolution).

  2. Calculez la moyenne des images d'entraînement et soustrayez l'image moyenne de chaque image.

  3. Calculez la matrice de covariance de l'image soustraite.

  4. Calculez le vecteur propre et la valeur propre à partir de la matrice de covariance.

  5. Sélectionnez le composant principal.

    eigenfaces_opencv.png

Cette fois, nous reconnaîtrons le visage, mais ces algorithmes sont également appliqués à l'évaluation de l'écriture manuscrite, au traitement d'images médicales et à la lecture labiale. Dans un endroit intéressant, il est possible d'identifier la personne déguisée.

OpenCV OpenCV (Open Source Computer Vision Library) est une collection de bibliothèques de traitement vidéo / image sous licence BSD. Il existe de nombreux algorithmes tels que le filtrage d'image, la correspondance de modèles, la reconnaissance d'objets, l'analyse vidéo et l'apprentissage automatique.

■ Exemple de suivi de mouvement avec OpenCV (OpenCV Google Summer of Code 2015) https://www.youtube.com/watch?v=OUbUFn71S4s

■ Cliquez ici pour une installation et une utilisation facile Installer OpenCV 3 (core + contrib) dans l'environnement Python 3 & Différence entre OpenCV 2 et OpenCV 3 & Easy operation check ★ La méthode predict () ne fonctionnait pas comme prévu dans le module face de opencv_contrib dans OpenCV 3.1. Cette fois, OpenCV 2 est installé sur Anaconda 2 et le programme suivant est en cours d'exécution.

■ Cliquez ici pour le traitement des images fixes Essayez la détection des bords avec OpenCV Effectuer divers filtres avec OpenCV (Gradient, Highpass, Laplacian, Gaussian) Extraire des points caractéristiques avec OpenCV (AgastFeature, FAST, GFTT, MSER, AKAZE, BRISK, KAZE, ORB, SimpleBlob) Reconnaissance faciale à l'aide d'OpenCV (classificateur de caractéristiques de type Haar)

■ Cliquez ici pour le traitement vidéo Essayez de convertir des vidéos en temps réel avec OpenCV Essayez de convertir des vidéos de caméra Web / caméra vidéo en temps réel avec OpenCV Dessinez un flux optique en temps réel avec OpenCV (méthode Shi-Tomasi, méthode Lucas-Kanade) Suivi d'objets à l'aide d'OpenCV (suivi des points caractéristiques spécifiés par la souris par la méthode Lucas-Kanade Analyse de modèles de mouvement à l'aide d'OpenCV (reconnaissance des objets et de leurs directions de déplacement en temps réel)

Base de données des visages

Présentation de la base de données de visages souvent utilisée dans le traitement d'images.

Cette fois, nous utiliserons la base de données des visages de Yale (visages de Yale).

Données d'entraînement et données de test

Yalefaces contient 15 visages faciaux différents. Chaque personne a un visage normal, un visage portant des lunettes, un visage heureux, un visage clignotant, un visage triste, un visage triste, un visage surpris et une lumière de droite / gauche. J'ai un visage. Le cas échéant, extrayez n'importe quelle image du visage de l'image du visage de chaque personne à des fins de test (n'incluez pas l'image de test dans l'image de formation). Cette fois, j'ai stocké les images d'entraînement dans le répertoire yalefaces et les images de test dans le répertoire test.

trainingdata.png Visages avec diverses expressions

programme

Le déroulement du programme est le suivant.

  1. Chargez l'image d'entraînement
  2. Extrayez la zone du visage à l'aide du classificateur d'objets de type Haar
  3. Redimensionner la zone du visage à une certaine taille
  4. Entraînez les images et les étiquettes en tant que données d'entraînement avec FaceRecognizer (train ())
  5. Répétez les étapes 1 à 4 pour toutes les images d'entraînement
  6. Chargez l'image de test
  7. Extraire la zone du visage à l'aide du classificateur d'entités de type Haar
  8. Redimensionner la zone du visage à une certaine taille
  9. Prédiction de l'image de test avec FaceRecognizer (prédire ()) ⇒ [Libellé, Précision]
  10. Répétez 6-9 pour toutes les images de test

Il y a quelques points dans le programme.

face_predict.py


#!/usr/bin/python
# -*- coding: utf-8 -*-

import cv2, os
import numpy as np
from PIL import Image

#Image de formation
train_path = './yalefaces'

#Image de test
test_path = './test'

# Haar-comme classificateur d'entités
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath)

#Créer un outil de reconnaissance de visage pour OpenCV 2
#* Dans OpenCV3, FaceRecognizer est cv2.Ce sera un module de visage
# EigenFace
#recognizer = cv2.createEigenFaceRecognizer()
# FisherFace
#recognizer = cv2.createFisherFaceRecognizer()
# LBPH
recognizer = cv2.createLBPHFaceRecognizer()

#Récupère l'image dans le chemin spécifié
def get_images_and_labels(path):
    #Tableau pour stocker des images
    images = []
    #Tableau pour stocker les étiquettes
    labels = []
    #Tableau pour stocker les noms de fichiers
    files = []
    for f in os.listdir(path):
        #Chemin de l'image
        image_path = os.path.join(path, f)
        #Charger l'image en échelle de gris
        image_pil = Image.open(image_path).convert('L')
        #Stocké dans un tableau de NumPy
        image = np.array(image_pil, 'uint8')
        # Haar-comme Détecter le visage avec le classificateur d'entités
        faces = faceCascade.detectMultiScale(image)
        #Traitement de l'image du visage détecté
        for (x, y, w, h) in faces:
            #Redimensionner le visage à une taille de 200 x 200
            roi = cv2.resize(image[y: y + h, x: x + w], (200, 200), interpolation=cv2.INTER_LINEAR)
            #Stocker des images dans un tableau
            images.append(roi)
            #Obtenir l'étiquette du nom de fichier
            labels.append(int(f[7:9]))
            #Stocker les noms de fichiers dans un tableau
            files.append(f)

    return images, labels, files


#Obtenir l'image de la formation
images, labels, files = get_images_and_labels(train_path)

#Mise en œuvre de la formation
recognizer.train(images, np.array(labels))

#Obtenir une image de test
test_images, test_labels, test_files = get_images_and_labels(test_path)

i = 0
while i < len(test_labels):
    #Implémentation de la prédiction pour les images de test
    label, confidence = recognizer.predict(test_images[i])
    #Sortie des résultats de prédiction vers la console
    print("Test Image: {}, Predicted Label: {}, Confidence: {}".format(test_files[i], label, confidence))
    #Afficher l'image de test
    cv2.imshow("test image", test_images[i])
    cv2.waitKey(300)
    
    i += 1

#Terminer le traitement
cv2.destroyAllWindows()

Ce programme fonctionnait sur Python 2.7.12 et OpenCV 2.4.13. Lors de l'exécution avec Python 3 et OpenCV 3, changez la partie FaceRecognizer du programme de «cv2» à «cv2.face». De plus, dans OpenCV 3.1, la méthode Predict () de FaceRecognizer ne fonctionne pas comme prévu. Pour plus de détails, reportez-vous à Différences entre OpenCV2 et OpenCV3 & etc. ⇒ Certaines méthodes ne fonctionnent pas en raison de bogues.

Résultat d'exécution

La formation est exécutée en définissant la partie «XX» de subjectXX comme valeur numérique dans l'étiquette. L'étiquette correcte (étiquette prédite) peut être estimée pour l'image de test (image).

Lorsqu'elle est estimée avec Eigenface, l'estimation de l'étiquette liée à la lumière = 5, 6, 8, 9 a échoué et d'autres estimations ont réussi.

Test Image: subject01.happy, Predicted Label: 1, Confidence: 4383.25505059
Test Image: subject02.wink, Predicted Label: 2, Confidence: 6947.75053221
Test Image: subject03.happy, Predicted Label: 3, Confidence: 4145.80848328
Test Image: subject04.glasses, Predicted Label: 4, Confidence: 5420.9213318
Test Image: subject05.leftlight, Predicted Label: 12, Confidence: 7722.72936213
Test Image: subject06.leftlight, Predicted Label: 1, Confidence: 10086.4101755
Test Image: subject07.glasses, Predicted Label: 7, Confidence: 7043.70495967
Test Image: subject08.leftlight, Predicted Label: 2, Confidence: 10275.9545456
Test Image: subject09.rightlight, Predicted Label: 15, Confidence: 7481.31094502
Test Image: subject10.sleepy, Predicted Label: 10, Confidence: 2317.22633915
Test Image: subject11.centerlight, Predicted Label: 11, Confidence: 8077.42380817
Test Image: subject12.glasses, Predicted Label: 12, Confidence: 5233.03342586
Test Image: subject13.surprised, Predicted Label: 13, Confidence: 6516.98395617
Test Image: subject14.normal, Predicted Label: 14, Confidence: 0.0
Test Image: subject15.surprised, Predicted Label: 15, Confidence: 7165.71597327

Quand je l'ai estimé avec Fisherface, toutes les estimations étaient réussies.

Test Image: subject01.happy, Predicted Label: 1, Confidence: 801.784987691
Test Image: subject02.wink, Predicted Label: 2, Confidence: 2368.90429845
Test Image: subject03.happy, Predicted Label: 3, Confidence: 826.018934498
Test Image: subject04.glasses, Predicted Label: 4, Confidence: 1080.94198758
Test Image: subject05.leftlight, Predicted Label: 5, Confidence: 2137.42013849
Test Image: subject06.leftlight, Predicted Label: 6, Confidence: 2092.53092982
Test Image: subject07.glasses, Predicted Label: 7, Confidence: 2042.67529443
Test Image: subject08.leftlight, Predicted Label: 8, Confidence: 2239.45348941
Test Image: subject09.rightlight, Predicted Label: 9, Confidence: 2875.2788263
Test Image: subject10.sleepy, Predicted Label: 10, Confidence: 662.762591569
Test Image: subject11.centerlight, Predicted Label: 11, Confidence: 1703.80515728
Test Image: subject12.glasses, Predicted Label: 12, Confidence: 1480.18770297
Test Image: subject13.surprised, Predicted Label: 13, Confidence: 1690.12255703
Test Image: subject14.normal, Predicted Label: 14, Confidence: 0.0
Test Image: subject15.surprised, Predicted Label: 15, Confidence: 1887.42538269

Lorsqu'elle est estimée par LBPH, l'estimation de l'étiquette liée à la lumière = 6, 9 a échoué. D'autres ont réussi.

Test Image: subject01.happy, Predicted Label: 1, Confidence: 34.9751422497
Test Image: subject02.wink, Predicted Label: 2, Confidence: 37.8730262399
Test Image: subject03.happy, Predicted Label: 3, Confidence: 35.1183059319
Test Image: subject04.glasses, Predicted Label: 4, Confidence: 37.5886492389
Test Image: subject05.leftlight, Predicted Label: 5, Confidence: 48.2634869014
Test Image: subject06.leftlight, Predicted Label: 14, Confidence: 64.5502245279
Test Image: subject07.glasses, Predicted Label: 7, Confidence: 54.5043891288
Test Image: subject08.leftlight, Predicted Label: 8, Confidence: 84.4281976817
Test Image: subject09.rightlight, Predicted Label: 12, Confidence: 75.3254674542
Test Image: subject10.sleepy, Predicted Label: 10, Confidence: 17.8806440153
Test Image: subject11.centerlight, Predicted Label: 11, Confidence: 74.8238311755
Test Image: subject12.glasses, Predicted Label: 12, Confidence: 31.8721301084
Test Image: subject13.surprised, Predicted Label: 13, Confidence: 40.3420527188
Test Image: subject14.normal, Predicted Label: 14, Confidence: 0.0
Test Image: subject15.surprised, Predicted Label: 15, Confidence: 33.2920487407

Le résultat de la comparaison des trois algorithmes montre que la Fisherface est moins sensible à la lumière, comme cela a été dit précédemment. De plus, puisque le succès et l'échec de l'estimation correspondaient dans une certaine mesure à la valeur de la confiance, il semblait bon de fixer un seuil de confiance et de classer les résultats d'estimation non fiables en éléments non estimables.

(Bonus) Image GIF → Conversion d'image PNG

OpenCV ne prend pas en charge les images GIF pour éviter les problèmes de brevet. La lecture d'une image GIF avec cv2.imread () ne lit rien. Si vous souhaitez utiliser Yalefaces, une base de données d'images de visage au format GIF, avec OpenCV, il est pratique de la convertir à l'avance en image de visage au format PNG avec le script suivant. Le script ci-dessous convertit l'image GIF du répertoire "yalefaces" en image PNG et l'enregistre dans le répertoire "png". Si vous en avez besoin, veuillez utiliser le script ci-dessous.

gif2png.py


# -*- coding: utf-8 -*-

import os
from PIL import Image
import shutil

#Répertoire contenant les fichiers à convertir
org_dir = 'yalefaces'
#Extension du fichier à convertir
org_ext = 'gif'
#Répertoire pour stocker le fichier converti
conv_dir = 'png'
#Extension de fichier converti
conv_ext = 'png'

#Supprimer les répertoires existants, y compris les fichiers
if os.path.exists(conv_dir):
    shutil.rmtree(conv_dir)
#Créer un annuaire
os.mkdir(conv_dir)

# 「.Longueur de la chaîne de caractères avec l'extension
org_ext_len = len(org_ext) + 1

for dirname, dirnames, filenames in os.walk(org_dir):
    for filename in filenames:
        #Chemin du fichier à convertir
        org_path = org_dir + '/' + filename

        #Chemin du fichier après retour
        if len(filename) > org_ext_len and \
            filename[-org_ext_len:] == '.' + org_ext:
            filename = filename[0:-org_ext_len]
        conv_path = conv_dir + '/' + filename + '.' + conv_ext

        try:
            #Convertir l'exécution
            Image.open(org_path).save(conv_path)
        except IOError:
            print('cannot convert :', org_path)

Si vous n'avez pas installé la bibliothèque de traitement d'image Python et le module PIL, veuillez installer l'oreiller. Exemple)

$ conda install pillow

Recommended Posts

Estimer qui est le visage en utilisant OpenCV (Eigenface, Fisherface, LBPH)
Reconnaissance faciale à l'aide d'OpenCV (classificateur de caractéristiques de type Haar)