Bishe – Gesichtserkennung basierend auf Deep Learning (detaillierte Schritte + Code)

Ich habe in letzter Zeit nichts zu tun und möchte einen Artikel über Gesichtserkennung basierend auf Deep Learning schreiben. Zur Implementierung verwende ich hauptsächlich zwei verschiedene neuronale Netze, nämlich ein einfaches dreischichtiges Faltungs-Neuronales Netz und ein komplexes VGG16-Neuronales Netz, und vergleiche die Erkennungseffekte der von den beiden Netzen trainierten Modelle. Den Endergebnissen zufolge ist die Wirkung von VGG16, das eine komplexere Struktur aufweist, erwartungsgemäß sogar noch besser. Lassen Sie mich den Implementierungsprozess im Folgenden im Detail vorstellen.

(Angesichts der Tatsache, dass mir viele Freunde privat mitgeteilt haben, dass ich an diesem Projekt interessiert bin, habe ich den Code-Link im Kommentarbereich angehängt. Wenn Sie ihn benötigen, helfen Sie sich bitte selbst. Wenn Sie ihn nützlich finden, denken Sie daran, ihn zu liken es und Post Q~~~)

Als nächstes werde ich es in der folgenden Reihenfolge erklären:

Umgebungskonfiguration
Gesichtserkennungsteil
Trainingsmodellteil
Gesichtserkennungsteil
 

1. Umgebungskonfiguration

①Python3.6 (Obwohl das aktuelle Python aufgrund des Tensorflow-Frameworks auf Version 3.9 aktualisiert wurde
Für Anacondas Anforderungen wird hier weiterhin Version 3.6 ausgewählt)
②opencv (opencv_python-4.4.0-cp36-cp36m-win_amd64, es gibt keine spezifische Begrenzung der Versionsnummer,
Muss aber Python3.6 unterstützen)
③scipy1.2.0 (Sie müssen darauf achten. Wenn Sie dieses Paket mit pip install scipy installieren, installieren Sie normalerweise Version 1.3+. In meinem Programm wird ein Fehler gemeldet, da ich die Methode in Version 1.2 verwendet habe. In This Methode wurde in Version 1.3 aufgegeben)
④tensorflow1.9
⑤keras2.2.0
⑥sklearn (scikit_learn-0.24.1-Version)
⑦tkinder (keine besonderen Anforderungen, dieses Design verwendet die neueste Version)

Wenn Sie bei der Installation dieser Bibliotheken die Pip-Installationsmethode verwenden, wird übrigens empfohlen, diese Methode zu verwenden. Andernfalls erhalten Sie bei der Installation mit anderen Methoden eine Fehlermeldung (ein Ratschlag eines Betrügers, haha). Die Konfiguration Es geht darum. Das ist alles. Einige davon werden möglicherweise nicht aufgeschrieben, und Sie müssen möglicherweise einige Konfigurationsfallen überwinden. (Werden Sie hier eine Ohrfeige bekommen?)

2. Gesichtserkennung
Dieser Teil verwendet hauptsächlich opencv, um die Kamera aufzurufen und die Bildverarbeitung durchzuführen, und verwendet dann eine auf Kaskadenklassifikator + Haarfunktion basierende Methode zur Gesichtserkennung. Opencv ist sehr bequem zu verwenden. Hier werden nur sehr wenige Funktionen verwendet, nämlich das normale Lesen von Bildern, die Graustufenkonvertierung, die Bildanzeige und die einfache Bildbearbeitung.

1) Lesen Sie das Bild

Geben Sie einfach den Pfad des Bildes an, das bearbeitet werden soll.

import cv2
image = cv2.imread(imagepath)


2) Graustufenkonvertierung

Der Zweck der Graustufenkonvertierung besteht darin, die Rechenintensität der in Graustufen konvertierten Bilder zu reduzieren. Da es sich bei den aktuellen Farbbildern ausschließlich um Dreikanaldaten ohne Verarbeitung handelt, ist die Datenmenge sehr groß und kann von den von unseren Schülern verwendeten Maschinen nicht gespeichert werden.

import cv2
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)


Das graue Bild sieht wahrscheinlich so aus.

3) Zeichne Bilder

Ein Ausdruck der Leistungsfähigkeit von opencv besteht darin, dass es Bilder beliebig bearbeiten und verarbeiten kann.

Der letzte Parameter der folgenden Funktion gibt die Größe des Pinsels an. Tatsächlich dient es dazu, den erkannten Gesichtsrand zu verfolgen.

