Mauvais message pour utiliser "animeface-2009" en Python et implémentation de la fonction pour générer un fichier XML au format PASCAL VOC

animeface2009_and_python.png

Si vous souhaitez détecter le visage d'un personnage à partir d'une image animée en Python, utilisez lbpcascade_animeface implémenté par nagadomi. Je vois souvent des cas. Cette lbpcascade_animeface est un module qui estime la boîte englobante d'un visage.

De plus, le module animeface-2009 implémenté par nagadomi mentionné ci-dessus n'est pas seulement le visage, mais aussi les parties du visage (yeux, nez, bouche, La boîte englobante du menton) est également détectable [^ 1]. Cependant, seul Ruby fournit ici une API de niveau de liaison. D'après README.md de lbpcascade_animeface, il est écrit que" la précision de détection est plus élevée dans ʻanimeface-2009` ". Par conséquent, je veux vraiment l'utiliser en Python.

[^ 1]: Cependant, la zone de délimitation sur le nez et le menton est de 1 x 1 pixels, il est donc préférable de l'appeler un point de repère.

Fonction à appeler "animeface-2009" depuis Python

Le dépôt Git de celui implémenté cette fois est ici.

La réécriture du code C implémenté pour Ruby pour Python n'est pas une tâche facile pour un putain d'ingénieur Zako comme moi. Donc, bien que ce soit une mauvaise idée, fonction Python qui démarre Ruby via le shell avec le module de sous-processus Python et exécute le script Ruby de ʻanimeface-2009`. noisy / animeface_result2xml / blob / master / animeface_poor_caller.py) a été implémenté. Bien sûr, ** ce code seul ne peut pas détecter les visages **. Une préparation préalable est requise. La structure du répertoire doit être similaire au référentiel Git mentionné ci-dessus, et animeface-2009 doit être construit [^ 2] ..

[^ 2]: L'original ʻanimeface-2009` était difficile à construire dans plusieurs environnements, j'ai donc apporté une modification au [dépôt de fourches](https://github.com/meow-noisy/animeface-2009/ tree / a39361157ba8bf16ccd838942fa2f333658e9627) est utilisé. Nous avons ajouté les étapes nécessaires à la construction de README.md dans ce référentiel, veuillez donc le vérifier également.

# a poor python caller of animeface-2009
# call rb module via shell by using subprocess...

import subprocess

import sys
import json
from pathlib import Path

this_file_dir = (Path(__file__).resolve()).parent


def detect_animeface(im_path):

    im_path = Path(im_path).resolve()
    assert im_path.exists()

    ruby_script_path = this_file_dir / 'animeface-2009/animeface-ruby/sample.rb'
    ret = subprocess.check_output(["ruby", str(ruby_script_path), str(im_path)]).decode('utf-8')

    ret = ret.replace("=>", ":")
    ret = ret.replace(">", "\"")
    ret = ret.replace("#", "\"")
    list_ = json.loads(ret)

    return list_

Nous ne transmettons pas de données directement de Ruby à Python. Après avoir sorti les informations de la boîte englobante détectée en standard, Python parvient à formater la chaîne de caractères afin qu'elle soit au format JSON et en fasse un type de dictionnaire [^ 4]. Bien qu'il s'agisse d'une interface de fonction, l'entrée est le chemin de l'image et la valeur de retour est le résultat de la détection, qui est une liste de dictionnaires comme indiqué ci-dessous. Un résultat de détection de visage est un dictionnaire.

[^ 4]: Certains éléments inutiles (chaînes de caractères représentant des objets Ruby) sont inclus, mais comme le post-traitement était gênant, j'essaye de le sortir tel quel.

[{'chin': {'x': 228, 'y': 266},
  'eyes': {'left': {'colors': ['<Magick::Pixel:0x00007ff93e969148',
                               '<Magick::Pixel:0x00007ff93e968e28',
                               '<Magick::Pixel:0x00007ff93e968d88',
                               '<Magick::Pixel:0x00007ff93e968bf8'],
                    'height': 31,
                    'width': 39,
                    'x': 222,
                    'y': 181},
           'right': {'colors': ['<Magick::Pixel:0x00007ff93e968040',
                                '<Magick::Pixel:0x00007ff93e968018',
                                '<Magick::Pixel:0x00007ff93e968180',
                                '<Magick::Pixel:0x00007ff93e9681a8'],
                     'height': 28,
                     'width': 31,
                     'x': 165,
                     'y': 202}},
  'face': {'height': 127, 'width': 127, 'x': 158, 'y': 158},
  'hair_color': '<Magick::Pixel:0x00007ff93e969cb0',
  'likelihood': 1.0,
  'mouth': {'height': 12, 'width': 25, 'x': 210, 'y': 243},
  'nose': {'x': 207, 'y': 233},
  'skin_color': '<Magick::Pixel:0x00007ff93e96a020'},
 {'chin': {'x': 379, 'y': 243},
  'eyes': {'left': {'colors': ['<Magick::Pixel:0x00007ff93e96b6a0',
                               '<Magick::Pixel:0x00007ff93e96b8d0',
                               '<Magick::Pixel:0x00007ff93e96b9e8',
                               '<Magick::Pixel:0x00007ff93e96bab0'],
                    'height': 29,
                    'width': 32,
                    'x': 418,
                    'y': 177},
           'right': {'colors': ['<Magick::Pixel:0x00007ff93e963568',
                                '<Magick::Pixel:0x00007ff93e963478',
                                '<Magick::Pixel:0x00007ff93e963298',
                                '<Magick::Pixel:0x00007ff93e9631a8'],
                     'height': 31,
                     'width': 39,
                     'x': 354,
                     'y': 157}},
  'face': {'height': 139, 'width': 139, 'x': 329, 'y': 121},
  'hair_color': '<Magick::Pixel:0x00007ff93e96ab38',
  'likelihood': 1.0,
  'mouth': {'height': 12, 'width': 20, 'x': 383, 'y': 218},
  'nose': {'x': 401, 'y': 205},
  'skin_color': '<Magick::Pixel:0x00007ff93e96a7c8'}]

