[PYTHON] J'ai essayé de faire un diagnostic de visage AI pour les golfeuses professionnelles ①

1.Tout d'abord

J'ai pensé à créer un produit en utilisant le deep learning que j'apprends maintenant. Je voulais créer une application d'intelligence artificielle qui utilise des images, alors j'ai travaillé dessus.

Quand je me demandais quoi faire avec le sujet, mon père était accro aux golfeuses professionnelles, alors j'ai décidé de créer une application de diagnostic professionnelle féminine. J'ai décidé de créer une application d'imagerie diagnostique pour Hinako Shibuno, Sakura Kobetsu et Erika Hara.

2. Comment procéder

① Collection d'images
② Obtenez uniquement la partie du visage
③ Supprimez les données inutiles (par exemple, un visage différent, des lunettes de soleil, l'image de l'oncle pour une raison quelconque)
④ Diviser en données de test et données de validation
⑤ Image gonflée
⑥ Construction du modèle (cette fois apprentissage par transfert vgg16)
⑦ Créer une demande de publication
⑧ Déployer

C'était assez difficile ... Je vais écrire sur ce que j'ai essayé.

3. Collection d'images

Je pense qu'il y a plusieurs façons de le faire, mais j'ai utilisé icrawler.

Qu'est-ce que icrawler?

Un mini-framework pour le robot d'exploration Web. Il prend en charge les données multimédias telles que les images et les vidéos, et peut être appliqué au texte et à d'autres types de fichiers. Scrapy est lourd et puissant, mais icrawler semble être léger. Référence officielle Veuillez également vous référer à la méthode d'installation.

search.py


from icrawler.builtin import BingImageCrawler
import os
import shutil

#Image à détecter
golfer_lists = {'Hinako Shibuno': 'shibuno', 'Petite fête Sakura': 'koiwai', 'Erika Hara': 'hara'}

#Créer le dossier
os.makedirs('./origin_image', exist_ok=True)

#La clé est le nom de la recherche et la valeur est le nom du dossier.
for key, value in golfer_lists.items():
    #Spécifiez la destination d'enregistrement de l'image acquise
    crawler = BingImageCrawler(storage={'root_dir': value})
    #Précisez les mots clés et le nombre d'acquisitions
    crawler.crawl(keyword=key, max_num=1000)
    #Déplacer le dossier
    path = os.path.join('./', value)
    shutil.move(path, './origin_image/')

Vous pouvez maintenant obtenir chaque image. Je l'ai réglé sur 1000, mais c'était en fait environ 700.

4. Acquisition de la partie faciale

J'ai utilisé face_recognition pour obtenir la partie du visage.

face_recognition.py


import cv2
from PIL import  Image
import os, glob
import numpy as np
import random
from PIL import ImageFile
import face_recognition

#Dossier d'origine contenant l'image d'origine
in_dir = './origin_image/*'
#Contient l'image du visage uniquement
out_dir = './face'
#Dossier pour chaque joueur
in_file = glob.glob(in_dir)
#Obtenez le nom du dossier de chaque joueur
fileName_lists = os.listdir('./origin_image')
#Où enregistrer le fichier de test
test_image_path = './test_image/'

