Fermer

novembre 7, 2019

Détection et reconnaissance de visage avec Keras –


Si vous utilisez régulièrement Google Photos, vous avez peut-être remarqué comment l'application extrait et regroupe automatiquement les visages des personnes à partir des photos que vous sauvegardez sur le nuage.

 La reconnaissance des visages dans l'application Web Google Photos. Reconnaissance des visages dans l'application Web Google Photos

Une application photo telle que celle de Google parvient à ce résultat en détectant les visages des humains (et des animaux domestiques!) Sur vos photos, puis en regroupant des visages similaires. La détection, puis la classification des visages dans les images est une tâche courante dans l’apprentissage en profondeur avec des réseaux de neurones

Dans la première étape de ce didacticiel, nous utiliserons un modèle MTCNN pré-formé à Keras pour détecter les visages dans les images. Une fois que nous avons extrait les visages d'une image, nous calculons un score de similarité pour déterminer s'ils appartiennent à la même personne.

Conditions préalables

Avant de commencer à détecter et à reconnaître les visages, vous devez configurez votre environnement de développement. Tout d'abord, vous devez «lire» les images via Python avant de les traiter. Nous allons utiliser la bibliothèque de traçage matplotlib pour lire et manipuler des images. Installez la dernière version via l'installateur pip :

 pip3 installe matplotlib

Pour utiliser n'importe quelle implémentation d'un algorithme CNN, vous devez installer keras . Téléchargez et installez la dernière version à l'aide de la commande ci-dessous:

 pip3 install keras

L’algorithme que nous utiliserons pour la détection des visages est le MTCNN (Réseaux de neurones convergés multitâche), basé sur l’article Détection et alignement des faces articulaires à l’aide de réseaux convolutionnels en cascade multi-tâches (Zhang et al. ., 2016). Une implémentation de l'algorithme MTCNN pour TensorFlow en Python3.4 est disponible sous la forme d'un package . Exécutez la commande suivante pour installer le package via pip :

 pip3 install mtcnn

Pour comparer les visages après les avoir extraits d’images, nous allons utiliser l’algorithme VGGFace2 développé par le groupe de géométrie visuelle de l’Université d’Oxford. Une implémentation Keras basée sur TensorFlow de l'algorithme VGG est disponible sous la forme d'un package à installer:

 pip3 install keras_vggface

Vous ressentirez peut-être le besoin de construire et d’entraîner votre propre modèle, mais vous auriez besoin d’un vaste ensemble de données de formation et d’une grande puissance de traitement. Comme ce didacticiel porte sur l'utilité de ces modèles, il utilise des modèles existants, formés par des experts du domaine.

Maintenant que vous avez installé avec succès les conditions préalables, passons directement au didacticiel!

Étape 1: Visage Détection avec le modèle MTCNN

Les objectifs de cette étape sont les suivants:

  • récupérer des images hébergées de manière externe sur un serveur local
  • en lisant des images via par matplotlib de imread () function
  • détecter et explorer des visages grâce à l'algorithme MTCNN
  • extraire les visages d'une image.

1.1 Stocker les images externes

Vous effectuez souvent une analyse à partir d'images hébergées sur des serveurs externes. Pour cet exemple, nous allons utiliser deux images de Lee Iacocca, le père de la Mustang, hébergées sur les sites BBC et de Detroit News .

Pour stocker temporairement les images localement pour notre analyse, nous allons récupérer chacun de ses URL et l'écrire dans un fichier local. Définissons une fonction store_image à cette fin:

 import urllib.request

def store_image (url, nom_fichier_local):
  avec urllib.request.urlopen (url) comme ressource:
    avec open (nom_fichier_local, 'wb') en tant que f:
      f.write (resource.read ())

Vous pouvez maintenant appeler simplement la fonction avec l'URL et le fichier local dans lequel vous souhaitez stocker l'image:

 store_image ('https://ichef.bbci.co.uk/news/320/ cpsprodpb / 5944 / production / _107725822_55fd57ad-c509-4335-a7d2-bcc86e32be72.jpg ',
            'iacocca_1.jpg')
