以下是使用 Python 和 OpenCV 库进行人脸识别的代码。该代码使用 PCA 进行特征提取,并利用 Haar 级联分类器进行人脸检测,并通过欧氏距离进行人脸匹配。

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


def detect_face(img, face_cascade):    #返回脸的图像和数值信息
    #将测试图像转换为灰度图像,因为opencv人脸检测器需要灰度图像
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    #检测多尺度图像,返回值是一张脸部区域信息的列表(x,y,宽,高)(输入图像,每次图像尺寸减小的比例,至少检测次数,目标的最小尺寸)
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE)  #检测人脸
    # 如果未检测到面部,则返回原始图像
    if (len(faces) == 0):
        return None, None
    #假设多张脸
    for (x, y, w, h) in faces:
        # 返回图像的正面部分
        # cv2.imshow('face', img[y:y + w, x:x + h, :])
        face = gray[y:y + w, x:x + h].astype(np.float32)  # 数值转换
        face = cv2.resize(face, (150,150))
        return face, faces


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:
                # 返回图像的正面部分
                # cv2.imshow('face', img[y:y + w, x:x + h, :])
                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]
                   print(face.shape)
                   faces.append(face_vector)
                   labels.append(label)
    #将faces和labels转换为numpy数组,以备后续PCA操作
    faces= np.array(faces)
    labels= np.array(labels)

    return faces, labels

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')
# 进行PCA降维处理,提取主要特征
faces = pca.fit_transform(faces)
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')

while not stop:
    success, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    face, rect = detect_face(img, face_cascade)
    if not rect is None:
        # 检测人脸
        (x, y, w, h) = rect
        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
        c = cv2.waitKey(100)

        subjects = ['xu', 'LU', 'ZHOU']
        # 生成图像的副本,这样就能保留原始图像
        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 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, (150, 150))
                # face_vector = np.reshape(face,(1,-1))[0]#转换成一维向量
                # 如果传入了PCA模型,则将人脸图像降维

                face_pca = pca.transform(face.reshape(1, -1))
                # face_pca = np.reshape(face_pca,(1,-1))[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):  # i,f是训练数据的信息,遍历训练数据
                    d = ((face_pca - f) ** 2).sum()  # 计算test和训练图片的欧氏距离
                    if d < min_d:
                        min_d = d
                        c = labels[i]  # 获得最小欧式距离,即最近邻
                print(subjects[c])
                cv2.putText(img1, subjects[c], (x, y), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2)
                cv2.imshow('test', img1)
                cv2.imshow('img', img1)
                cv2.waitKey(1)

                if c & 0xFF == ord('q'):
                    stop = True
                    cv2.destroyAllWindows()

    # 0.81


为什么摄像头不显示
内容:可能是以下原因之一:
1. 摄像头没有正确连接到计算机;
2. 摄像头驱动程序没有正确安装;
3. 摄像头被其他程序占用,例如Skype或Zoom等;
4. 摄像头硬件故障。

解释:

  1. 人脸检测:使用 face_cascade.detectMultiScale() 函数检测图像中的人脸,该函数返回人脸区域的坐标信息。
  2. 特征提取:使用 PCA 降维技术提取人脸的特征。
  3. 人脸匹配:使用欧氏距离计算测试人脸与训练人脸之间的距离,并将距离最小的训练人脸作为匹配结果。
  4. 显示结果:在图像中显示人脸识别结果,包括识别到的姓名。

注意事项:

  • 确保已安装 OpenCV 库。
  • 确保已将 Haar 级联分类器文件 haarcascade_frontalface_default.xmlhaarcascade_frontalface_alt.xml 放在代码的同一目录下。
  • 确保在 prepare_training_data() 函数中正确设置训练数据目录路径。
  • 确保摄像头已正确连接到计算机,并且驱动程序已正确安装。

可能的错误和解决方法:

  • 摄像头无法打开:检查摄像头是否正确连接到计算机,并且驱动程序是否已正确安装。
  • 人脸检测失败:检查 Haar 级联分类器文件是否已正确放置。
  • 识别结果不准确:尝试增加训练数据量,或调整 PCA 的参数。
  • 其他错误:参考 OpenCV 文档,或在网上搜索相关解决方案。

代码的扩展:

  • 可以使用其他特征提取方法,例如深度学习模型。
  • 可以使用其他距离度量方法,例如余弦相似度。
  • 可以添加人脸识别功能,例如登录或身份验证。
  • 可以将人脸识别集成到其他应用程序中,例如图像处理或视频监控。

希望这能够帮助你完成人脸识别项目。如果你还有其他问题,请随时提问。

人脸识别 Python 代码:使用 PCA 降维和 OpenCV 实现

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

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