Ich habe ein Programm erstellt, das Gesichter mit der von OpenCV bereitgestellten Haar-Like-Funktion Cascade erkennt und automatisch ausschneidet.
-Software- Windows 10 Home Anaconda3 64-bit(Python3.7) Spyder -Library- opencv-python 4.1.2.30 natsort 7.0.0 -Hardware- CPU: Intel core i9 9900K RAM: 16GB 3200MHz
** Bücher ** OpenCV4-Programmierung beginnend mit Python Naohiro Kitayama (Autor) ([Amazon-Seite](https://www.amazon.co.jp/Python%E3%81%A7%E5%A7%8B%E3%82%81%E3%82%8BOpenCV-4%E3%83% 97% E3% 83% AD% E3% 82% B0% E3% 83% A9% E3% 83% 9F% E3% 83% B3% E3% 82% B0-% E5% 8C% 97% E5% B1% B1 -% E7% 9B% B4% E6% B4% 8B / dp / 4877834613))
Ich werde es auf Github posten.
https://github.com/himazin331/Face-Cropping Das Repository enthält das Datenverarbeitungsprogramm Haar-Cascade
Für den Betrieb dieses Programms ist eine Cascade-Datei mit Haar-ähnlichen Funktionen erforderlich. Dieses Mal werden wir Haar-Cascade von OpenCV verwenden. Cascade ist im Repository enthalten, sodass Sie es nicht separat vorbereiten müssen.
** Bitte beachten Sie, dass der Code verschmutzt ist ... **
face_cut.py
import cv2
import os
import argparse as arg
import sys
from natsort import natsorted
#Bildverarbeitung
def face_cut(imgs_dir, result_out, img_size, label, HAAR_FILE):
# Haar-Wie Feature Cascade Typ Klassifikator Lesen
cascade = cv2.CascadeClassifier(HAAR_FILE)
#Datenverarbeitung
for img_name in natsorted(os.listdir(imgs_dir)):
print("Bilddaten:{}".format(img_name))
#Nur JPG-Format
_, ext = os.path.splitext(img_name)
if ext.lower() == '.jpg':
img_path = os.path.join(imgs_dir, img_name) #Dateipfade kombinieren
img = cv2.imread(img_path) #Daten gelesen
img_g = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) #In Graustufen konvertieren
face = cascade.detectMultiScale(img_g) #Gesicht erkennen
#Wenn kein Gesicht erkannt wird
if len(face) == 0:
print("Face not found.")
else:
for x,y,w,h in face:
#Schneiden Sie das Gesicht aus
face_cut = img_g[y:y+h, x:x+w]
#Größe ändern
face_img = cv2.resize(face_cut, (img_size, img_size))
#sparen
result_img_name = '\data' + str(label) + '.jpg'
cv2.imwrite(os.path.join(result_out + result_img_name), face_img)
label += 1
print("Processing success!!")
else:
print("Unsupported file extension")
def main():
#Erstellen Sie Befehlszeilenoptionen
parser = arg.ArgumentParser(description='Face image cropping')
parser.add_argument('--imgs_dir', '-d', type=str, default=None,
help='Pfad des Bildordners(Fehler, wenn nicht angegeben)')
parser.add_argument('--out', '-o', type=str,
default=os.path.dirname(os.path.abspath(__file__))+'/result_crop'.replace('/', os.sep),
help='Speichern Sie das Ziel der Nachbearbeitungsdaten(Standardwert=./reslut_crop)')
parser.add_argument('--img_size', '-s', type=int, default=32,
help='Größe ändern(N für NxN,Standardwert=32)')
parser.add_argument('--label', '-l', type=int, default=1,
help='dataN.Anfangswert von N in jpg(Standardwert=1)')
parser.add_argument('--haar_file', '-c', type=str, default=os.path.dirname(os.path.abspath(__file__))+'/haar_cascade.xml'.replace('/', os.sep),
help='haar-Kaskadenpfadspezifikation(Standardwert=./haar_cascade.xml)')
args = parser.parse_args()
#Wenn der Bildordner nicht angegeben ist->Ausnahme
if args.imgs_dir == None:
print("\nException: Cropping target is not specified.\n")
sys.exit()
#Wenn ein nicht vorhandener Bildordner angegeben wird->Ausnahme
if os.path.exists(args.imgs_dir) != True:
print("\nException: {} does not exist.\n".format(args.imgs_dir))
sys.exit()
#Wenn eine nicht vorhandene Kaskade angegeben wird->Ausnahme
if os.path.exists(args.haar_file) != True:
print("\nException: {} does not exist.\n".format(args.haar_file))
sys.exit()
#Informationsausgabe einstellen
print("=== Setting information ===")
print("# Images folder: {}".format(os.path.abspath(args.imgs_dir)))
print("# Output folder: {}".format(args.out))
print("# Images size: {}".format(args.img_size))
print("# Start index: {}".format(args.label))
print("# Haar-cascade: {}".format(args.haar_file))
print("===========================\n")
#Ausgabeordner erstellen(Nicht erstellen, wenn der Ordner vorhanden ist)
os.makedirs(args.out, exist_ok=True)
#wird bearbeitet
face_cut(args.imgs_dir, args.out, args.img_size, args.label, args.haar_file)
print("")
if __name__ == '__main__':
main()
Die vorbereiteten Bilder sind wie folgt. Tatsuya Okawa.
** Wenn "Gesicht nicht gefunden" ausgegeben wird, bedeutet dies, dass das Gesicht nicht erkannt werden konnte, dh es konnte nicht als Gesicht erkannt werden **. In diesem Beispiel konnten die beiden unteren nicht als Gesichter erkannt werden.
Beide haben geneigte Gesichter. Es ist kein Problem, wenn es bis zu einem gewissen Grad geneigt ist, aber es scheint nutzlos zu sein, wenn es in einem Winkel wie das Bild geneigt ist. Wenn Sie das Gesicht wirklich ausschneiden möchten, müssen Sie eine affine Konvertierung für das Bild durchführen.
Anders als diese beiden, so
Es wurde grau skaliert und nur das Gesicht wurde ausgeschnitten und in der Größe geändert. Es spielt keine Rolle, ob Sie eine Brille tragen. (Das Tragen von Sonnenbrillen und Masken kann schwierig sein ...)
Befehl
python face_cut.py -d <Bildordner> (-o <Ziel> -s <Größengröße> -l <Index> -c <Kaskade>)
Das Speicherziel der verarbeiteten Bilddaten ist standardmäßig ". / Result_crop". Die Haar-Cascade-Spezifikation lautet standardmäßig ". / Haar_cascade.xml". Außerdem beträgt die Größenänderung 32 x 32 Pixel und der Index ist standardmäßig 1.
Verwenden Sie die Funktion face_cut, um das Gesicht in Graustufen zu skalieren, zu schneiden und seine Größe zu ändern.
Laden Sie zuerst die Haar-Kaskade, mit der das Gesicht erkannt und ausgeschnitten wird.
# Haar-Wie Feature Cascade Typ Klassifikator Lesen
cascade = cv2.CascadeClassifier(HAAR_FILE)
HAAR_FILE
ist der durch die Befehlsoption angegebene Haar-Kaskadenpfad.
Die folgende Verarbeitung lädt das Bild, skaliert es in Graustufen und erkennt das Gesicht.
#Datenverarbeitung
for img_name in natsorted(os.listdir(imgs_dir)):
print("Bilddaten:{}".format(img_name))
#Nur JPG-Format
_, ext = os.path.splitext(img_name)
if ext.lower() == '.jpg':
img_path = os.path.join(imgs_dir, img_name) #Dateipfade kombinieren
img = cv2.imread(img_path) #Daten gelesen
img_g = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) #In Graustufen konvertieren
face = cascade.detectMultiScale(img_g) #Gesicht erkennen
Dieses Mal werden nur ** JPEG-Dateien als Ziel ausgewählt **, Wenn Sie "if ext.lower () ==". Jpg ":" auf ".png " oder "Bmp" setzen, können Sie die Datei verarbeiten.
Konvertieren Sie ein RGB-Bild mit cv2.cvtColor ()
in ein Graustufenbild.
Danach wird "cascade.detectMultiScale ()" verwendet, um das Gesicht mithilfe der Haar-Kaskade zu erkennen.
img_g = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) #In Graustufen konvertieren
face = cascade.detectMultiScale(img_g) #Gesicht erkennen
cascade.detectMultiScale ()
gibt ** die x- und y-Koordinaten, die Breite und die Höhe des erkannten Ortes ** zurück, wenn ein Gesicht erkannt wird.
Wenn das Gesicht nicht erkannt wird, wird nichts zurückgegeben.
#Wenn kein Gesicht erkannt wird
if len(face) == 0:
print("Face not found.")
else:
for x,y,w,h in face:
#Schneiden Sie das Gesicht aus
face_cut = img_g[y:y+h, x:x+w]
#Größe ändern
face_img = cv2.resize(face_cut, (img_size, img_size))
#sparen
result_img_name = '\data' + str(label) + '.jpg'
cv2.imwrite(os.path.join(result_out + result_img_name), face_img)
label += 1
print("Processing success!!")
else:
print("Unsupported file extension")
Im folgenden Prozess wird das Gesicht basierend auf den zurückgegebenen Informationen ausgeschnitten.
#Schneiden Sie das Gesicht aus
face_cut = img_g[y:y+h, x:x+w]
Es sieht aus wie in der Abbildung unten. (Es ist schwer zu sehen ...)
Ändern Sie nach dem Schneiden die Größe mit "cv2.resize ()" auf die angegebene Größe und speichern Sie sie.
das ist alles. Ich denke nicht, dass es notwendig ist, die Hauptfunktion zu erklären, deshalb werde ich sie weglassen.
Ich habe Data Scraping und dieses Programm verwendet, um Trainingsdaten zu sammeln. Wenn Sie nicht besonders darauf eingehen, können Sie es genug verwenden.
Wie in [Ausführungsergebnis] erwähnt (https://qiita.com/hima_zin331/items/c4160c5c31888e2066a4#%E5%AE%9F%E8%A1%8C%E7%B5%90%E6%9E%9C) Es gibt Grenzen. Im Fall eines Profils ist auch eine Haar-Kaskade enthalten, die dem Profil gewidmet ist. Sie können diese also verwenden. Außerdem ** gibt es einige Fehlalarme, sodass eine Datenbereinigung ** (Eliminierung von Bildern mit Nicht-Gesichtsschnitten) ** erforderlich ist **.
Recommended Posts