store_image ('https://www.gannett-cdn.com/presto/2019/07/03/PDTN/205798e7-9555-4245-99e1-fd300c50ce85-AP_080910055617.jpg?width=540&height=&fit=bounds&auto=webp',
            'iacocca_2.jpg')

Après avoir récupéré les images, détectons les visages

1.2 Détecter les visages dans une image

À cette fin, nous allons importer deux – matplotlib pour lire des images, et mtcnn pour la détection de visages dans les images:

 à partir de pyplot d'importation Matplotlib en tant que plt
à partir de mtcnn.mtcnn import MTCNN

Utilisez la fonction imread () pour lire une image:

 image = plt.imread ('iacocca_1.jpg')

Ensuite, initialisez un objet MTCNN () dans la variable du détecteur et utilisez la méthode .detect_faces () pour détecter les faces d'une image. Voyons ce qu’il retourne:

 détecteur = MTCNN ()

faces = detect.detect_faces (image)
pour le visage dans les visages:
    imprimer (visage)

Pour chaque visage, un dictionnaire Python contenant trois clés est renvoyé. La touche contient les limites du visage dans l'image. Il a quatre valeurs: les coordonnées x et y du sommet gauche supérieur, la largeur et la hauteur du rectangle contenant la face. Les autres clés sont clés de confiance et . La clé Keypoints contient un dictionnaire contenant les caractéristiques d'un visage détecté, ainsi que leurs coordonnées:

 {'box': [160, 40, 35, 44]'confidence': 0.9999798536300659, 'keypoints': { 'left_eye': (172, 57), 'right_eye': (188, 57), 'nez': (182, 64), 'mouth_left': (173, 73), 'mouth_right': (187, 73)} }

1.3 Mettre en surbrillance les visages dans une image

Maintenant que nous avons détecté un visage, dessinons un rectangle dessus pour le surligner afin de vérifier si la détection est correcte.

Pour dessiner un rectangle , importez l’objet Rectangle de matplotlib.patches :

 de matplotlib.patches import Rectangle

Définissons une fonction highlight_faces pour afficher d’abord l’image, puis dessiner des rectangles sur les visages détectés. Tout d’abord, lisez l’image par imread () et tracez-la dans imshow () . Pour chaque face détectée, tracez un rectangle à l'aide de la classe Rectangle () .

Enfin, affichez l'image et les rectangles à l'aide de la méthode .show () . Si vous utilisez des blocs-notes Jupyter, vous pouvez utiliser la commande magique % matplotlib inline pour afficher les tracés en ligne:

 def highlight_faces (chemin_image, faces):
  # afficher l'image
    image = plt.imread (chemin_image)
    plt.imshow (image)

    ax = plt.gca ()

    # pour chaque face, tracez un rectangle basé sur les coordonnées
    pour le visage dans les visages:
        x, y, largeur, hauteur = face ['box']
        face_border = Rectangle ((x, y), largeur, hauteur,
                          remplir = faux, couleur = 'rouge')
        ax.add_patch (face_border)
    plt.show ()

Affiche maintenant l’image et le visage détecté à l’aide de la fonction highlight_faces () :

 highlight_faces ('iacocca_1.jpg', faces)
 Visage détecté sur une image de Lee Iacocca Visage détecté sur une image de Lee Iacocca. Source: BBC

Affiche la deuxième image et le (s) visage (s) détecté (s):

 image = plt.imread ('iacocca_2.jpg')
faces = detect.detect_faces (image)

highlight_faces ('iacocca_2.jpg', visages)

Dans ces deux images, vous pouvez voir que l'algorithme MTCNN détecte correctement les visages. Extrayons maintenant ce visage de l’image pour effectuer une analyse plus poussée.

À ce stade, vous connaissez les coordonnées des visages provenant du détecteur. Extraire les visages est une tâche assez facile en utilisant des index de liste. Cependant, l'algorithme VGGFace2 que nous utilisons nécessite que les faces soient redimensionnées à 224 x 224 pixels. Nous allons utiliser la bibliothèque PIL pour redimensionner les images.

La fonction extract_face_from_image () extrait tous les visages d’une image:

 à partir de numpy import asarray.
de PIL import Image