#Effectuer le traitement pour chaque dossier
for golfer, fileName in zip(in_file, fileName_lists):
    #Obtenez la liste d'images de chaque joueur
    in_jpg = glob.glob(golfer + '/*')
    #Nom d'image de chaque joueur
    in_fileName=os.listdir(golfer)
    #Chemin du dossier pour chaque joueur
    folder_path = out_dir + '/' + fileName
    #Créez un dossier de sortie pour chaque lecteur
    os.makedirs(folder_path, exist_ok=True)

    #Traitez chaque image
    for i in range(len(in_jpg)):
        #Charger l'image
        # image(Verticale,côté,3 couleurs)
        image = face_recognition.load_image_file(str(in_jpg[i]))
        faces = face_recognition.face_locations(image)
        
        #Si l'image existe([(911, 2452, 1466, 1897)])Est la sortie comme
        if len(faces) > 0:
            #Sélectionnez la plus grande parmi les images de visage acquises((top - bottom)*(right - left)Calculer)
            face_max = [(abs(faces[i][0]-faces[i][2])) * (abs(faces[i][1]-faces[i][3])) for i in range(len(faces))]
            top, right, bottom, left = faces[face_max.index(max(face_max))]

            #Extraire l'image de la partie du visage
            faceImage = image[top:bottom, left:right]

            # Image.fromarray()Passer ndarray à PIL.L'image est obtenue et sa sauvegarde()Peut être enregistré en tant que fichier image avec la méthode.
            final = Image.fromarray(faceImage)

            final = np.asarray(final.resize((64, 64)))
            final = Image.fromarray(final)

            file_path = folder_path + '/' + str(i) + '.jpg'
            final.save(file_path)
        else:
            print('No Face')

C'est un peu long, mais ça ressemble à ça.

Vérifiez le système de dossiers actuel フォルダ.png

Vous pouvez maintenant obtenir la partie du visage. __ Après cela, essayez de vérifier un par un ... __ C ’est très difficile, mais c’ est important.

5. Données de formation séparées et données de validation

Divisez en données d'entraînement 80% et données de validation 20%.

split.py


#Séparez les données d'entraînement et les données de validation
import os, glob
import shutil

#Contient l'image du visage uniquement
in_dir = './face/*'
#Dossier pour chaque joueur['./face/shibuno' './face/koiwai', './face/hara']
in_file = glob.glob(in_dir) 
#Obtenez le nom du dossier de chaque joueur['shibuno', 'koiwai', 'hara']
fileName_lists = os.listdir('./face')
#Où enregistrer le fichier de test
test_image_path = './valid/'

#Effectuer le traitement pour chaque dossier
for golfer, fileName in zip(in_file, fileName_lists):
    #Obtenez la liste d'images de chaque joueur
    in_jpg = glob.glob(golfer + '/*')
    #Nom d'image de chaque joueur
    in_fileName=os.listdir(golfer)

    #Enregistrer les données pour validation
    test_path = test_image_path + fileName
    os.makedirs(test_path, exist_ok=True)

    #Déplacer vers le dossier de validation
    for i in range(len(in_jpg)//5):
        shutil.move(str(in_jpg[i]), test_path+'/')
フォルダ2.png

Ce n'est pas grave si ça ressemble à ça. Ensuite, l'image des données d'entraînement est gonflée.

6. Données gonflées (gonflées)

Collecter des données d'image et les sélectionner est très long et difficile. (C'était vraiment dur) Par conséquent, de nouvelles données sont créées en inversant ou en décalant les données d'image.

pic_add


import PIL
from keras.preprocessing.image import load_img, img_to_array, ImageDataGenerator, array_to_img
import numpy as np
import os, glob
import matplotlib.pyplot as plt
import cv2

#Dossier d'origine contenant l'image d'origine
in_dir = './face/*'
#Contient l'image du visage uniquement
out_dir = './face'
#Chemin du dossier pour chaque joueur
in_files = glob.glob(in_dir)
#Chaque nom de dossier
folder_names = os.listdir('./face')

