[PYTHON] Versuchen wir nun die Gesichtserkennung mit Chainer (Vorhersagephase).

Überblick

Dies ist eine Fortsetzung von Versuchen wir die Gesichtserkennung mit Chainer (Lernphase), und diesmal ist es die Vorhersagephase.

Versuchen wir die Gesichtserkennung mit einer über USB angeschlossenen Webcam.

Umgebung

-Software- Windows 10 Home Anaconda3 64-bit(Python3.7) Spyder -Library- Chainer 7.0.0 opencv-python 4.1.2.30 -Hardware- CPU: Intel core i9 9900K GPU: NVIDIA GeForce RTX2080ti RAM: 16GB 3200MHz (Es kann sogar auf einem PC ausgeführt werden, wenn Sie eine Webcam haben)

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)) Seite? ˅ Chainer-API-Referenz

Programm

Vorerst werde ich es auf Github veröffentlichen. https://github.com/himazin331/Face-Recognition-Chainer- Das Repository enthält eine Lernphase, eine Vorhersagephase, ein Datenverarbeitungsprogramm und 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_recog_CH.py


from PIL import Image
import numpy as np
import cv2

import sys
import os
import argparse as arg

import chainer
import chainer.links as L
import chainer.functions as F
import chainer.serializers as S
  
# ==================================== face_recog_train_CH.Gleiche Netzwerkkonfiguration wie py====================================
class CNN(chainer.Chain):
    def __init__(self, n_out):
        super(CNN, self).__init__(
            conv1=L.Convolution2D(1, 16, 5, 1, 0),  
            conv2=L.Convolution2D(16, 32, 5, 1, 0),  
            conv3=L.Convolution2D(32, 64, 5, 1, 0),  
            link=L.Linear(None, 1024),  
            link_class=L.Linear(None, n_out),  
        )
    def __call__(self, x):
        h1 = F.max_pooling_2d(F.relu(self.conv1(x)), ksize=2)
        h2 = F.max_pooling_2d(F.relu(self.conv2(h1)), ksize=2)
        h3 = F.relu(self.conv3(h2))
        h4 = F.relu(self.link(h3))
        return self.link_class(h4)
# ================================================================================================================

