Wenn Sie das Gesicht eines Charakters anhand eines animierten Bildes in Python erkennen möchten, verwenden Sie lbpcascade_animeface, das von nagadomi implementiert wurde. Ich sehe oft Fälle. Dieses lbpcascade_animeface ist ein Modul, das den Begrenzungsrahmen eines Gesichts schätzt.
Darüber hinaus ist das von Nagadomi implementierte Modul animeface-2009 nicht nur das Gesicht, sondern auch die Gesichtsteile (Augen, Nase, Mund, Der Begrenzungsrahmen des Kinns ist ebenfalls nachweisbar [^ 1]. Hier bietet jedoch nur Ruby eine API auf Bindungsebene. Laut README.md von "lbpcascade_animeface" steht geschrieben, dass "die Erkennungsgenauigkeit in" animeface-2009 "höher ist". Daher möchte ich es definitiv in Python verwenden.
[^ 1]: Der Begrenzungsrahmen an Nase und Kinn ist jedoch 1x1 Pixel groß, daher ist es möglicherweise besser, ihn als Orientierungspunkt zu bezeichnen.
Das Git-Repository des diesmal implementierten Repositorys ist hier.
Das Umschreiben von C-Code, der für Ruby for Python implementiert wurde, ist für einen verdammten Zako-Ingenieur wie mich keine leichte Aufgabe.
Obwohl es eine schlechte Idee ist, startet Python-Funktion Ruby über die Shell mit dem Python-Unterprozessmodul und führt das Ruby-Skript von animeface-2009
aus. noisy / animeface_result2xml / blob / master / animeface_poor_caller.py) wurde implementiert.
Natürlich kann ** dieser Code allein keine Gesichter erkennen **. Eine vorherige Vorbereitung ist erforderlich. Die Verzeichnisstruktur sollte dem oben erwähnten Git-Repository ähnlich sein, und animeface-2009 sollte erstellt werden [^ 2] ..
[^ 2]: Das ursprüngliche animeface-2009
war in mehreren Umgebungen schwer zu erstellen, daher habe ich eine Änderung am [Fork-Repository] vorgenommen (https://github.com/meow-noisy/animeface-2009/). tree / a39361157ba8bf16ccd838942fa2f333658e9627) wird verwendet. Wir haben die erforderlichen Schritte zum Erstellen von README.md in diesem Repository hinzugefügt. Überprüfen Sie dies daher ebenfalls.
# 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_
Wir geben keine Daten direkt von Ruby an Python weiter. Nach der standardmäßigen Ausgabe der erkannten Begrenzungsrahmeninformationen kann Python die Zeichenfolge so formatieren, dass sie im JSON-Format vorliegt, und sie zu einem Wörterbuchtyp [^ 4] machen. Obwohl es sich um eine Funktionsschnittstelle handelt, ist die Eingabe der Bildpfad und der Rückgabewert das Erkennungsergebnis, bei dem es sich um eine Liste von Wörterbüchern handelt, wie unten gezeigt. Ein Gesichtserkennungsergebnis ist ein Wörterbuch.
[^ 4]: Einige unnötige Elemente (Zeichenfolgen, die Ruby-Objekte darstellen) sind enthalten, aber da die Nachbearbeitung problematisch war, versuche ich, sie so auszugeben, wie sie ist.
[{'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'}]
Übrigens, wenn Sie ein Skript einer Python-Datei ausführen, wird ein Bild ausgegeben, das das Erkennungsergebnis darstellt.
Mit der obigen Funktion können Sie animierte Gesichter (Teile) erkennen, aber nicht alle Gesichter können erkannt werden. Unter dem Gesichtspunkt der Skalierbarkeit der Erkennungsleistung werden wir auch die Migration auf DNN-basierte Detektoren in Betracht ziehen. Aus diesem Grund haben wir unter Verwendung der Erkennungsergebnisse von animeface-2009 eine Funktion implementiert, um einen Objekterkennungsdatensatz zum Lernen von DNN zu erstellen. Das Format des Datensatzes ist das Standard-PASCAL-VOC.
$ python animeface_result2xml.py [Verzeichnis des zu erkennenden Bildes] [Verzeichnis zur Ausgabe der XML-Datei] [Textdateipfad der erstellten XML-Dateiliste]
Sammeln Sie die Bilder, die Sie erkennen möchten, im Voraus im Verzeichnis (die Konfiguration des Unterverzeichnisses ist möglich) und geben Sie den Pfad zum Verzeichnis an, in dem die XML-Datei und die Textdatei mit der Liste der erstellten Dateien ausgegeben werden sollen.
Die XML-Datei lautet übrigens wie folgt.
<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>
...
Beim Bearbeiten einer XML-Datei wird empfohlen, das Annotationstool LabelImg zu verwenden. Sie können den geschätzten Begrenzungsrahmen grafisch überprüfen und die falsche Stelle an Ort und Stelle korrigieren.
Danach wird das erstellte XML vom Datenlader des Deep-Learning-Frameworks analysiert und das DNN-Modell zur Objekterkennung trainiert.
Ich habe eine schmutzige Funktion implementiert, um animeface-2009
, ein Ruby-Modul, das Anime-Gesichtsteile erkennt, in Python zu verwalten. Wir haben auch eine Funktion implementiert, um das Erkennungsergebnis in eine XML-Datei im Pascal VOC-Format zu konvertieren.
Ich möchte dies nutzen, um das Anwendungsspektrum des maschinellen Lernens von Anime zu erweitern.
In diesem Artikel habe ich die Position vertreten, dass ein Anmerkungsetikett erforderlich ist, um ein animiertes Objekt mit DNN zu erkennen, aber einige Leute finden es möglicherweise etwas problematisch. Kürzlich veröffentlichte Kanosawa einen Artikel, in dem mithilfe der Domänenanpassungstechnik Objekterkennungsmodelle trainiert werden. Sie können das Objekterkennungsmodell (Faster RCNN) lernen, ohne den Begrenzungsrahmen des animierten Gesichts zu kommentieren. Überprüfen Sie es daher, wenn Sie interessiert sind.
Recommended Posts