import cv2
cv2.rectangle(image,(x,y),(x+w,y+w),(0,255,0),2)

4) Bild anzeigen

Das bearbeitete Bild wird entweder direkt angezeigt oder auf einem physischen Speichermedium gespeichert.

import cv2
cv2.imshow("Image Title",image)


5) Erhalten Sie Trainingsdaten für die Gesichtserkennung

Es scheint kompliziert zu sein, aber es handelt sich tatsächlich um eine Beschreibung von Gesichtsmerkmalen. Auf diese Weise kann opencv nach dem Lesen der Daten die Merkmale der gelesenen Bilder basierend auf den Beispieldaten im Training erkennen und dann eine Gesichtserkennung an den Bildern durchführen.

import cv2
face_cascade = cv2.CascadeClassifier(r'./haarcascade_frontalface_default.xml')


Die darin enthaltene XML-Datei ist sehr wichtig. Man kann sagen, dass sie der Kern dieses Modells ist und auf sie angewiesen ist, um Gesichtsdaten zu erhalten. Es handelt sich um universell trainierte Daten, die von opencv auf GitHub geteilt werden. Wir können es direkt verwenden.

6) Gesichter erkennen

Vereinfacht gesagt handelt es sich dabei um den Prozess der Identifizierung neuer Bilder anhand von Trainingsdaten.

import cv2
# 探测图片中的人脸
 
faces = face_cascade.detectMultiScale(
   gray,
   scaleFactor = 1.15,
   minNeighbors = 5,
   minSize = (5,5),
   flags = cv2.cv.CV_HAAR_SCALE_IMAGE
)


Wir können die Werte der darin enthaltenen Parameter beliebig angeben, um eine Erkennung mit unterschiedlicher Genauigkeit zu erreichen. Der Rückgabewert spiegelt das Erkennungsergebnis des Bildes durch opencv wider.

Verarbeitung der Ergebnisse der Gesichtserkennung

Nachdem wir gerade die Gesichtserkennung abgeschlossen haben, können wir den Rückgabewert zur weiteren Verarbeitung abrufen. Das heißt aber nicht, dass es kompliziert wird, es geht lediglich darum, Punkteigenwerte hinzuzufügen.

import cv2
 
print "发现{0}个人脸!".format(len(faces))
for(x,y,w,h) in faces:
   cv2.rectangle(image,(x,y),(x+w,y+w),(0,255,0),2)


Das Obige hat einige notwendige Funktionen eingeführt, einschließlich Funktionen zur Gesichtserkennung. Dann werden wir über dieses Modell sprechen. Es ist eigentlich einfach, über das Modell zu sprechen: Erhalten Sie zuerst die Trainingsdaten, schreiben Sie dann das Modelltraining und erkennen Sie schließlich den Effekt. Lassen Sie uns in dieser Reihenfolge zunächst darüber sprechen, wie Gesichtsdaten erfasst werden.

Wir müssen nur Bilder von zwei Personen sammeln. Unter Berücksichtigung der Laptopkonfiguration jedes Einzelnen muss jede Person nur ein paar hundert Bilder sammeln. Der Dateiname lautet get_face.py und der Code lautet wie folgt:

def CatchPICFromVideo(window_name, camera_idx, catch_pic_num, path_name):
    cv2.namedWindow(window_name)
    # 视频来源,可以来自一段已存好的视频,也可以直接来自USB摄像头
    cap = cv2.VideoCapture(camera_idx)
 
    # 告诉OpenCV使用人脸识别分类器
    data_path = "haarcascade_frontalface_default.xml"
    classfier = cv2.CascadeClassifier(data_path)
 
    # 识别出人脸后要画的边框的颜色,RGB格式
    color = (0, 255, 0)
 
    num = 0
    while cap.isOpened():
        ok, frame = cap.read()  # 读取一帧数据
        if not ok:
            break
 
        grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # 将当前桢图像转换成灰度图像
        # 人脸检测,1.2和2分别为图片缩放比例和需要检测的有效点数
        faceRects = classfier.detectMultiScale(grey, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))
        if len(faceRects) > 0:  # 大于0则检测到人脸
            for faceRect in faceRects:  # 单独框出每一张人脸
                x, y, w, h = faceRect
 
                # 将当前帧保存为图片
                img_name = '%s/%d.jpg ' %(path_name, num)
                image = frame[y - 10: y + h + 10, x - 10: x + w + 10]
                cv2.imwrite(img_name, image)
                num += 1
                if num > catch_pic_num:  # 如果超过指定最大保存数量退出循环
                    break
 
                # 画出矩形框
                cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 2)
 
                # 显示当前捕捉到了多少人脸图片
                font = cv2.FONT_HERSHEY_SIMPLEX
                cv2.putText(frame ,'num:%d' % (num) ,(x + 30, y + 30), font, 1, (255 ,0 ,255) ,4)
 
                # 超过指定最大保存数量结束程序
        if num > catch_pic_num:
            break
 
        # 显示图像
        cv2.imshow(window_name, frame)
        c = cv2.waitKey(10)
        if c & 0xFF == ord('q'):
            break
    # 释放摄像头并销毁所有窗口
    cap.release()
    cv2.destroyAllWindows()


 

