[PYTHON] Détection de visage en collectant des images d'Angers.

Si vous ne connaissez pas Vtuber ou Nijisanji, vous n'arriverez pas ici, mais Je voulais faire du machine learning pour identifier "Sanbaka", j'ai donc d'abord téléchargé l'image d'Angers et détecté le visage. Il existe différents sites de référence, mais ils sont basés sur les sites suivants.

https://qiita.com/Tatsuro64/items/95b0ce48b6bb155bfe29

Programme: pytyon3.7 Environnement: ubuntu18.04 Bibliothèque utilisée: BeautifulSoup (scraping), opencv (détection de visage), urllib (téléchargement d'image)

Le traitement principal du code est le suivant.

if __name__ == '__main__':

    downloads = ImageDownloader('Angers Katrina').go()
    for i, d in enumerate(downloads):
        FaceDetector(d).cutout_faces('image/faces/faces_{}.jpg'.format(i + 1))

DL avec le téléchargeur et détecter le visage dans la liste, c'est tout.

Le téléchargeur est ci-dessous.

class ImageDownloader(object):
    def __init__(self, keyword):
        session = requests.session()
        session.headers.update(
            {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) \
             Gecko/20100101 Firefox/10.0'})
        params = urllib.parse.urlencode(
            {'q': keyword, 'tbm': 'isch', 'ijn': '1'})
        query = "https://www.google.co.jp/search" + '?' + params
        self._bs = BeautifulSoup(session.get(query).text, 'html.parser')

    def go(self):
        downloads = []
        for img in self._bs.find_all('img'):
            try:
                url = img['data-iurl']
                downloads.append('image/image_{}.jpg'.format(len(downloads) + 1))
                urllib.request.urlretrieve(url, downloads[-1])
            except KeyError:
                print('failed to get url : {}'.format(img))
        return downloads

■ Constructeur J'émets une requête à Google (mot-clé: Angers) et mets la page de résultats de recherche (seulement la première page cette fois) sur la bibliothèque de scraping (Beautiful Soup).

■ méthode go Recherchez toutes les balises img et le lien est stocké dans l'attribut ['data-iurl'], donc téléchargez-le avec le module urllib. Vous trouverez des balises à l'intérieur qui n'ont pas l'attribut ['data-iurl'], probablement autre que l'image de recherche, donc il intercepte l'exception KeyError et la traverse.

Le coupe-visage est le suivant.

class FaceDetector(object):

    #Modèle formé
    FACE_CASCADE = '/home/websoler/anaconda3/lib/python3.7/site-packages/cv2/data/lbpcascade_animeface.xml'

    def __init__(self, fname):
        self._img = cv2.imread(fname)

    def cutout_faces(self, fname):
        gray = cv2.cvtColor(self._img, cv2.COLOR_BGR2GRAY)
        classifier = cv2.CascadeClassifier(FaceDetector.FACE_CASCADE)
        faces = classifier.detectMultiScale(gray, scaleFactor=1.2, minSize=(30, 30))
        if len(faces):
            for (x, y, w, h) in faces:
                region = self._img[y:y + h, x:x + w]
                region_resized = cv2.resize(region, (128, 128))
                cv2.imwrite(fname, region_resized)
                break  #TODO Pour le moment, seul le premier cas.

■ Constructeur J'ai opencv lu le fichier passé.

■ méthode cut_faces Lorsque le visage est détecté, je le coupe, le redimensionne à 128 x 128 et l'enregistre en tant que fichier.

Le modèle d'apprentissage n'est pas le modèle standard fourni par OpenCV, mais utilise lbpcascade_animeface.xml, qui est spécialisé pour les visages d'anime. Cela ne fonctionnait pas quand je le mettais localement, donc je l'ai mis directement dans le chemin de la bibliothèque python. Dans mon environnement, l'anaconda était dedans avant que je le sache, donc en dessous de ça.

Le modèle d'anime est DL parmi les suivants. https://github.com/nagadomi/lbpcascade_animeface

J'ai spécifié minSize car plus la zone est petite, plus le taux de faux positifs est élevé. Les manches et les doigts d'Angers sont appelés «visages».

La prochaine fois, je préparerai le format TF Records pour l'apprentissage automatique et TensorFlow.

Le code complet est ci-dessous.


from bs4 import BeautifulSoup
import cv2
import os
import requests
import shutil
import urllib


#Arrangement environnemental
shutil.rmtree('image')
os.mkdir('image')
os.mkdir('image/faces')


class ImageDownloader(object):
    def __init__(self, keyword):
        session = requests.session()
        session.headers.update(
            {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) \
             Gecko/20100101 Firefox/10.0'})
        params = urllib.parse.urlencode(
            {'q': keyword, 'tbm': 'isch', 'ijn': '1'})
        query = "https://www.google.co.jp/search" + '?' + params
        self._bs = BeautifulSoup(session.get(query).text, 'html.parser')

    def go(self):
        downloads = []
        for img in self._bs.find_all('img'):
            try:
                url = img['data-iurl']
                downloads.append('image/image_{}.jpg'.format(len(downloads) + 1))
                urllib.request.urlretrieve(url, downloads[-1])
            except KeyError:
                print('failed to get url : {}'.format(img))
        return downloads


class FaceDetector(object):

    #Modèle formé
    FACE_CASCADE = '/home/websoler/anaconda3/lib/python3.7/site-packages/cv2/data/lbpcascade_animeface.xml'

    def __init__(self, fname):
        self._img = cv2.imread(fname)

    def cutout_faces(self, fname):
        gray = cv2.cvtColor(self._img, cv2.COLOR_BGR2GRAY)
        classifier = cv2.CascadeClassifier(FaceDetector.FACE_CASCADE)
        faces = classifier.detectMultiScale(gray, scaleFactor=1.2, minSize=(30, 30))
        if len(faces):
            for (x, y, w, h) in faces:
                region = self._img[y:y + h, x:x + w]
                region_resized = cv2.resize(region, (128, 128))
                cv2.imwrite(fname, region_resized)
                break  #TODO Pour le moment, seul le premier cas.

if __name__ == '__main__':

    downloads = ImageDownloader('Angers Katrina').go()
    for i, d in enumerate(downloads):
        FaceDetector(d).cutout_faces('image/faces/faces_{}.jpg'.format(i + 1))

Recommended Posts

Détection de visage en collectant des images d'Angers.
Approximation de bas rang des images par HOSVD étape par étape
Approximation de bas rang de l'image par décomposition de Tucker
[Python] Détection de visage par OpenCV (Haar Cascade)
Classification des images de guitare par apprentissage automatique Partie 1
Catégoriser les images de visage de personnages d'anime avec Chainer
Approximation de bas rang des images par HOSVD et HOOI
Classification des images de guitare par apprentissage automatique, partie 2
Optical Flow, l'image dynamique capturée par OpenCV
Détection d'anomalies des données de séries chronologiques par LSTM (Keras)
J'ai comparé l'identité des images par moment Hu
Détection des marqueurs ArUco
Améliorez rapidement la précision de détection en spécifiant les paramètres avec la détection de visage openCV