[Deep Learning] Gesichtserkennungsprojekt basierend auf Convolutional Neural Network (Tensorflow) (4)

Vorwort

Nach Recherchen vor einiger Zeit, von der Einführung von LeNet-5 handschriftlichen Ziffern bis hin zu einer aktuellen Studie zur Wettererkennung. Ich möchte eine große Abstimmung machen, da ich mich mit C++/Qt-Entwicklung beschäftige und mit Qt relativ vertraut bin, daher möchte ich eine schnittstellenbasierte Gesichtserkennung implementieren.

Wenn Sie mit dem Konzept der Convolutional Neural Networks nicht vertraut sind, können Sie sich diesen Artikel ansehen: Was macht Convolution eigentlich?
Wenn Sie den Trainingsprozess von Neuronalen Netzwerken verstehen oder wie man eine Umgebung aufbaut, können Sie dies lesen Artikel: Umgebungskonstruktion und Trainingsprozess

Wenn Sie dieses Projekt lernen möchten, gehen Sie bitte zum
ersten Artikel
: Gesichtserkennungsprojekt basierend auf Convolutional Neural Network (Tensorflow) (1) Teil 2: Gesichtserkennungsprojekt
basierend auf Convolutional Neural Network (Tensorflow) (2)
Teil 2 Drei : Gesichtserkennungsprojekt basierend auf Convolutional Neural Network (Tensorflow) (3)

Die Grundidee

Konkrete Schritte sind wie folgt:

  1. Zuerst müssen Daten gesammelt werden, meine Idee ist, die Kamera über OpenCV anzurufen, um Gesichtsfotos zu sammeln.
  2. Führen Sie dann eine Vorverarbeitung durch, hauptsächlich um den Datensatz, den Trainingssatz, den Validierungssatz und den Testsatz zu klassifizieren.
  3. Um mit dem Training des Modells zu beginnen, erstellen Sie im Voraus Label-Schlüssel/Wert-Paare.
  4. Testen Sie den Gesichtserkennungseffekt, erfassen Sie das Gesichtsfoto über OpenCV, verarbeiten Sie das Bild dann vor und geben Sie es schließlich an das Modell weiter. Drucken Sie dann das Erkennungsergebnis in Form von Text auf dem Bildschirm aus und radeln Sie, bis Sie q zum Beenden eingeben.

Dieser Artikel implementiert hauptsächlich den vierten Schritt in den obigen Schritten. Teilen Sie schließlich den vollständigen Projektcode des gesamten Prozesses.

Testen Sie den Gesichtserkennungseffekt

Gestaltungsideen

Öffnen Sie die Kamera über OpenCV, um den Gesichtsbereich zu erfassen, verarbeiten Sie das Bild dann vor (z. B. Graustufen, Normalisierung usw.), laden Sie dann das Modell, fügen Sie das verarbeitete Bild zur Vorhersage in das Modell ein und führen Sie dann die Vorhersage für das Ergebnis durch. Ein Präzisionsfilter soll berücksichtigen, dass die Erkennungsrate weniger als 90 % des Ergebnisses beträgt, dass die Erkennung ungenau ist, und es wird andere ausgeben, um anzuzeigen, dass es nicht gut erkannt werden kann. Unter normalen Umständen wird das jeder Datei entsprechende Etikett ausgegeben.

Detaillierter Code

Modell laden

Laden Sie das Modell, das wir zuvor trainiert haben, über die Methode load_model.

	MODEL_PATH = './me.face.model.h5'
    def load_model(self, file_path=MODEL_PATH):
        self.model = load_model(file_path)

Gesichtsvorhersage

