[PYTHON] Schneiden wir das Gesicht aus dem Bild

Überblick

Ich habe ein Programm erstellt, das Gesichter mit der von OpenCV bereitgestellten Haar-Like-Funktion Cascade erkennt und automatisch ausschneidet.

Umgebung

-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

Referenz

** 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))

Programm

Ich werde es auf Github posten.

https://github.com/himazin331/Face-Cropping Das Repository enthält das Datenverarbeitungsprogramm Haar-Cascade

Annahme

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.

Quellcode

** 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()

Ausführungsergebnis

Die vorbereiteten Bilder sind wie folgt. Tatsuya Okawa. image.png

image.png

** 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. image.png

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 image.png

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.

Erläuterung

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 ...) image.png

Ä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.

abschließend

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

Schneiden wir das Gesicht aus dem Bild
Lassen Sie uns von der Linie suchen
Entfernen Sie den Rahmen aus dem Bild
Lassen Sie uns den Entwicklungsstatus der Stadt anhand des Satellitenbildes erraten.
Ich habe versucht, ein Standbild aus dem Video auszuschneiden
Gesichtserkennung aus mehreren Bilddateien mit openCV, ausschneiden und speichern
Laden Sie Bilder aus einer Textdatei herunter, die die URL enthält
Wenden wir die Markenbildfarbe auf die Farbkarte von matplotlib an!
Ich habe versucht, Iris aus dem Kamerabild zu erkennen
Identifizieren Sie den Namen aus dem Blumenbild mit Keras (Tensorfluss)
Extrahierter Text aus dem Bild
Fügen wir es der Umgebungsvariablen mit dem Befehl ~ hinzu
Ich möchte mit Python nur das Gesicht aus einem Personenbild ausschneiden und speichern ~ Gesichtserkennung und Zuschneiden mit face_recognition ~
Speichern Sie das Eingangsvideo von der Aufnahmekarte als Bild
Ich habe versucht, das Gesicht aus dem Video zu erkennen (OpenCV: Python-Version)
Punkt entsprechend dem Bild
Lassen Sie uns die Luft Gacha drehen
Ich habe vom Terminal getwittert!
Schneiden Sie das PyTorch-Berechnungsdiagramm aus
Umrisse das Gesicht mit Dlib (1)
Das Bild ist Namekuji
Suchen Sie mit Pythonista3 nach einem Bild von der Kamerarolle
Lassen Sie uns vorerst Googles Vision API von Python berühren