def main():

    #Optionale Argumente für die Befehlszeile
    parser = arg.ArgumentParser(description='Face Recognition Program(Chainer)')
    parser.add_argument('--param', '-p', type=str, default=None,
                        help='Gelernte Parameter angeben(Fehler, wenn nicht angegeben)')
    parser.add_argument('--cascade', '-c', type=str, default=os.path.dirname(os.path.abspath(__file__))+'/haar_cascade.xml'.replace('/', os.sep),
                        help='Haar-Spezifikation der Kaskade(Standardwert=./haar_cascade.xml)')
    parser.add_argument('--device', '-d', type=int, default=0,
                        help='Angeben der Kamera-Geräte-ID(Standardwert=0)')
    args = parser.parse_args()

    #Wenn keine Parameterdatei angegeben ist->Ausnahme
    if args.param == None:
        print("\nException: Trained Parameter-File not specified.\n")
        sys.exit()
    #Wenn eine nicht vorhandene Parameterdatei angegeben wird->Ausnahme
    if os.path.exists(args.param) != True:
        print("\nException: Trained Parameter-File {} is not found.\n".format(args.param))
        sys.exit()
    #Haar, das es nicht gibt-Wenn Kaskade angegeben ist->Ausnahme
    if os.path.exists(args.cascade) != True:
        print("\nException: Haar-cascade {} is not found.\n".format(args.cascade))
        sys.exit()

    #Informationsausgabe einstellen
    print("=== Setting information ===")
    print("# Trained Prameter-File: {}".format(os.path.abspath(args.param)))
    print("# Haar-cascade: {}".format(args.cascade))
    print("# Camera device: {}".format(args.device))
    print("===========================")

    #Generierung von Kamerainstanzen
    cap = cv2.VideoCapture(args.device)
    #FPS-Werteinstellung
    cap.set(cv2.CAP_PROP_FPS, 60)
    
    #Satz Gesichtsdetektoren
    detector = cv2.CascadeClassifier(args.cascade)

    #Gelernte Parameter laden
    model = L.Classifier(CNN(2))
    S.load_npz(args.param, model)

    red = (0, 0, 255)
    green = (0, 255, 0)
    p = (10, 30)
    
    while True:

        #Holen Sie sich Rahmen
        _, frame = cap.read()

        #Kameraerkennung nicht möglich->Ausnahme
        if _ == False:
            print("\nException: Camera read failure.\n".format(args.param))
            sys.exit()

        #Gesichtserkennung
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = detector.detectMultiScale(gray)
 
        #Gesicht unentdeckt->continue
        if len(faces) == 0:

            cv2.putText(frame, "face is not found",
                    p, cv2.FONT_HERSHEY_SIMPLEX, 1.0, red, thickness=2)
            cv2.imshow("frame", frame)
            
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

            continue
        
        #Wenn das Gesicht erkannt wird
        for (x, y, h, w) in faces:
            
            #Gesichtsbereichsanzeige
            cv2.rectangle(frame, (x, y), (x+w, y+h), red, thickness=2) 
            
            #Durch, wenn das Gesicht zu klein ist
            if h < 50 and w < 50:
                cv2.putText(frame, "detected face is too small",
                    p, cv2.FONT_HERSHEY_SIMPLEX, 1.0, red, thickness=2)
                cv2.imshow("frame", frame)
                break
                
            #Zeigen Sie das erkannte Gesicht an
            cv2.imshow("gray", cv2.resize(gray[y:y + h, x:x + w], (250, 250)))
                    
            #Bildverarbeitung
            face = gray[y:y + h, x:x + w]
            face = Image.fromarray(face)
            face = np.asarray(face.resize((32, 32)), dtype=np.float32)
            recog_img = face[np.newaxis, :, :]
                    
            #Gesichtserkennung
            y = model.predictor(chainer.Variable(np.array([recog_img])))
            c = F.softmax(y).data.argmax()
            
            if c == 0:
                cv2.putText(frame, "Unknown",
                    p, cv2.FONT_HERSHEY_SIMPLEX, 1.0, green, thickness=2)     
            elif c == 1:
                cv2.putText(frame, "Kohayakawa",
                    p, cv2.FONT_HERSHEY_SIMPLEX, 1.0, green, thickness=2)    
                
            cv2.imshow("frame", frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
  
    
    #Ressourcenfreigabe
    cap.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()

Ausführungsergebnis

Dieses Mal habe ich versucht, Shinzo Abe und Taro Aso zu identifizieren. Die Anzahl der Trainingsdaten beträgt für beide 100. abe.png aso.png

Befehl

python face_recog_CH.py -p <Parameterdatei> -c <Kaskade> (-d <Kamera-Geräte-ID>)

Erläuterung

Da es sich um die Vorhersagephase handelt, handelt es sich um ein Programm, das das Gesicht mit einer Kamera identifiziert.

Netzwerkmodell

CNN-Klasse, aber genau das gleiche wie das Netzwerkmodell der Lernphase (face_recog_train_CH.py) Bitte beschreiben Sie, wie es ist. Es wird nicht funktionieren, wenn die Struktur etwas anders ist. Unterschiedliche Hyperparameter und Ebenen haben unterschiedliche Anzahlen von Parametern wie Gewichten, also lernoptimierte Parameter. Kann nicht angewendet werden.

CNN-Klasse


# ==================================== face_recog_train_CH.Gleiche Netzwerkkonfiguration wie py====================================
class CNN(chainer.Chain):
    def __init__(self, n_out):
        super(CNN, self).__init__(
            conv1=L.Convolution2D(1, 16, 5, 1, 0),  
            conv2=L.Convolution2D(16, 32, 5, 1, 0),  
            conv3=L.Convolution2D(32, 64, 5, 1, 0),  
            link=L.Linear(None, 1024),  
            link_class=L.Linear(None, n_out),  
        )
    def __call__(self, x):
        h1 = F.max_pooling_2d(F.relu(self.conv1(x)), ksize=2)
        h2 = F.max_pooling_2d(F.relu(self.conv2(h1)), ksize=2)
        h3 = F.relu(self.conv3(h2))
        h4 = F.relu(self.link(h3))
        return self.link_class(h4)
# ================================================================================================================

installieren

Es erstellt eine Kamerainstanz, lädt eine Kaskade und importiert Parameter.

    #Generierung von Kamerainstanzen
    cap = cv2.VideoCapture(args.device)
    #FPS-Werteinstellung
    cap.set(cv2.CAP_PROP_FPS, 60)
    
    #Satz Gesichtsdetektoren
    detector = cv2.CascadeClassifier(args.cascade)

Wenden Sie mit "chainer.serializers.load_npz ()" Parameter auf das Netzwerkmodell an. Beachten Sie, dass ich in der Lernphase das Modell mit "L.Classifier ()" umbrochen und eine Instanz erstellt habe. Sie müssen das Modell auch in der Vorhersagephase in "L.Classifier ()" einschließen.

    #Gelernte Parameter laden
    model = L.Classifier(CNN(2))
    S.load_npz(args.param, model)

Gesichtserkennung

Machen Sie zuerst ein Bild mit der Kamera. Sie können mit "cap.read ()" schießen. Wenn Sie "cap.read ()" einmal ausführen, erhalten Sie ein Standbild. Verwenden Sie die while-Anweisung und die for-Anweisung, um "cap.read ()" nacheinander auszuführen, und geben Sie die erhaltenen Standbilder kontinuierlich aus, damit sie so aussehen, als würden sie sich bewegen.

cap.read () gibt zwei Werte zurück. Das erste ist eine Flagge (_ im Code), ob ein Schießen möglich ist oder nicht. Das zweite tatsächlich aufgenommene Standbild (Frame im Code).

Im Folgenden wird das Standbild als Rahmen bezeichnet.

    while True:

        #Holen Sie sich Rahmen
        _, frame = cap.read()

        #Kameraerkennung nicht möglich->Ausnahme
        if _ == False:
            print("\nException: Camera read failure.\n".format(args.param))
            sys.exit()

        #Gesichtserkennung
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = detector.detectMultiScale(gray)
 
        #Gesicht unentdeckt->continue
        if len(faces) == 0:

            cv2.putText(frame, "face is not found",
                    p, cv2.FONT_HERSHEY_SIMPLEX, 1.0, red, thickness=2)
            cv2.imshow("frame", frame)
            
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

            continue

Nach dem Erfassen des Rahmens wird der Rahmen grau skaliert und die Gesichtserkennung wird unter Verwendung von Cascade durchgeführt, einer haarähnlichen Funktion. detector.detectMultiScale () gibt Informationen zur Erkennungsposition (Koordinaten und Breite Höhe) zurück, wenn ein Gesicht erkannt wird und wenn es nicht erkannt werden kann. Ich werde nichts zurückgeben.

Wenn ein Gesicht nicht erkannt werden kann, wird im Fenster "Gesicht wird nicht gefunden" ausgegeben und fortgefahren.


Ich werde die Verarbeitung erklären, wenn ein Gesicht erkannt wird.

Die Bildverarbeitung wird unter Verwendung der x- und y-Koordinaten, der Breite und der Höhe des zurückgegebenen Erkennungsorts durchgeführt.

        #Wenn das Gesicht erkannt wird
        for (x, y, h, w) in faces:
            
            #Gesichtsbereichsanzeige
            cv2.rectangle(frame, (x, y), (x+w, y+h), red, thickness=2) 
            
            #Durch, wenn das Gesicht zu klein ist
            if h < 50 and w < 50:
                cv2.putText(frame, "detected face is too small",
                    p, cv2.FONT_HERSHEY_SIMPLEX, 1.0, red, thickness=2)
                cv2.imshow("frame", frame)
                break
                
            #Zeigen Sie das erkannte Gesicht an
            cv2.imshow("gray", cv2.resize(gray[y:y + h, x:x + w], (250, 250)))
                    
            #Bildverarbeitung
            face = gray[y:y + h, x:x + w]
            face = Image.fromarray(face)
            face = np.asarray(face.resize((32, 32)), dtype=np.float32)
            recog_img = face[np.newaxis, :, :]
                    
            #Gesichtserkennung
            y = model.predictor(chainer.Variable(np.array([recog_img])))
            c = F.softmax(y).data.argmax()
            
            if c == 0:
                cv2.putText(frame, "Abe Sinzo",
                    p, cv2.FONT_HERSHEY_SIMPLEX, 1.0, green, thickness=2)     
            elif c == 1:
                cv2.putText(frame, "Aso Taro",
                    p, cv2.FONT_HERSHEY_SIMPLEX, 1.0, green, thickness=2)    
                
            cv2.imshow("frame", frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

Die Bildverarbeitung ist konkret ① Schneiden Sie den Gesichtsbereich aus dem Rahmen aus ② Konvertieren Sie einmal von Array zu Bild, um die Größe des Gesichtsbereichs zu ändern ③ Ändern Sie die Größe auf 32 x 32 Pixel ④ Fügen Sie die Dimension des Arrays hinzu (Addition der Anzahl der Kanäle, [Anzahl der Kanäle, Höhe, Breite]) Ich mache.

Wenn wir nun die Daten in eine identifizierbare Form bringen können, ist es endlich Zeit, das Gesicht zu erkennen. y = model.predictor(chainer.Variable(np.array([recog_img]))) Beginnen Sie die Vorhersage mit. chainer.Variable () ist eine Funktion, die Daten einer Kettenregel zuordnet. Verwenden Sie als Nächstes c = F.softmax (y) .data.argmax (), um das Vorhersageergebnis durch die Softmax-Funktion zu leiten, und verwenden Sie dann argmax. Das größte Element (Index) wird zurückgegeben.

Und schließlich wird mit der if-Anweisung der Klassenname ausgegeben, der dem Element (Index) entspricht.

Dieses Mal gibt es zwei Klassen, Shinzo Abe und Taro Aso, aber lernen wir ein Gesicht, das keines von beiden ist. Wenn Sie ein Gesicht eingeben, das weder Shinzo Abe noch Taro Aso ist, können Sie so etwas wie "weder" ausgeben.

abschließend

Ursprünglich wurden diese Programme in der High-School-Aufgabenforschung (Abschlussforschung) entwickelt, daher ist der Code angemessen. Sie können die Anzahl der zu klassifizierenden Klassen leicht ändern, solange Sie über Lerndaten verfügen. Machen Sie also bitte, was Sie möchten.

Recommended Posts

Versuchen wir nun die Gesichtserkennung mit Chainer (Vorhersagephase).
Versuchen wir nun die Gesichtserkennung mit Chainer (Lernphase)
Versuchen Sie die Gesichtserkennung mit Python
Versuchen Sie, Pferderennen mit Chainer vorherzusagen
Versuchen Sie die Gesichtserkennung mit Python + OpenCV
Erste Anime-Gesichtserkennung mit Chainer
[Python3] [Ubuntu16] [Docker] Versuchen Sie die Gesichtserkennung mit OpenFace
Gesichtserkennung mit Edison
Einfacher Gesichtserkennungsversuch mit Jetson Nano und Webkamera
Gesichtserkennung mit OpenCV von Python
Versuchen Sie, RBM mit Chainer zu implementieren.
Gesichtserkennung durch Amazon Rekognition
Gesichtserkennung / Schneiden mit OpenCV
Gesichtserkennung mit Kamera mit opencv3 + python2.7
Versuchen Sie Common Representation Learning mit Chainer
Lassen Sie uns mit Azure Face Emotionen erkennen
Ich habe versucht, das Gesicht mit OpenCV zu erkennen
Versuchen Sie es mit Chainer Deep Q Learning - Launch
Versuchen wir es mit gRPC mit Go und Docker
Gesichtserkennung von Anime-Charakteren mit Keras
[python, openCV] base64 Gesichtserkennung in Bildern
Serverlose Gesichtserkennungs-API mit Python
Kategorisieren Sie Gesichtsbilder von Anime-Charakteren mit Chainer
Versuchen Sie, Ihr Gesicht mit dem AB-Test zu montieren
Bilderkennung mit Caffe Model Chainer Yo!