Hier werden die Bilder normalisiert und die Vorhersageergebnisse präzisionsgefiltert.
Notiz: K.image_dim_ordering() =\= 'th': Wenn ein Fehler gemeldet wird, ersetzen Sie ihn bitte durch K.image_data_format() == 'channels_first'channels_last“ entsprechend dem ursprünglichen „ tf“ und „ channels_first“ entsprechend dem ursprünglichen „ th“.

    def face_predict(self, image):
        if K.image_data_format() == 'channels_first' and image.shape != (1, 3, IMAGE_SIZE, IMAGE_SIZE):
            image = resize_image(image)  # 尺寸必须与训练集一致都应该是IMAGE_SIZE x IMAGE_SIZE
            image = image.reshape((1, 3, IMAGE_SIZE, IMAGE_SIZE))  # 与模型训练不同,这次只是针对1张图片进行预测
        elif K.image_data_format() == 'channels_last' and image.shape != (1, IMAGE_SIZE, IMAGE_SIZE, 3):
            image = resize_image(image)
            image = image.reshape((1, IMAGE_SIZE, IMAGE_SIZE, 3))

        # 浮点并归一化
        image = image.astype('float32')
        image /= 255

        # 给出输入属于各个类别的概率
        result = self.model.predict_proba(image)
        print('result:', result)
        my_result = list(result[0]).index(max(result[0]))
        max_result = max(result[0])
        print("result最大值下标:", my_result)
        if max_result > 0.90:
            return my_result
        else:
            return -1

Hauptlogik

Hauptsächlich in die folgenden Schritte unterteilt:

  1. Modell laden
  2. Vorverarbeitung (Einstellung der Kamera, der Rahmenfarbe des Gesichtsbereichs, des Pfads des Haarklassifikators, des Label-Arrays usw.)
  3. Nehmen Sie einen Bildrahmen auf
  4. Graustufen Sie das Bild
  5. Berechnen Sie die Gesichtsfläche und rahmen Sie sie ein
  6. Übergeben Sie den Gesichtsbereich zur Erkennung an das Erkennungsmodell
  7. Siebdruck der Erkennungsergebnisse
  8. Dann radeln Sie 3-7 Schritte.
  9. Geben Sie q ein, um die Erkennung zu beenden, und geben Sie dann die belegten Ressourcen frei

Diese Logik ist nicht sehr kompliziert, der Code wird direkt darunter angezeigt, und es gibt auch detaillierte Kommentare im Code:

import cv2
from keras_train import Model

if __name__ == '__main__':
    model = Model()# 加载模型
    model.load_model(file_path='./model/me.face.model.h5')
    
    color = (0, 255, 0)# 框住人脸的矩形边框颜色
    
    cap = cv2.VideoCapture(0)# 捕获指定摄像头的实时视频流
    
    cascade_path = "./model/haarcascade_frontalface_alt2.xml"# 人脸识别分类器本地存储路径

    # 循环检测识别人脸
    while True:
        _, frame = cap.read()  # 读取一帧视频

        # 图像灰化,降低计算复杂度
        frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # 使用人脸识别分类器,读入分类器
        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)

                # 
                human = {
    
    0: 'use2', 1: 'use3', 2: 'use4', -1: 'others', 3: 'use5', 4: 'LinXi07',
                         5: 'use7', 6: 'use8', 7: 'use1', 8: 'use9'}

                cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, thickness=2)

                # 文字提示是谁
                cv2.putText(frame, human[faceID],
                            (x + 30, y + 30),  # 坐标
                            cv2.FONT_HERSHEY_SIMPLEX,  # 字体
                            1,  # 字号
                            (255, 0, 255),  # 颜色
                            2)  # 字的线宽

        cv2.imshow("Face Identification System", frame)

        # 等待10毫秒看是否有按键输入
        k = cv2.waitKey(10)
        # 如果输入q则退出循环
        if k & 0xFF == ord('q'):
            break

    # 释放摄像头并销毁所有窗口
    cap.release()
    cv2.destroyAllWindows()

Testeffekt

Das hier getestete Modell unterstützt mehrere Gesichtserkennungen gleichzeitig und die Erkennungsrate ist hoch. ( Gesichter ignorieren )
Bildbeschreibung hier einfügen

Zusammenfassen

