import cv2
import os
import numpy as np
from sklearn.decomposition import PCA


def detect_face(img, face_cascade):
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE)
    if len(faces) == 0:
        return None
    for (x, y, w, h) in faces:
        face = gray[y:y + w, x:x + h].astype(np.float32)
        face = cv2.resize(face, (150, 150))
        return face


def prepare_training_data(data_folder_path):
    face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
    dirs = os.listdir(data_folder_path)
    faces = []
    labels = []
    for dir_name in dirs:
        label = int(dir_name)
        subject_dir_path = data_folder_path + '/' + dir_name
        subject_images_names = os.listdir(subject_dir_path)

        for image_name in subject_images_names:
            image_path = subject_dir_path + '/' + image_name
            image = cv2.imread(image_path)

            if image is None:
                continue

            gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
            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, (150, 150))
                if face is not None:
                   face_vector = np.reshape(face,(1,-1))[0]
                   faces.append(face_vector)
                   labels.append(label)

    faces= np.array(faces)
    labels= np.array(labels)

    return faces, labels


def preprocess_image(img, face_cascade, pca):
    face = detect_face(img, face_cascade)
    if face is not None:
        face_pca = pca.transform(face.reshape(1, -1))
        img_processed = cv2.cvtColor(face, cv2.COLOR_GRAY2RGB)
        return face_pca, img_processed
    else:
        return None, None


def main():
    cap = cv2.VideoCapture(0)
    stop = False
    face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    pca = PCA(n_components=60, svd_solver='full')
    faces, labels = prepare_training_data('raw1')
    faces = pca.fit_transform(faces)

    while not stop:
        success, img = cap.read()
        face_pca, img_processed = preprocess_image(img, face_cascade, pca)
        if face_pca is not None:
            subjects = ['xu', 'LU', 'ZHOU']
            img1 = img_processed.copy()
            faces_cascade = face_cascade.detectMultiScale(img, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE)
            if len(faces_cascade) > 0:
                (x, y, w, h) = faces_cascade[0]
                cv2.rectangle(img1, (x, y), (x + w, y + h), (0, 255, 0), 2)
                min_d = 1000000000000
                c = -1
                for i, f in enumerate(faces):
                    d = ((face_pca - f) ** 2).sum()
                    if d < min_d:
                        min_d = d
                        c = labels[i]
                print(subjects[c])
            cv2.imshow('test', img1)
            cv2.putText(img1, subjects[c], (x, y), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2)
        c = cv2.waitKey(1)
        if c & 0xFF == ord('q'):
            stop = True
    cv2.destroyAllWindows()




if __name__ == '__main__':
    main()

代码说明:

  1. 人脸检测: 使用 cv2.CascadeClassifier() 加载 Haar 级联分类器,用于检测图像中的人脸。
  2. 数据准备: prepare_training_data() 函数从文件夹中读取训练图像,并提取人脸特征,用于训练 PCA 模型。
  3. PCA 降维: 使用 PCA(n_components=60) 创建 PCA 模型,将人脸特征降维至 60 维。
  4. 实时识别:main() 函数中,从摄像头读取视频帧,检测人脸,并使用 PCA 模型将人脸特征降维。
  5. 特征匹配: 通过计算当前人脸特征与训练数据中每个人的特征向量之间的距离,找到距离最小的特征向量,并根据标签确定识别结果。

注意:

  • 确保已经安装了 OpenCVscikit-learn 库。
  • raw1 替换为实际的训练数据文件夹路径。
  • 调整 n_components 参数,可以改变 PCA 模型的降维程度。
  • 可以调整人脸检测参数 scaleFactorminNeighborsminSize,以获得更好的识别效果。

运行代码:

  1. 将代码保存为 face_recognition.py 文件。
  2. 打开终端,运行命令 python face_recognition.py

显示空白界面原因:

  • 摄像头没有成功打开。请检查摄像头是否连接正确。
  • 没有检测到人脸。请确保摄像头能清晰地拍摄到你的脸部。
  • 训练数据不足或质量差。请使用充足且高质量的训练数据。

调试代码:

  • detect_face 函数中添加 print(faces) 语句,查看是否检测到人脸。
  • prepare_training_data 函数中添加 print(faces.shape, labels.shape) 语句,查看训练数据的大小。
  • main() 函数中添加 print(face_pca) 语句,查看是否成功进行 PCA 降维。
  • main() 函数中添加 print(subjects[c]) 语句,查看识别结果。
人脸识别 Python 代码:使用 PCA 降维进行实时人脸识别

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

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