#Le nom du pass et du dossier de chaque joueur
for file, name in zip(in_files, folder_names):
    #Chaque image
    image_files = glob.glob(file + '/*')
    #Chaque nom de fichier
    in_fileName = os.listdir(file)

    SAVE_DIR = './face/' + name
    #Si le répertoire de destination de sauvegarde n'existe pas, créez-le.
    if not os.path.exists(SAVE_DIR):
        os.makedirs(SAVE_DIR)

    #Gonflez chaque image individuellement
    for num in range(len(image_files)):
        datagen = ImageDataGenerator(
        rotation_range=40,       #Plage de rotation à rotation aléatoire (unité: degré)
        width_shift_range=0.2,   #Mouvement parallèle aléatoire dans le sens horizontal, rapport à la largeur de l'image
        height_shift_range=0.2,  #Mouvement parallèle aléatoire dans la direction verticale, rapport à la largeur verticale de l'image
        shear_range=0.2,         #Degré de cisaillement. L'augmentation de la taille donne à l'image un aspect plus écrasé ou étiré en diagonale (unité: degré)
        zoom_range=0.2,          #Vitesse à laquelle l'image est compressée et agrandie de manière aléatoire. Minimum 1-Comprimé à la plage de zoom, jusqu'à 1+zoom_Élargi à la gamme.
        horizontal_flip=True,    #Si True est spécifié, il sera retourné horizontalement au hasard.
        fill_mode='nearest')

        img_array = cv2.imread(image_files[num])  #Chargement d'image
        img_array = img_array.reshape((1,) + img_array.shape)  #Convertir en données 4D (flux()Passer à)

        # flow()Créez un lot d'images converties au hasard.
        #Enregistrez l'image générée dans le répertoire spécifié.
        i = 0
        for batch in datagen.flow(img_array, batch_size=1,
                                save_to_dir=SAVE_DIR, save_prefix='add', save_format='jpg'):
            i += 1
            if i == 5:
                break  #Boucle infinie si non arrêtée

Avec cela, le nombre d'images de données d'entraînement a dépassé 1000.

__ Cela fait si longtemps que je reprendrai la création du modèle la prochaine fois. __

Le code lorsque le classificateur en cascade est utilisé comme une édition supplémentaire est également décrit.

* Classificateur en cascade

Au début, j'ai essayé d'obtenir la partie du visage en utilisant le classificateur en cascade, mais je ne pouvais pas obtenir la partie du personnage et le visage, et la quantité de données est devenue d'environ 1/6. Je publierai également le classificateur en cascade pour le moment Téléchargez "haarcascade_frontalface_default.xml" à partir du lien ci-dessous.

(https://github.com/opencv/opencv/tree/master/data/haarcascades)

cascade.py


import cv2
from PIL import  Image
import os, glob
import numpy as np
import random
from PIL import ImageFile

#Dossier d'origine contenant l'image d'origine
in_dir = './origin_image/*'
#Contient l'image du visage uniquement
out_dir = './face_image'
#Dossier pour chaque joueur
in_file = glob.glob(in_dir)
#Obtenez le nom du dossier de chaque joueur
fileName_lists = os.listdir('./origin_image')
#Où enregistrer le fichier de test
test_image_path = './face_image/test_image/'

cascade_path = './haarcascade_frontalface_alt.xml'
face_cascade = cv2.CascadeClassifier(cascade_path)

#Effectuer le traitement pour chaque dossier
for golfer, fileName in zip(in_file, fileName_lists):
    #Obtenez la liste d'images de chaque joueur
    in_jpg = glob.glob(golfer + '/*')
    #Nom d'image de chaque joueur
    in_fileName=os.listdir(golfer)
    #Chemin du dossier pour chaque joueur
    folder_path = out_dir + '/' + fileName
    #Créez un dossier de sortie pour chaque lecteur
    os.makedirs(folder_path, exist_ok=True)

    #Traitez chaque image
    for i in range(len(in_jpg)):
        #Charger l'image
        image=cv2.imread(str(in_jpg[i]))
        #Faites-en une échelle de gris
        image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=2, minSize=(64, 64))

        if len(faces) > 0:
            for j, face in enumerate(faces,1):
                x, y ,w, h =face
                save_img_path = folder_path + '/' + str(i) +'_' + str(j) + '.jpg'
                cv2.imwrite(save_img_path , image[y:y+h, x:x+w])
        else:
            print ('image' + str(i) + ':NoFace')

Recommended Posts