3. Trainingsmodell
Nachdem wir die Daten erhalten haben, besteht der nächste Schritt darin, das Modelltraining zu schreiben. Ich habe jeweils zwei Modelle verwendet. Das folgende Modell wird mit 3 Faltungsoperationen + 1 vollständigen Verbindungsoperation implementiert. Wenn es sich um VGG16 handelt, ändern Sie einfach die folgenden Teile. Die anderen Teile des Codes sind gleich.

Der Modellcode lautet wie folgt:

def build_model(self, dataset, nb_classes=2):
        # 构建一个空的网络模型,它是一个线性堆叠模型,各神经网络层会被顺序添加,专业名称为序贯模型或线性堆叠模型
        self.model = Sequential()
 
        # 以下代码将顺序添加CNN网络需要的各层,一个add就是一个网络层
        self.model.add(Convolution2D(32, 3, 3, border_mode='same',
                                     input_shape=dataset.input_shape))  # 1 2维卷积层
        self.model.add(Activation('relu'))  # 2 激活函数层
 
        self.model.add(MaxPooling2D(pool_size=(2, 2)))  # 5 池化层
        self.model.add(Dropout(0.25))  # 6 Dropout层
 
        self.model.add(Convolution2D(64, 3, 3, border_mode='same'))  # 7  2维卷积层
        self.model.add(Activation('relu'))  # 8  激活函数层
 
        self.model.add(MaxPooling2D(pool_size=(2, 2)))  # 11 池化层
        self.model.add(Dropout(0.25))  # 12 Dropout层
 
        self.model.add(Flatten())  # 13 Flatten层
        self.model.add(Dense(512))  # 14 Dense层,又被称作全连接层
        self.model.add(Activation('relu'))  # 15 激活函数层
        self.model.add(Dropout(0.5))  # 16 Dropout层
        self.model.add(Dense(nb_classes))  # 17 Dense层
        self.model.add(Activation('softmax'))  # 18 分类层,输出最终结果
 
        # 输出模型概况
        self.model.summary()
因为是用keras写的,所以看起来比较简洁。

训练模型的函数也很简洁

sgd = SGD(lr=0.01, decay=1e-6,
                  momentum=0.9, nesterov=True)  # 采用SGD+momentum的优化器进行训练,首先生成一个优化器对象
        self.model.compile(loss='categorical_crossentropy',
                           optimizer=sgd,
                           metrics=['accuracy'])  # 完成实际的模型配置工作


Noch etwas hier: Wir wissen, dass wir, wenn wir feststellen wollen, wer zwei Personen sind, die Fotos der beiden Personen während des Trainings klassifizieren müssen. Beispielsweise ist A als 0 und B als 1 markiert. Auch dieses Modell wird auf diese Weise trainiert. Die Funktion „load_dataset()“ in „load_face.py“ enthält eine Codezeile. Der Code lautet wie folgt:

# 标注数据,'LDY'文件夹下都是我的脸部图像,全部指定为0,另外一个文件夹下是同学的,全部指定为1
labels = np.array([0 if label.endswith('LDY') else 1 for label in labels])


Dieser Teil der Datei muss ebenfalls geändert werden, d. h. „LDY“ in den Namen Ihres eigenen Ordners ändern.

Wenn Sie mehrere Personen identifizieren möchten, müssen Sie auch hier Tricks anwenden. Ich habe hier 0 und 1 markiert, damit jeder natürlich weiß, dass ich die Identifizierung von zwei Personen durchführe. Wenn Sie mehr Personen identifizieren möchten, machen Sie einfach mehr Markierungen.

Schließlich gibt es noch eine Stelle, die geändert werden muss, nämlich den Hauptfunktionsteil der train.py-Datei:

