人脸识别:基于LBP和PCA的人脸识别系统

本代码使用 OpenCV 和 Python 实现了一个简单的人脸识别系统。该系统结合了 LBP 特征提取和 PCA 降维技术,能够识别多个目标人脸。

1. 准备训练数据

import cv2
import os
import numpy as np
from sklearn.decomposition import PCA
from skimage.feature import local_binary_pattern   #调用函数精确度更高


def prepare_training_data(data_folder_path):
    # 获取数据文件夹中的目录(每个主题的一个目录)
    face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')   #训练一组数据
    dirs = os.listdir(data_folder_path) #返回data_folder_path目录下的文件夹和文件
    # 两个列表分别保存所有的脸部和标签
    faces = []
    labels = []
    # 浏览每个目录并访问其中的图像
    for dir_name in dirs:
        # dir_name(str类型)即标签
        label = int(dir_name)
        # 建立包含当前主题主题图像的目录路径
        subject_dir_path = data_folder_path + '/' + dir_name
        # 获取给定主题目录内的图像名称
        subject_images_names = os.listdir(subject_dir_path)

        # 浏览每张图片并检测脸部,然后将脸部信息添加到脸部列表faces[]
        for image_name in subject_images_names:
            # 建立图像路径
            image_path = subject_dir_path + '/' + image_name
            # 读取图像
            image = cv2.imread(image_path)
            # 确保图像正确加载
            if image is None:
                continue
            # 显示图像0.1s
            cv2.imshow('Training on image...', image)
            cv2.waitKey(100)

            # 检测脸部
            gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
            # 检测多尺度图像,返回值是一张脸部区域信息的列表(x,y,宽,高)(输入图像,每次图像尺寸减小的比例,至少检测次数,目标的最小尺寸)
            rect = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30),
                                                 flags=cv2.CASCADE_SCALE_IMAGE)  # 检测人脸
            # 假设多张脸
            for (x, y, w, h) in rect:
                face = gray[y:y + w, x:x + h].astype(np.float32)  # 数值转换
                face = cv2.resize(face, (100, 100))
                face_lbp = local_binary_pattern(face, 1, 8).reshape(1, -1)
                # 我们忽略未检测到的脸部
                if face_lbp is not None:
                    # 将脸添加到脸部列表并添加相应的标签
                    # 将每张面部图像转换为一维向量并添加到列表中
                    faces.append(face_lbp)
                    labels.append(label)
            # 将faces和labels转换为numpy数组,以备后续PCA操作
    faces = np.array(faces)
    labels = np.array(labels)
    return faces, labels


if __name__ == '__main__':
    pca = PCA(n_components=40, svd_solver='full')
    faces, labels = prepare_training_data('allraw')
    faces = faces.reshape(faces.shape[0], -1)
    faces = pca.fit_transform(faces)  # 训练集拟合
    cap = cv2.VideoCapture(0)
    stop = False
    face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')#加载检测器
    while not stop:
        success, img = cap.read()
        subjects = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33']
        # 生成图像的副本,这样就能保留原始图像
        img1 = img.copy()
        # 检测人脸
        # 将测试图像转换为灰度图像,因为opencv人脸检测器需要灰度图像
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # 检测多尺度图像,返回值是一张脸部区域信息的列表(x,y,宽,高)
        rect = face_cascade.detectMultiScale(img, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30),
                                             flags=cv2.CASCADE_SCALE_IMAGE)
        # 如果未检测到面部
        if len(rect) == 0:
            txt = 'no face!'
            cv2.putText(img1, txt, (10, 20), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2)
        if not rect is None:
            for (x, y, w, h) in rect:
                face = gray[y:y + w, x:x + h].astype(np.float32)  # 数值转换
                face = cv2.resize(face, (100, 100))
                face_lbp = local_binary_pattern(face, 1, 8).reshape(1, -1)
                face_pca = pca.transform(face_lbp) #测试集降维
                cv2.rectangle(img1, (x, y), (x + w, y + h), (0, 255, 0), 2)  # 画出矩形框
                k = cv2.waitKey(100)  # 每0.1秒读取一次键盘
                min_d = 1000000000000
                c = -1
                for i, f in enumerate(faces):  # i,f是训练数据的信息,遍历训练数据
                   d = ((face_pca - f) ** 2).sum()  # 计算test和训练图片的欧氏距离
                   if d < min_d:
                      min_d = d
                      c = labels[i]
                if min_d < 200000000:
                      cv2.putText(img1, subjects[c], (x, y), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2)
                else:
                      label = 'unknown'
                      cv2.putText(img1, label, (x, y), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2)
                cv2.imshow('img', img1)
                cv2.waitKey(1)
                if c & 0xFF == ord('q'):  # 按下q程序结束
                    stop = True
                    cv2.destroyAllWindows()  # 释放窗口

2. 代码说明

  1. 准备训练数据:函数 prepare_training_data() 用于从文件夹中读取图像,并使用 OpenCV 的 CascadeClassifier 检测人脸。然后,使用 LBP 提取人脸特征,并将特征向量和对应的标签保存到列表中。
  2. PCA 降维:使用 sklearn.decomposition.PCA 进行降维,将每个特征向量降维到 40 维。
  3. 实时识别:使用摄像头获取视频流,并使用 OpenCV 的 CascadeClassifier 检测人脸。然后,使用 LBP 提取人脸特征,并使用训练好的 PCA 模型对特征向量进行降维。最后,通过计算测试特征向量与训练特征向量的欧氏距离,找到最接近的匹配,从而识别出目标人脸。

3. 运行方法

  1. 将所有训练图像放置在名为 'allraw' 的文件夹中,每个主题一个文件夹,文件夹名称为对应的标签。
  2. 运行代码,打开摄像头,将人脸对准摄像头,程序会识别出对应的人脸。

4. 注意事项

  1. 训练图像需要包含不同光照、角度和表情的人脸,以提高识别精度。
  2. 识别精度与训练数据量和质量有关,更多、更优质的训练数据将提高识别精度。
  3. 使用 LBP 特征提取和 PCA 降维可以有效地减少计算量,提高识别速度。

5. 总结

本代码提供了一个简单的人脸识别系统的示例,通过 LBP 特征提取和 PCA 降维技术,能够识别多个目标人脸。您可以根据实际需求修改代码,例如增加更多特征提取方法、使用更复杂的分类器等。

人脸识别:基于LBP和PCA的人脸识别系统

原文地址: https://www.cveoy.top/t/topic/mJQl 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录