Aikatsu! Ich wollte das Gesichtsfoto eines Charakters verwenden, um die Ergebnisse der Serienanalyse zu zeichnen, aber die Anzahl der Personen ist groß und die manuelle Bedienung ist mühsam. Also habe ich mit Beautiful Soup und Print Screen mit Selen geschabt. Ich habe mich dazu entschlossen, dies automatisch zu tun, bis das Gesicht des Charakters mit OpenCV aus PrintScreen ausgeschnitten ist.
from urllib import request
from bs4 import BeautifulSoup
from selenium import webdriver
import pandas as pd
import time
import os
import shutil
import itertools
#OpenCV erlaubt keine japanischen Dateinamen. Laden Sie daher die Zuordnungsdatei
df=pd.read_csv("C:/XXXX/aikatsu_name_romaji_mapping.tsv", sep='\t', engine='python', encoding="utf-8")
#Laden Sie den Chrome-Treiber
driver = webdriver.Chrome("C:/XXXX/chromedriver/chromedriver.exe")
#Haben Sie eine Tupel-URL zum Kratzen
character_urls =(
"http://www.aikatsu.net/01/character/index.html",
"http://www.aikatsu.net/02/character/index.html",
"http://www.aikatsu.net/03/character/index.html",
"http://www.aikatsu.net/aikatsustars_01/character/index.html",
"http://www.aikatsu.net/aikatsustars_02/character/index.html",
"http://www.aikatsu.net/aikatsufriends_01/character/",
"http://www.aikatsu.net/aikatsufriends_02/character/",
"http://www.aikatsu.net/character/"
)
#Erstellen eines Verzeichnisses zum Speichern von PrintScreen
target_dir = "C:/XXXX/download/"
if os.path.isdir(target_dir):
shutil.rmtree(target_dir)
time.sleep(1)
os.mkdir(target_dir)
Es wäre möglicherweise besser gewesen, den Verzeichniserstellungsteil als Funktion zu verwenden.
Das Mapping ist so einfach.
Ich benutze Pandas nur, weil die Anzahl der Zielcharaktere ungefähr 67 beträgt und es nicht notwendig ist, es DB oder Rich zu machen, und ich kann es schnell mit nur Wissen machen.
Bei Verwendung von Selenium wird der Speicherort des Treibers normalerweise in der Umgebungsvariablen festgelegt. Da es sich jedoch um ein Einwegwerkzeug handelt, muss es nicht so umfangreich sein. Während ich mich auf Folgendes bezog, schrieb ich den Treiber in Solid. Einführung in Selen beginnend mit nur 3 Python-Zeilen
Außerdem ist zum Zeitpunkt der Ausführung der folgende Fehler aufgetreten.
WebDriverError: unknown error: Runtime.executionContextCreated has invalid
Dies wird gelöst, indem die von Ihnen verwendete Treiberversion mit der Chrome-Version abgeglichen wird, da sie sich von der Chrome-Version unterscheidet.
for character_url in character_urls:
html = request.urlopen(character_url)
soup = BeautifulSoup(html, "html.parser")
#Holen Sie sich Informationen zu jedem Charakter
characters=soup.find_all("a")
idol_names = [i.find('img') for i in characters]
urls = [i.get('href') for i in characters]
character_url_prefix=character_url.split("index.html")
for i, j in zip(idol_names, urls):
#Wenn das Alt-Tag nicht korrekt verwendet werden kann, wird der Vorgang abgelehnt.
if i == None:
continue
#Andere Informationen als Zeichen abwehren
if j.startswith("http") or j.startswith("../") or j.startswith("index"):
continue
idol_name = i.get("alt").replace(" ","").replace(" ","")
print(idol_name)
#Anzeige und Einstellung der Selenseite
driver.get(character_url_prefix[0]+j)
driver.set_window_size(1250, 1036)
driver.execute_script("document.body.style.zoom='90%'")
#Shirayuri Kaguya legt einen festen Wert fest, da die Alt-Informationen leer sind
if idol_name == "":
idol_name = "Shirayuri Kaguya"
#OpenCV kann keine japanischen Namen verwenden, konvertieren Sie sie daher in römische Zeichen
idol_name_romaji = df[df["character"]==idol_name]["romaji"].values[0]
file_name="{}{}.png ".format(target_dir, idol_name_romaji)
#Wenn bereits eine gleichnamige Datei vorhanden ist, benennen Sie sie um.
if os.path.exists(file_name):
for i in itertools.count(1):
newname = '{} ({})'.format(idol_name_romaji, i)
file_name="{}{}.png ".format(target_dir, newname)
#Beenden Sie das Programm, wenn die gleichnamige Datei nicht vorhanden ist
if not os.path.exists(file_name):
break
#Stellen Sie eine etwas längere Ruhezeit ein, um Effekte beim Übergang zu Webseiten zu vermeiden
time.sleep(5)
driver.save_screenshot(file_name)
driver.quit()
Sie können die Daten so erhalten. Ursprünglich wurde der japanische Name alt zum Dateinamen hinzugefügt, aber da er von OpenCV nicht gelesen werden kann, wird er absichtlich in die Romaji-Notation konvertiert. (Romaji ist angemessen, so dass Sie einen Fehler machen können)
Wenn Sie die Charakternamen (idol_names) abrufen, wird None wie unten gezeigt erhalten. Da die URL und der Charaktername jedes Zeichens mit zip geloopt werden, ist es notwendig, die gleiche Anzahl von Elementen zu haben, also versuche ich, innerhalb statt vor der Schleife zu spielen.
[<img alt="Aikatsu auf Parade!" src="../images/logo.png "/>,
<img alt="Aikatsu auf Parade! Kommunikation" src="../images/bt-aikatsuonparadecom.png "/>,
<img alt="Aikatsu auf Parade! Was ist" src="../images/bt-aikatsuonparade.png "/>,
<img alt="Broadcast-Informationen" src="../images/bt-tvinfo.png "/>,
<img alt="Charakter" src="../images/bt-character.png "/>,
<img alt="Geschichte" src="../images/bt-story.png "/>,
<img alt="CD" src="../images/bt-cd.png "/>,
<img alt="BD/DVD" src="../images/bt-bddvd.png "/>,
<img alt="NEWS" src="../images/bt-news.png "/>,
<img alt="TOP" src="../images/bt-top.png "/>,
<img alt="Raki Himeishi" src="images/bt-raki.png "/>,
<img alt="Yuki Aine" src="images/bt-aine.png "/>,
<img alt="Mio Minato" src="images/bt-mio.png "/>,
<img alt="Hoshimiya Ichigo" src="images/bt-ichigo.png "/>,
<img alt="Akari Ozora" src="images/bt-akari.png "/>,
<img alt="Yume Nijino" src="images/bt-yume.png "/>,
<img alt="BANDAINAMCO Pictures" height="53" src="../images/bnp.png " width="118"/>,
None]
import os
import cv2
from pathlib import Path
#Ein Verzeichnis erstellen
download_dir = '{0}parse/'.format(target_dir)
if os.path.isdir(download_dir):
shutil.rmtree(download_dir)
time.sleep(1)
os.mkdir(download_dir)
#Erstellen Sie einen Klassifizierer basierend auf der Feature-Betragsdatei
classifier = cv2.CascadeClassifier('C:/XXX/lbpcascade_animeface.xml')
#Holen Sie sich Dateien in das Scraped-Verzeichnis
p = Path(target_dir)
for i in list(p.glob("*.png ")):
#Gesichtserkennung
image = cv2.imread(i.as_posix())
#Ein Verzeichnis erstellen
file_tmp=i.as_posix().split("/")
parse_dir = '{0}{1}/'.format(download_dir, file_tmp[len(file_tmp)-1:len(file_tmp)][0].split(".")[0])
os.mkdir(parse_dir)
#Graustufen
gray_image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
faces = classifier.detectMultiScale(gray_image)
for i, (x,y,w,h) in enumerate(faces):
#Schneiden Sie die Gesichter einzeln aus. Passen Sie die y-Koordinate an, um sie rechteckig zu machen
face_image = image[y-50:y+h, x:x+w]
output_path = '{0}{1}.png'.format(parse_dir, i)
#Schreiben
cv2.imwrite(output_path ,face_image)
Ich wollte, dass OpenCV rechteckig ist, also habe ich die Koordinaten ein wenig angepasst und der Inhalt ist wie folgt. Anime-Gesichtserkennung mit OpenCV
Sie können es so bekommen. Aufgrund der Pose wurden einige von ihnen vom Klassifikator nicht als Zeichen identifiziert. Da es nur wenige Leute gibt, frage ich mich, ob ich es manuell machen muss.
Recommended Posts