# 此处文件地址是你收集的图片的文件夹地址
    dataset = Dataset('D:\PyCharm-Community\Workplace\Face_Recognition\\face_data')
    dataset.load()
    model = Model()
    model.build_model(dataset)
    model.train(dataset)
# 此处地址是你保存训练好模型的地址
    model.save_model(file_path='D:\PyCharm-Community\Workplace\Face_Recognition\\face_data\model\ldy_face_model.h5')
    model.evaluate(dataset)


 

4. Gesichtserkennung
Nachdem das Modell trainiert wurde, können Sie es endlich mit Fotos testen.

Der Dateiname lautet: Face_recognition.py, der Code lautet wie folgt:

if __name__ == '__main__':
    if len(sys.argv) != 1:
        print("Usage:%s camera_id\r\n" % (sys.argv[0]))
        sys.exit(0)
 
    # 加载模型
    model = Model()
    model.load_model(file_path='D:\PyCharm-Community\Workplace\Face_Recognition\model\jianxin_face_model.h5')
 
    # 框住人脸的矩形边框颜色
    color = (0, 255, 0)
 
    # 捕获指定摄像头的实时视频流
    cap = cv2.VideoCapture(0)
 
    # 人脸识别分类器本地存储路径
    cascade_path = "D:\opencv\\build\etc\haarcascades\haarcascade_frontalface_default.xml"
 
    # 循环检测识别人脸
    while True:
        ret, frame = cap.read()  # 读取一帧视频
 
        if ret is True:
 
            # 图像灰化,降低计算复杂度
            frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        else:
            continue
        # 使用人脸识别分类器,读入分类器
        cascade = cv2.CascadeClassifier(cascade_path)
 
        # 利用分类器识别出哪个区域为人脸
        faceRects = cascade.detectMultiScale(frame_gray, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))
        if len(faceRects) > 0:
            for faceRect in faceRects:
                x, y, w, h = faceRect
 
                # 截取脸部图像提交给模型识别这是谁
                image = frame[y - 10: y + h + 10, x - 10: x + w + 10]
                faceID = model.face_predict(image)
                print("faceID", faceID)
                # 如果是“我”
                if faceID == 0:
                    cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, thickness=2)
                    # 文字提示是谁
                    cv2.putText(frame, 'Chengjianxin',
                                (x + 30, y + 30),  # 坐标
                                cv2.FONT_HERSHEY_SIMPLEX,  # 字体
                                1,  # 字号
                                (255, 0, 255),  # 颜色
                                2)  # 字的线宽
                else:
                    cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, thickness=2)
                    cv2.putText(frame, 'Nobody',
                                (x + 30, y + 30),  # 坐标
                                cv2.FONT_HERSHEY_SIMPLEX,  # 字体
                                2,  # 字号
                                (255, 0, 0),  # 颜色
                                2)  # 字的线宽
                    pass
 
        cv2.imshow("Face Recognition", frame)
 
        # 等待10毫秒看是否有按键输入
        k = cv2.waitKey(10)
        # 如果输入q则退出循环
        if k & 0xFF == ord('q'):
            break
 
    # 释放摄像头并销毁所有窗口
    cap.release()
    cv2.destroyAllWindows()
其中有3处地方需要修改

# 加载模型
model = Model()
model.load_model(file_path='D:\PyCharm-Community\Workplace\Face_Recognition\model\jianxin_face_model.h5')
模型地址改成你自己的。

# 人脸识别分类器本地存储路径
cascade_path = "D:\opencv\\build\etc\haarcascades\haarcascade_frontalface_default.xml"
这个xml文件地址也改成你自己的,前面的get_face.py也是这样。

# 如果是“我”
if faceID == 0:
   cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, thickness=2)
   # 文字提示是谁
   cv2.putText(frame, 'Chengjianxin',
                     (x + 30, y + 30),  # 坐标
                     cv2.FONT_HERSHEY_SIMPLEX,  # 字体
                     1,  # 字号
                     (255, 0, 255),  # 颜色
                     2)  # 字的线宽
else:
   cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, thickness=2)
   cv2.putText(frame, 'Nobody',
                    (x + 30, y + 30),  # 坐标
                    cv2.FONT_HERSHEY_SIMPLEX,  # 字体
                    2,  # 字号
                    (255, 0, 0),  # 颜色
                    2)  # 字的线宽


Ändern Sie einfach die Textaufforderungen hier in Ihre eigenen.

Supongo que te gusta

Origin blog.csdn.net/weixin_44791757/article/details/118551673
Recomendado
Clasificación