def extract_face_from_image (image_path, required_size = (224, 224)):
  # charge l'image et détecte les visages
    image = plt.imread (chemin_image)
    détecteur = MTCNN ()
    faces = detect.detect_faces (image)

    face_images = []

    pour le visage dans les visages:
        # extraire le cadre de sélection de la face demandée
        x1, y1, largeur, hauteur = face ['box']
        x2, y2 = x1 + largeur, y1 + hauteur

        # extraire le visage
        face_boundary = image [y1:y2, x1:x2]

        # redimensionner les pixels à la taille du modèle
        face_image = Image.fromarray (face_boundary)
        face_image = face_image.resize (taille requise)
        face_array = asarray (face_image)
        face_images.append (face_array)

    retourner face_images

extract_face = extract_face_from_image ('iacocca_1.jpg')

# Affiche la première face des faces extraites
plt.imshow (extraite_face [0])
plt.show ()

Voici à quoi ressemble le visage extrait de la première image

 Visage extrait et redimensionné de la première image Visage extrait et redimensionné de la première image

Etape 2: Reconnaissance des visages avec le modèle VGGFace2

Dans cette section, testons d’abord le modèle sur les deux images de Lee Iacocca que nous avons récupérées. Nous passerons ensuite à la comparaison des visages à partir des images des onze de départ de l'équipe de football de Chelsea en 2018 et 2019. Vous pourrez ensuite déterminer si l'algorithme identifie les visages des joueurs communs entre les images.

2.1 Comparez deux visages

Dans cette section, vous devez importer trois modules: VGGFace pour préparer les visages extraits à utiliser dans les modèles de reconnaissance faciale et la fonction de cosinus de SciPy. calculer la distance entre deux faces:

 à partir de keras_vggface.utils import preprocess_input
à partir de keras_vggface.vggface import VGGFace
à partir de scipy.spatial.distance import cosinus

Définissons une fonction qui prend les faces extraites en entrée et renvoie les scores du modèle calculé. Le modèle renvoie un vecteur représentant les caractéristiques d'un visage:

 def get_model_scores (faces):
    échantillons = asarray (faces, 'float32')

    # prépare les données pour le modèle
    samples = preprocess_input (samples, version = 2)

    # créer un objet de modèle vggface
    model = VGGFace (model = 'resnet50',
      include_top = False,
      forme_entrée = (224, 224, 3),
      pooling = 'avg')

    # effectuer la prédiction
    retourne model.predict (samples)

visages = [extract_face_from_image(image_path)
         for image_path in ['iacocca_1.jpg', 'iacocca_2.jpg']]

model_scores = get_model_scores (faces)

Étant donné que les scores du modèle pour chaque face sont des vecteurs, nous devons rechercher la similarité entre les scores de deux faces. Nous pouvons généralement utiliser une fonction euclidienne ou Cosinus pour calculer la similarité.

La représentation vectorielle des visages est adaptée à la similitude des cosinus. Voici une comparaison détaillée entre cosinus et les distances euclidiennes avec un exemple .

La fonction cosinus () calcule la distance cosinus entre deux vecteurs. Plus ce nombre est bas, plus vos visages sont assortis. Dans notre cas, nous allons placer le seuil à 0,4 de distance. Ce seuil est discutable et pourrait varier selon votre cas d'utilisation. Vous devez définir ce seuil en fonction des études de cas de votre jeu de données:

 si cosinus (model_scores [0]model_scores [1]) <= 0.4:
  print ("Faces Matched")

En l'espèce, les deux visages de Lee Iacocca étaient identiques.

 Faces Matched

2.2 Comparer plusieurs visages dans deux images

Utilisons le modèle à bon escient dans cette section du didacticiel. Nous comparerons les visages dans deux images des onze de départ du club de football de Chelsea dans un match de la Ligue européenne contre Slavia Prague lors de la saison 2018-19 et du match de la Super Coupe de l'UEFA contre Liverpool ] dans la saison 2019-2020. Bien que de nombreux joueurs soient présents dans les deux équipes de match, voyons si l'algorithme est capable de détecter tous les joueurs communs.