Von der initialen Datensammlung über die zwischenzeitliche Vorverarbeitung bis hin zum späteren Modellbau bis hin zum finalen Testeffekt ist der Weg sehr holprig, entweder das Datenformat passt nicht zum Fehler, oder die Version passt nicht hin und her um die Umgebung neu zu installieren und dann die Modellerkennungsrate. Endlich geschafft, der Weg ist holprig, aber die Ernte ist nicht billig. Machen wir es zusammen! ! ! !

alle Codes

Hier klassifiziere ich Dateien für Dateien, insgesamt gibt es vier Dateien.

Dateiname veranschaulichen
frame_capture.py Erstellen Sie einen Datensatz
keras_train.py Trainieren Sie das Modell. Evaluieren Sie das Modell
load_data.py Daten laden, vorverarbeiten
face_predict_use_keras.py Vorhersagemodell

Dann wird deep_learning verwendet, um das Foto jeder Person zu speichern. model wird verwendet, um das Modell und den harr-Klassifikator zu speichern.
Bildbeschreibung hier einfügen

face_predict_use_keras.py

import cv2
import sys

def catch_usb_video(window_name, camera_idx):
    '''使用cv2.imshow()的时候,如果图片太大,会显示不全并且无法调整。
    因此在cv2.imshow()的前面加上这样的一个语句:cv2.namedWindow('image', 0),
    得到的图像框就可以自行调整大小,可以拉伸进行自由调整。'''
    cv2.namedWindow(window_name, 0)

    # 视频来源,可以来自一段已存好的视频,也可以直接来自USB摄像头
    cap = cv2.VideoCapture(camera_idx)

    # 告诉OpenCV使用人脸识别分类器  级联分类器
    '''
    Haar特征是一种反映图像的灰度变化的,像素分模块求差值的一种特征。它分为三类:边缘特征、线性特征、中心特征和对角线特征。
    '''
    classfier = cv2.CascadeClassifier("./model/haarcascade_frontalface_alt2.xml")
    # 识别出人脸后要画的边框的颜色,RGB格式
    color = (0, 0, 255)
    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))
        #  faceRects = [405 237 222 222]
        if len(faceRects) > 0:  # 大于0则检测到人脸
            for faceRect in faceRects:  # 单独框出每一张人脸
                # 在原图上框出需要保存的图
                x, y, w, h = faceRect
                cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 2)
                # 将当前帧保存为图片
                # frame 是原图,(x - 10, y - 10) 是图片的左上角的那个点,(x + w + 10, y + h + 10)是图片右下角的点
                # color, 2 颜色和线的宽度
                img_name = '%s/%d.jpg' % ('./deep_learning/zm', num)
                image = frame[y - 10: y + h + 10, x - 10: x + w + 10]
                cv2.imwrite(img_name, image)
                num += 1
                if num > (500):  # 如果超过指定最大保存数量退出循环
                    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 > (500):
            break
        # 显示图像
        cv2.imshow(window_name, frame)
        c = cv2.waitKey(1)
        if c & 0xFF == ord('q'):
            break
    # 释放摄像头并销毁所有窗口
    cap.release()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    catch_usb_video("face", 0)

keras_train.py

import random
from sklearn.model_selection import train_test_split
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.optimizers import SGD
from keras.utils import np_utils
from keras.models import load_model
from keras import backend as K
from load_data import load_dataset, resize_image, IMAGE_SIZE