J'ai essayé de faire un diagnostic de visage AI pour les golfeuses professionnelles ①
J'ai essayé de faire un diagnostic de visage AI pour les golfeuses professionnelles ②
J'ai essayé de faire un diagnostic de visage AI pour les golfeuses professionnelles ③
J'ai essayé de faire de l'IA pour Smash Bra
J'ai créé une API Web
J'ai essayé de faire une étrange citation pour Jojo avec LSTM
J'ai créé un jeu ○ ✕ avec TensorFlow
[Python] J'ai essayé de créer une IA Shiritori qui améliore le vocabulaire grâce aux batailles
J'ai essayé de faire un "putain de gros convertisseur de littérature"
J'ai essayé de créer un environnement d'apprentissage amélioré pour Othello avec Open AI gym
J'ai essayé de faire de l'art créatif avec l'IA! J'ai programmé une nouveauté! (Article: Réseau Adversaire Créatif)
J'ai essayé de créer un bot pour annoncer un événement Wiire
J'ai fait un chronomètre en utilisant tkinter avec python
J'ai créé un éditeur de texte simple en utilisant PyQt
[5e] J'ai essayé de créer un certain outil de type Authenticator avec python
[2nd] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de créer une expression régulière de "montant" en utilisant Python
[Python] J'ai essayé d'implémenter un tri stable, alors notez
J'ai essayé de créer une expression régulière de "temps" en utilisant Python
[3ème] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de créer une expression régulière de "date" en utilisant Python
J'ai essayé de faire un processus d'exécution périodique avec Selenium et Python
J'ai essayé de créer une application de notification de publication à 2 canaux avec Python
J'ai essayé de créer une application todo en utilisant une bouteille avec python
[4th] J'ai essayé de créer un certain outil de type Authenticator avec python
[1er] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de créer un mécanisme de contrôle exclusif avec Go
J'ai essayé de créer un linebot (implémentation)
J'ai essayé de créer un linebot (préparation)
J'ai essayé de créer un LINE BOT "Sakurai-san" avec API Gateway + Lambda
J'ai essayé de faire un signal avec Raspeye 4 (édition Python)
[Pyto] J'ai essayé d'utiliser un smartphone comme clavier pour PC
J'ai essayé de créer un service de raccourcissement d'url sans serveur avec AWS CDK
J'ai refactoré "J'ai essayé de faire d'Othello AI lorsque les débutants en programmation ont étudié python"
Je veux faire de matplotlib un thème sombre
J'ai essayé de créer une méthode de super résolution / ESPCN
J'ai essayé de faire un processus périodique avec CentOS7, Selenium, Python et Chrome
J'ai fait une application d'envoi de courrier simple avec tkinter de Python
Quand j'ai essayé de créer un VPC avec AWS CDK mais que je n'ai pas pu le faire
Les débutants en IA essaient de faire des étudiants professionnels Bot
Je veux faire un jeu avec Python
[Analyse des brevets] J'ai essayé de créer une carte des brevets avec Python sans dépenser d'argent
J'ai essayé d'expliquer à quoi sert le générateur Python aussi facilement que possible.
J'ai créé une API de recherche de château avec Elasticsearch + Sudachi + Go + echo
Continuer à faire des prévisions de stock AI pendant 10 heures par jour le 1er mois
J'ai lu "Comment créer un laboratoire de piratage"
J'ai essayé de créer un BOT de traduction qui fonctionne avec Discord en utilisant googletrans
Je pensais que je pouvais créer un bon éditeur gitignore, alors j'ai essayé de faire quelque chose comme MVP pour le moment
J'ai essayé de générer une chaîne de caractères aléatoire
J'ai essayé de créer une méthode de super résolution / SRCNN ③
J'ai essayé de créer une fonction de dictionnaire insensible à la casse
J'ai essayé de créer un bouton pour Slack avec Raspeye + Tact Switch
J'ai essayé de créer une méthode de super résolution / SRCNN ②
J'ai essayé d'automatiser le travail de masquage du visage de l'image de coordination pour l'usure
J'ai essayé de faire MAP rapidement une personne suspecte en utilisant les données d'adresse Geolonia
J'ai essayé de créer une API de reconnaissance d'image simple avec Fast API et Tensorflow
Continuer à faire des prévisions de stock AI pendant 10 heures par jour 3ème mois
J'ai essayé de faire un BOT de détection de lèvre d'air et de réponse automatique pour le travail à distance