Premièrement, récupérons les ressources des URL, détectons les visages dans chaque image et les surlignent: [19659026] store_image ('https://cdn.vox-cdn.com/thumbor/Ua2BXGAhneJHLQmLvj-ZzILK-Xs=/0xx:4872×3160/1820×1213/filters:focal (1877×860: 2655×1660) / format (webp) .com / uploads / chorus_image / image / 63613936 / 1143553317.jpg.5.jpg ',
            'chelsea_1.jpg')

image = plt.imread ('chelsea_1.jpg')
faces_staring_xi = détecteur.detect_faces (image)

highlight_faces ('chelsea_1.jpg', faces_staring_xi)

store_image ('https://cdn.vox-cdn.com/thumbor/mT3JHQtZIyInU8_uGxVH-TCbF50=/0x415:5000×2794/1820×1213/filters: Focal (1878×1176: 2678×1976): format (webp) / cdnd uploads / chorus_image / image / 65171515 / 1161847141.jpg.0.jpg ',
            'chelsea_2.jpg')

image = plt.imread ('chelsea_2.jpg')
faces = detect.detect_faces (image)

highlight_faces ('chelsea_2.jpg', visages)

Avant d’aller plus loin, voici les onze de départ des deux matches:

Nous avons huit joueurs qui sont communs à Les deux XIs de départ et ceux qui, idéalement, devraient correspondre à l'algorithme.

Commençons par calculer les scores:

 slavia_faces = extract_face_from_image ('chelsea_1.jpg')
liverpool_faces = extract_face_from_image ('chelsea_2.jpg')

model_scores_starting_xi_slavia = get_model_scores (slavia_faces)
model_scores_starting_xi_liverpool = get_model_scores (liverpool_faces)
``
pour idx, face_score_1 dans enumerate (model_scores_starting_xi_slavia):
  pour idy, face_score_2 dans enumerate (model_scores_starting_xi_liverpool):
    score = cosinus (face_score_1, face_score_2)
    si score <= 0.4:
      # Impression des identifiants de visages et de partitions
      print (idx, idy, score)
      # Affichage de chaque paire de visages appariés
      plt.imshow (slavia_faces [idx])
      plt.show ()
      plt.imshow (liverpool_faces [idy])
      plt.show ()

Voici la liste des paires de faces auxquelles l’algorithme a correspondu. Notez qu'il a pu faire correspondre les huit paires de visages.

 Huit visages correctement reconnus Huit visages correctement reconnus (Kepa, Azpilicueta, Emerson, Giroud, Kante, Pedro, Christensen et Kovacic)

ont réussi à faire correspondre chaque visage dans nos images, je voudrais revenir en arrière pour discuter des ramifications des partitions. Comme indiqué plus haut, il n’existe pas de seuil universel permettant de faire correspondre deux images. Vous devrez peut-être redéfinir ces seuils avec de nouvelles données entrant dans l'analyse. Par exemple, même Google Photos utilise vos entrées lorsqu'il est impossible de déterminer par programmation le meilleur seuil pour une paire.

 Google Photos prenant des entrées d'utilisateur pour la correspondance des visages Google Photos prenant des entrées d'utilisateur pour la correspondance des visages

. Il est important d’évaluer soigneusement les cas lorsqu’on compare différents types de visage. Les émotions des visages et de leurs angles jouent également un rôle dans la précision. Dans notre cas d’utilisation, remarquez que j’ai délibérément utilisé des photos de joueurs à partir de onze alors que les joueurs regardaient droit dans la caméra! Vous pouvez essayer de faire correspondre les onze de départ avec ceux d'une célébration de trophée et je suis à peu près sûr que la précision baissera.

Conclusion

Dans ce didacticiel, nous avons d'abord détecté des visages dans des images à l'aide du modèle MTCNN et les avons mis en évidence dans les images pour déterminer si le modèle fonctionnait correctement. Nous avons ensuite utilisé l'algorithme VGGFace2 pour extraire les caractéristiques des visages sous la forme d'un vecteur et apparié différents visages pour les regrouper.

Utilisez-vous un algorithme différent pour détecter et faire correspondre les visages? Faites-moi savoir sur Twitter !






Source link