class Dataset:
    def __init__(self, path_name):
        # 训练集
        self.train_images = None
        self.train_labels = None

        # 验证集
        self.valid_images = None
        self.valid_labels = None

        # 测试集
        self.test_images = None
        self.test_labels = None

        # 数据集加载路径
        self.path_name = path_name

        # 当前库采用的维度顺序
        self.input_shape = None

    # 加载数据集并按照交叉验证的原则划分数据集并进行相关预处理工作
    def load(self, img_rows=IMAGE_SIZE, img_cols=IMAGE_SIZE,
             img_channels=3, nb_classes=3):
        # 加载数据集到内存
        images, labels = load_dataset(self.path_name)

        train_images, valid_images, train_labels, valid_labels = train_test_split(images, labels, test_size=0.2,
                                                                                  random_state=random.randint(0, 100))
        _, test_images, _, test_labels = train_test_split(images, labels, test_size=0.5,
                                                          random_state=random.randint(0, 100))

        # 当前的维度顺序如果为'th',则输入图片数据时的顺序为:channels,rows,cols,否则:rows,cols,channels
        # 这部分代码就是根据keras库要求的维度顺序重组训练数据集
       # if K.image_dim_ordering() == 'th':  “channels_last”对应原本的“tf”,“channels_first”对应原本的“th”。
        if K.image_data_format() == 'channels_first':
            train_images = train_images.reshape(train_images.shape[0], img_channels, img_rows, img_cols)
            valid_images = valid_images.reshape(valid_images.shape[0], img_channels, img_rows, img_cols)
            test_images = test_images.reshape(test_images.shape[0], img_channels, img_rows, img_cols)
            self.input_shape = (img_channels, img_rows, img_cols)
        else:
            train_images = train_images.reshape(train_images.shape[0], img_rows, img_cols, img_channels)
            valid_images = valid_images.reshape(valid_images.shape[0], img_rows, img_cols, img_channels)
            test_images = test_images.reshape(test_images.shape[0], img_rows, img_cols, img_channels)
            self.input_shape = (img_rows, img_cols, img_channels)

            # 输出训练集、验证集、测试集的数量
            print(train_images.shape[0], 'train samples')
            print(valid_images.shape[0], 'valid samples')
            print(test_images.shape[0], 'test samples')

            # 我们的模型使用categorical_crossentropy作为损失函数,因此需要根据类别数量nb_classes将
            # 类别标签进行one-hot编码使其向量化,在这里我们的类别只有两种,经过转化后标签数据变为二维
            train_labels = np_utils.to_categorical(train_labels, nb_classes)
            valid_labels = np_utils.to_categorical(valid_labels, nb_classes)
            test_labels = np_utils.to_categorical(test_labels, nb_classes)

            # 像素数据浮点化以便归一化
            train_images = train_images.astype('float32')
            valid_images = valid_images.astype('float32')
            test_images = test_images.astype('float32')

            # 将其归一化,图像的各像素值归一化到0~1区间
            train_images /= 255
            valid_images /= 255
            test_images /= 255

            self.train_images = train_images
            self.valid_images = valid_images
            self.test_images = test_images
            self.train_labels = train_labels
            self.valid_labels = valid_labels
            self.test_labels = test_labels