À propos, lorsque vous exécutez un script d'un fichier Python, une image représentant le résultat de la détection est sortie.

result_image.png

Un module qui sort le résultat de la détection dans un fichier XML au format PASCAL VOC

Vous pouvez utiliser la fonction ci-dessus pour détecter les visages (parties) animés, mais tous les visages ne peuvent pas être détectés. Du point de vue de l'évolutivité des performances de détection, nous envisagerons également de migrer vers des détecteurs basés sur DNN. Par conséquent, en utilisant les résultats de détection de animeface-2009, nous avons implémenté une fonction pour créer un ensemble de données de détection d'objets pour l'apprentissage du DNN. Le format de l'ensemble de données est le PASCAL VOC standard.

$ python animeface_result2xml.py [Répertoire de l'image à détecter] [Répertoire de sortie du fichier XML] [Chemin du fichier texte de la liste de fichiers XML créée]

Collectez à l'avance les images que vous souhaitez détecter dans le répertoire (la configuration du sous-répertoire est possible), et spécifiez le chemin d'accès au répertoire pour sortir le fichier XML et le fichier texte qui affiche la liste des fichiers créés.

À propos, le fichier XML est le suivant.

<annotation>
    <folder>folder_name</folder>
    <filename>img_file_path</filename>
    <path>/path/to/dummy</path>
    <source>
    <database>Unknown</database>
    </source>
    <size>
        <width>600</width>
        <height>600</height>
        <depth>3</depth>
    </size>
    <segmented>0</segmented>
    <object>
        <name>face</name>
        <pose>Unspecified</pose>
        <truncated>1</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>158</xmin>
            <ymin>158</ymin>
            <xmax>285</xmax>
            <ymax>285</ymax>
        </bndbox>
    </object><object>
        <name>right_eye</name>
        <pose>Unspecified</pose>
        <truncated>1</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>165</xmin>
            <ymin>202</ymin>
            <xmax>196</xmax>
            <ymax>230</ymax>
        </bndbox>
...

Vérification des étiquettes avec des outils

Lors de l'édition d'un fichier XML, il est recommandé d'utiliser l'outil d'annotation LabelImg. Vous pouvez vérifier graphiquement la boîte englobante estimée et corriger le mauvais endroit sur place.

labelimg.png

Après cela, le XML créé est analysé par le chargeur de données de l'infrastructure d'apprentissage en profondeur et le modèle DNN de détection d'objets est entraîné.

en conclusion

J'ai implémenté une fonction sale pour gérer ʻanimeface-2009`, qui est un module Ruby qui détecte les parties de visage d'anime, en Python. Nous avons également implémenté une fonction qui convertit le résultat de la détection en un fichier XML au format Pascal VOC. Je voudrais utiliser cela pour élargir la gamme d'applications de l'apprentissage automatique d'anime.

Dans cet article, j'ai pris la position qu'une étiquette d'annotation est nécessaire pour détecter un objet animé avec DNN, mais certaines personnes peuvent trouver cela un peu gênant. Récemment, kanosawa a publié un article utilisant la technique d'adaptation de domaine pour entraîner des modèles de détection d'objets. Vous pouvez apprendre le modèle de détection d'objet (RCNN plus rapide) sans annoter le cadre de délimitation du visage animé, veuillez donc le cocher si vous êtes intéressé.

Recommended Posts

Mauvais message pour utiliser "animeface-2009" en Python et implémentation de la fonction pour générer un fichier XML au format PASCAL VOC
Convertir le fichier XML au format Pascal VOC en fichier json au format COCO
Sortie de la table spécifiée de la base de données Oracle en Python vers Excel pour chaque fichier
Convertir un document XML stocké dans une base de données XML (BaseX) au format CSV (en utilisant Python)
Évaluation de la vitesse de sortie du fichier CSV en Python
Changer la destination de sortie standard en un fichier en Python
Pour renvoyer char * dans une fonction de rappel à l'aide de ctypes en Python
Un mémo que j'ai écrit une fonction de base en Python en utilisant la récurrence
Google recherche la chaîne sur la dernière ligne du fichier en Python
Convertir un fichier Excel en texte en Python à des fins de comparaison
Publier sur Twitter en utilisant Python
Implémentation du tri rapide en Python
Publier sur Slack en Python
Exportez le contenu de ~ .xlsx dans le dossier en HTML avec Python
Exporter les résultats de la recherche de publication dans un fichier à l'aide de l'API Mattermost
Implémentation de la fonction de connexion dans Django
Sortie vers un fichier csv avec Python
Implémentation du jeu de vie en Python
Implémentation des notifications de bureau à l'aide de Python
Notes pour l'entrée / sortie de fichier Python
Implémentation du tri original en Python
Le nom du fichier était mauvais en Python et j'étais accro à l'importation
Implémentation du filtre à particules par Python et application au modèle d'espace d'états
Comment bien formater une liste de dictionnaires (ou d'instances) en Python
J'ai fait un programme pour vérifier la taille d'un fichier avec Python
[Python] [Word] [python-docx] Essayez de créer un modèle de phrase de mot en Python en utilisant python-docx