Afin de produire des résultats très précis à l'aide de l'apprentissage automatique pour un certain problème, il est important de concevoir la création d'un ensemble de données et la conception de l'apprenant. Parmi ceux-ci, le nombre de données préparées lors de la création d'un ensemble de données est particulièrement important pour un apprentissage réussi. La première chose à faire pour collecter les données nécessaires à l'apprentissage est de trouver une base de données que les ancêtres du monde ont organisée et construite les données qui débordent déjà sur le Web et les données qu'ils ont créées eux-mêmes. Cependant, il n'y a pas toujours une base de données aussi pratique, vous devrez peut-être la collecter vous-même. Donc, cette fois, à titre d'exemple simple pour étudier, j'ai créé un script en Python qui collecte des images de personnes, puis recadre et enregistre uniquement le visage.
Le script créé cette fois est censé rechercher et collecter des images associées sur le Web après avoir donné une requête, effectuer une reconnaissance faciale à l'aide d'OpenCV, puis recadrer et enregistrer. Le moteur de recherche utilisé est la recherche d'images de Bing.
Le code source de ce script se trouve sur le lien ci-dessous. https://github.com/tokkuman/FaceImageCollection Chaque fonction de ce script sera décrite ci-dessous.
Import Les modules importés dans cette création de script sont les suivants.
import sys
import os
import commands as cmd
import cv2
import time
import copy
from argparse import ArgumentParser
getHtml Une fonction qui récupère le html de la page recherchée en lançant une requête. Puisque la sortie cmd.getstatus renvoie (statut, sortie) sous forme de taple, cette fois, seul le code HTML extrait par wget -O est renvoyé.
def getHtml(query):
return cmd.getstatusoutput("wget -O - https://www.bing.com/images/search?q=" + query)[1]
extractImageURL Une fonction qui reçoit les formats html et image et extrait uniquement les liens du format spécifié de html.
def extractImageURL(html, suffix):
url = []
snum, lnum = 0, 0
text = html.split('\n')
for sen in text:
if sen.find('<div class="item">') >= 0:
element = sen.split('<div class="item">')
for num in range(len(element)):
for suf in suffix:
snum = element[num].find("href") + 6
lnum = element[num].find(suf) + len(suf)
if lnum > 0:
url.append(element[num][snum:lnum])
break
return url
saveImg extractImage Une fonction qui enregistre temporairement l'image souhaitée localement à partir du lien extrait par URL. Créez un autre répertoire appelé Original dans le répertoire créé (opbase) et enregistrez-y les images.
def saveImg(opbase, url):
dir = opbase + '/Original/'
if not (os.path.exists(dir)):
os.mkdir(dir)
for u in url:
try:
os.system('wget -P ' + dir + ' ' + u)
except:
continue
cropFace Une fonction qui extrait uniquement le visage de l'image enregistrée, la rogne et l'enregistre. La reconnaissance faciale utilise un modèle entraîné (cascade haar) du classificateur Haar dans OpenCV. Dans ce script, il est possible d'utiliser quatre types de méthodes, en supposant que seule la face de face est extraite. Pour la précision du modèle, je me suis référé au lien suivant (http://stackoverflow.com/questions/4440283/how-to-choose-the-cascade-file-for-face-detection). Pour l'image après Crop, créez un répertoire Crop dans opbase et enregistrez-le dedans.
def cropFace(opbase, path, imsize, method):
dir = opbase + '/Crop/'
if not (os.path.exists(dir)):
os.mkdir(dir)
for p in path:
img = cv2.imread(opbase + '/Original/' + p)
gImg = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
if method == 1:
face_cascade = cv2.CascadeClassifier('haarcascade/haarcascade_frontalface_default.xml')
elif method == 2:
face_cascade = cv2.CascadeClassifier('haarcascade/haarcascade_frontalface_alt.xml')
elif method == 3:
face_cascade = cv2.CascadeClassifier('haarcascade/haarcascade_frontalface_alt2.xml')
else:
face_cascade = cv2.CascadeClassifier('haarcascade/haarcascade_frontalface_alt_tree.xml')
faces = face_cascade.detectMultiScale(gImg, 1.3, 5)
for num in range(len(faces)):
cropImg = copy.deepcopy(img[faces[num][1]:faces[num][1]+faces[num][3], faces[num][0]:faces[num][0]+faces[num][2]])
resizeImg = cv2.resize(cropImg, (imsize, imsize))
filename = dir + p[:-4] + '_' + str(num + 1) + '.tif'
cv2.imwrite(filename, resizeImg)
main La fonction principale de ce script. Exécutez avec un analyseur avec les options suivantes.
De plus, le répertoire de sortie de ce script est créé avec le nom de requête spécifié.
if __name__ == "__main__":
ap = ArgumentParser(description='ImageCollenction.py')
ap.add_argument('--query', '-q', nargs='*', default='hoge', help='Specify Query of Image Collection ')
ap.add_argument('--suffix', '-s', nargs='*', default='jpg', help='Specify Image Suffix')
ap.add_argument('--imsize', '-i', type=int, default=100, help='Specify Image Size of Crop Face Image')
ap.add_argument('--method', '-m', type=int, default=1, help='Specify Method Flag (1 : Haarcascades Frontalface Default, 2 : Haarcascades Frontalface Alt1, 3 : Haarcascades Frontalface Alt2, Without : Haarcascades Frontalface Alt Tree)')
args = ap.parse_args()
t = time.ctime().split(' ')
if t.count('') == 1:
t.pop(t.index(''))
# Path Separator
psep = '/'
for q in args.query:
opbase = q
# Delite File Sepaeator
if (opbase[len(opbase) - 1] == psep):
opbase = opbase[:len(opbase) - 1]
# Add Current Directory (Exept for Absolute Path)
if not (opbase[0] == psep):
if (opbase.find('./') == -1):
opbase = './' + opbase
# Create Opbase
opbase = opbase + '_' + t[1] + t[2] + t[0] + '_' + t[4] + '_' + t[3].split(':')[0] + t[3].split(':')[1] + t[3].split(':')[2]
if not (os.path.exists(opbase)):
os.mkdir(opbase)
print 'Output Directory not exist! Create...'
print 'Output Directory:', opbase
html = getHtml(q)
url = extractImageURL(html, args.suffix)
saveImg(opbase, url)
cropFace(opbase, os.listdir(opbase + '/Original'), args.imsize, args.method)
Afin d'expérimenter la quantité de bruit mélangée, cette fois je montrerai le résultat obtenu en lançant les requêtes "Gacky" et "Becky" comme passe-temps personnel.
Il faut dire que c'était Gacky dans le monde, et bien qu'il contenait du bruit de monstre, c'était généralement Gacky. D'un autre côté, Becky a également fait venir des personnes que l'on pense être Becky autres que Becky. Il est inévitable en termes de spécifications qu'une requête de plus grande généralité contienne plus de bruit, mais on peut dire qu'il y a place à l'amélioration. De plus, le point le plus important à améliorer est le nombre d'images pouvant être collectées, et comme le nombre d'images par requête est extrêmement faible, on peut dire qu'il y a encore des problèmes dans l'ensemble.
Dans le monde, il est courant d'utiliser l'API Google Custom Search ou l'API Bing Search pour la collecte d'images, et la précision et le nombre de collections sont extrêmement élevés. Cette fois, le défi était de savoir jusqu'où je pouvais essayer sans utiliser ces API, mais j'aimerais également essayer la méthode utilisant des API. De plus, étant donné que la méthode d'analyse html a également été explorée, on considère qu'il y avait un problème avec la méthode d'extraction. Vous pouvez utiliser Beautiful Soup, que vous voyez souvent comme un module pratique. De plus, Gacky fait de grands progrès avec la danse amoureuse (même s'il était à l'origine un ange, donc il volait), tandis que Becky a redémarré de la falaise, ce qui se refléterait dans ce résultat. Faites de votre mieux avec le MC d'Ainori.
Recommended Posts