# CNN网络模型类
class Model:
    def __init__(self):
        self.model = None

        # 建立模型

    def build_model(self, dataset, nb_classes=3):
        # 构建一个空的网络模型,它是一个线性堆叠模型,各神经网络层会被顺序添加,专业名称为序贯模型或线性堆叠模型
        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(Convolution2D(32, 3, 3))  # 3 2维卷积层
        self.model.add(Activation('relu'))  # 4 激活函数层

        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(Convolution2D(64, 3, 3))  # 9  2维卷积层
        self.model.add(Activation('relu'))  # 10 激活函数层

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

        # 训练模型

    def train(self, dataset, batch_size=20, nb_epoch=10, data_augmentation=True):
        # 参数batch_size的作用即在于此,其指定每次迭代训练样本的数量
        # nb_epoch 训练轮换次数
        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'])  # 完成实际的模型配置工作

        # 不使用数据提升,所谓的提升就是从我们提供的训练数据中利用旋转、翻转、加噪声等方法创造新的
        # 训练数据,有意识的提升训练数据规模,增加模型训练量
        if not data_augmentation:
            self.model.fit(dataset.train_images,
                           dataset.train_labels,
                           batch_size=batch_size,
                           nb_epoch=nb_epoch,
                           validation_data=(dataset.valid_images, dataset.valid_labels),
                           shuffle=True)
        # 使用实时数据提升
        else:
            # 定义数据生成器用于数据提升,其返回一个生成器对象datagen,datagen每被调用一
            # 次其生成一组数据(顺序生成),节省内存,其实就是python的数据生成器
            datagen = ImageDataGenerator(
                featurewise_center=False,  # 是否使输入数据去中心化(均值为0),
                samplewise_center=False,  # 是否使输入数据的每个样本均值为0
                featurewise_std_normalization=False,  # 是否数据标准化(输入数据除以数据集的标准差)
                samplewise_std_normalization=False,  # 是否将每个样本数据除以自身的标准差
                zca_whitening=False,  # 是否对输入数据施以ZCA白化
                rotation_range=20,  # 数据提升时图片随机转动的角度(范围为0~180)
                width_shift_range=0.2,  # 数据提升时图片水平偏移的幅度(单位为图片宽度的占比,0~1之间的浮点数)
                height_shift_range=0.2,  # 同上,只不过这里是垂直
                horizontal_flip=True,  # 是否进行随机水平翻转
                vertical_flip=False)  # 是否进行随机垂直翻转

            # 计算整个训练样本集的数量以用于特征值归一化、ZCA白化等处理
            datagen.fit(dataset.train_images)

            # 利用生成器开始训练模型
            self.model.fit_generator(datagen.flow(dataset.train_images, dataset.train_labels,
                                                  batch_size=batch_size),
                                     samples_per_epoch=dataset.train_images.shape[0],
                                     nb_epoch=nb_epoch,
                                     validation_data=(dataset.valid_images, dataset.valid_labels))

    MODEL_PATH = './me.face.model.h5'

    def save_model(self, file_path=MODEL_PATH):
        self.model.save(file_path)

    def load_model(self, file_path=MODEL_PATH):
        self.model = load_model(file_path)

    def evaluate(self, dataset):
        score = self.model.evaluate(dataset.test_images, dataset.test_labels, verbose=1)
        print("%s: %.2f%%" % (self.model.metrics_names[1], score[1] * 100))

    def face_predict(self, image):
        # if K.image_dim_ordering() == 'th':  “channels_last”对应原本的“tf”,“channels_first”对应原本的“th”。
        if K.image_data_format() == 'channels_first' and image.shape != (1, 3, IMAGE_SIZE, IMAGE_SIZE):
            image = resize_image(image)  # 尺寸必须与训练集一致都应该是IMAGE_SIZE x IMAGE_SIZE
            image = image.reshape((1, 3, IMAGE_SIZE, IMAGE_SIZE))  # 与模型训练不同,这次只是针对1张图片进行预测
        elif K.image_data_format() == 'channels_last' and image.shape != (1, IMAGE_SIZE, IMAGE_SIZE, 3):
            image = resize_image(image)
            image = image.reshape((1, IMAGE_SIZE, IMAGE_SIZE, 3))

        # 浮点并归一化
        image = image.astype('float32')
        image /= 255

        # 给出输入属于各个类别的概率
        result = self.model.predict_proba(image)
        print('result:', result)
        my_result = list(result[0]).index(max(result[0]))
        max_result = max(result[0])
        print("result最大值下标:", my_result)
        if max_result > 0.90:
            return my_result
        else:
            return -1



if __name__ == '__main__':
    dataset = Dataset('.\\deep_learning')
    dataset.load(nb_classes=9)

    # 训练模型
    model = Model()
    model.build_model(dataset, nb_classes=9)
    model.train(dataset)
    model.save_model(file_path='./model/me.face.model.h5')

    # 评估模型,确认模型的精度是否能达到要求
    model = Model()
    model.load_model(file_path='./model/me.face.model.h5')
    model.evaluate(dataset)

load_data.py

import os
import numpy as np
import cv2

IMAGE_SIZE = 64


# 按照指定图像大小调整尺寸
def resize_image(image, height=IMAGE_SIZE, width=IMAGE_SIZE):
    top, bottom, left, right = (0, 0, 0, 0)

    # 获取图像尺寸
    h, w, _ = image.shape

    # 对于长宽不相等的图片,找到最长的一边
    longest_edge = max(h, w)

    # 计算短边需要增加多上像素宽度使其与长边等长
    if h < longest_edge:
        dh = longest_edge - h
        top = dh // 2
        bottom = dh - top
    elif w < longest_edge:
        dw = longest_edge - w
        left = dw // 2
        right = dw - left
    else:
        pass

        # RGB颜色
    BLACK = [0, 0, 0]

    # 给图像增加边界,是图片长、宽等长,cv2.BORDER_CONSTANT指定边界颜色由value指定
    constant = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT, value=BLACK)

    # 调整图像大小并返回
    return cv2.resize(constant, (height, width))


# 读取训练数据
images = []
labels = []


def read_path(path_name):
    for dir_item in os.listdir(path_name):
        # 从初始路径开始叠加,合并成可识别的操作路径
        full_path = os.path.abspath(os.path.join(path_name, dir_item))
        #
        if os.path.isdir(full_path):  # 如果是文件夹,继续递归调用
            read_path(full_path)
        else:  # 文件
            if dir_item.endswith('.jpg'):
                image = cv2.imread(full_path)
                
                image = resize_image(image, IMAGE_SIZE, IMAGE_SIZE)

                images.append(image)
                labels.append(path_name)

    return images, labels

# 给文件夹后缀,加标注,使其向量化,如果添加新的人,就可以对应文件夹和下标 
# 这里我随便写的label  因为涉及到隐私。
def indentify(label):
    if label.endswith('use'):
        return 0
    elif label.endswith('use'):
        return 1
    elif label.endswith('use'):
        return 2
    elif label.endswith('use'):
        return 3
    elif label.endswith('use'):
        return 4
    elif label.endswith('use'):
        return 5
    elif label.endswith('use'):
        return 6
    elif label.endswith('use'):
        return 7
    elif label.endswith('use'):
        return 8



# 从指定路径读取训练数据
def load_dataset(path_name):
    images, labels = read_path(path_name)

    # 将输入的所有图片转成四维数组,尺寸为(图片数量*IMAGE_SIZE*IMAGE_SIZE*3)
    # 图片为64 * 64像素,一个像素3个颜色值(RGB)
    images = np.array(images)
    print(images.shape)

    labels = np.array([indentify(label) for label in labels])

    print(images,labels)
    return images, labels


if __name__ == '__main__':
    images, labels = load_dataset('./deep_learning')

face_predict_use_keras.py

import cv2
from keras_train import Model

if __name__ == '__main__':
    # 加载模型
    model = Model()
    model.load_model(file_path='./model/me.face.model.h5')

    # 框住人脸的矩形边框颜色
    color = (0, 255, 0)

    # 捕获指定摄像头的实时视频流
    cap = cv2.VideoCapture(0)

    # 人脸识别分类器本地存储路径
    cascade_path = "./model/haarcascade_frontalface_alt2.xml"

    # 循环检测识别人脸
    while True:
        _, frame = cap.read()  # 读取一帧视频

        # 图像灰化,降低计算复杂度
        frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # 使用人脸识别分类器,读入分类器
        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)

                # 这里我随便写的,因为涉及到隐私。
                human = {
    
    0: 'use3', 1: 'use4', 2: 'use8', -1: 'others', 3: 'use88', 4: 'LinXi07',
                         5: 'use2', 6: 'use', 7: 'use1', 8: 'use7'}

                cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, thickness=2)

                # 文字提示是谁
                cv2.putText(frame, human[faceID],
                            (x + 30, y + 30),  # 坐标
                            cv2.FONT_HERSHEY_SIMPLEX,  # 字体
                            1,  # 字号
                            (255, 0, 255),  # 颜色
                            2)  # 字的线宽

        cv2.imshow("Face Identification System", frame)

        # 等待10毫秒看是否有按键输入
        k = cv2.waitKey(10)
        # 如果输入q则退出循环
        if k & 0xFF == ord('q'):
            break

    # 释放摄像头并销毁所有窗口
    cap.release()
    cv2.destroyAllWindows()

Das Obige ist der gesamte Code. Wenn Sie Fragen haben, diskutieren Sie diese bitte im Kommentarbereich.

Ich denke du magst

Origin blog.csdn.net/qq_45254369/article/details/126492132
Empfohlen
Rangfolge