[Python急救站]人脸识别技术练习

python · 浏览次数 : 0

小编点评

**代码功能:** 1. 加载预先训练的 LogisticRegression 模型,用于人脸识别。 2. 加载特征缩放器,用于标准化输入数据,提高模型识别性能。 3. 加载 PCA 模型,用于降维处理,减少计算复杂度并去除噪声。 4. 定义一个函数 `load_reference_image()`,用于从给定路径加载参考照片并提取其面部特征。 5. 定义一个函数 `preprocess_face()`,用于预处理输入人脸图像,以便用于模型识别。 6. 定义一个函数 `recognize_faces()`,用于识别视频流中的脸部并判断是否为目标人物。 7. 加载OpenCV预训练的人脸检测模型(基于Haar特征的级联分类器)。 8. 设置目标人物在模型中的标签假设。 9. 初始化Tkinter图形界面,用于展示视频帧及识别结果。 10. 定义视频流展示的回调函数,持续更新显示内容并执行人脸识别。 11. 初始化摄像头设备。 12. 启动视频流的显示循环。 13. 运行Tkinter事件循环,实现连续更新。 14. 关闭摄像头资源。 **使用说明:** 1. 将代码中的所有路径根据您的实际路径进行修改。 2. 运行脚本,会创建三个训练好的pkl文件:`model.pkl`、`scaler.pkl`和 `pca.pkl`。 3. 创建一个人脸识别py文件,并将其命名为 `face_recognizer.py`。 4. 将 `face_recognizer.py` 文件中的代码粘贴到 `face_recognizer.py` 中。 5. 运行 `python face_recognizer.py` 运行人脸识别程序。 **注意:** * 代码中的所有路径都应该改成自己的路径。 * 训练脚本和识别脚本的像素必须一致,否则会报错。 * 如果您遇到任何问题,请在评论区提问或发个人邮箱:linyuanda@linyuanda.com。

正文

这段时间做了一个用于初学者学习人脸识别系统的程序,在上代码时,先给说说事前准备:

首先我们需要一个OpenCV的一个haarcascade_frontalface_default.xml文件,只要去GitHub上面即可下载:https://github.com/opencv/opencv

点击Code,选择Download ZIP,下载后解压在目录下opencv-4.x\data\haarcascades中可以找到haarcascade_frontalface_default.xml,这个时候将这个文件复制到你的工程目录下。

第二个要准备的文件是:lfw-deepfunneled,这个文件在网站中下载:https://vis-www.cs.umass.edu/lfw/#download

进入网站后下拉找到Download the database:  ,然后在这个模块中找到All images aligned with deep funneling,点击下载后,将压缩包解压到工程目录下即可。

然后创建一个模型训练的py文件,代码如下:

import os
import numpy as np
import cv2
from matplotlib import pyplot as plt
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report, confusion_matrix
from joblib import dump

# 设置数据集路径
lfw_home = 'D:/Pythonxiangmu/Python/renlian/lfw-deepfunneled'  # 替换为实际路径
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')


# 函数:从目录加载图像并提取人脸区域
def load_images_and_labels(directory):
    images = []
    labels = []
    for label in sorted(os.listdir(directory)):
        if not os.path.isdir(os.path.join(directory, label)):
            continue
        for img_path in os.listdir(os.path.join(directory, label)):
            img = cv2.imread(os.path.join(directory, label, img_path), cv2.IMREAD_GRAYSCALE)
            faces = face_cascade.detectMultiScale(img, scaleFactor=1.1, minNeighbors=5)
            if len(faces) > 0:
                for (x, y, w, h) in faces:
                    face_img = img[y:y + h, x:x + w]
                    face_img_resized = cv2.resize(face_img, (130, 195))  # 保持与应用代码一致
                    images.append(face_img_resized.flatten())
                    labels.append(label)
    return np.array(images), np.array(labels)


def train_face_recognition_model(dataset_path):
    # 加载图像和标签
    X, labels = load_images_and_labels(dataset_path)

    # 数据集划分
    X_train, X_test, y_train, y_test = train_test_split(X, labels, test_size=0.25, random_state=42)

    # 特征缩放
    scaler = StandardScaler()
    X_train_scaled = scaler.fit_transform(X_train)
    X_test_scaled = scaler.transform(X_test)

    # PCA降维
    n_components = 150  # 选择合适的主成分数
    pca = PCA(n_components=n_components, whiten=True)
    X_train_pca = pca.fit_transform(X_train_scaled)
    X_test_pca = pca.transform(X_test_scaled)

    # 训练逻辑回归模型
    clf = LogisticRegression(C=1e5)
    clf.fit(X_train_pca, y_train)

    # 预测与评估
    y_pred = clf.predict(X_test_pca)
    print("Classification Report:")
    print(classification_report(y_test, y_pred))
    print("Confusion Matrix:")
    print(confusion_matrix(y_test, y_pred))

    # Eigenfaces进行可视化(可选)
    n_components_to_show = 10
    """可视化前n个Eigenfaces"""
    eigenfaces = pca.components_
    eigenface_titles = ["Eigenface %d" % i for i in range(1, n_components_to_show + 1)]

    # 选择前n个Eigenfaces进行可视化

    for i in range(n_components_to_show):
        eigenface = eigenfaces[i].reshape(195, 130)  # 根据之前调整的尺寸进行重塑
        plt.subplot(2, 5, i + 1)
        plt.imshow(eigenface, cmap='gray')
        plt.title(eigenface_titles[i])
        plt.axis('off')  # 不显示坐标轴

    plt.show()
    # 保存模型与预处理器
    dump(clf, 'model.pkl')
    dump(scaler, 'scaler.pkl')
    dump(pca, 'pca.pkl')


# 调用函数以执行训练流程
train_face_recognition_model(lfw_home)

运行结束后,就会在你的工程目录下创建三个训练好的pkl文件。

然后再创建一个人脸识别用的py文件,代码如下:

import os
from tkinter import Tk, Label, messagebox
import cv2
import joblib
import numpy as np
from PIL import Image, ImageTk

# 加载预先训练好的LogisticRegression模型,用于后续的人脸识别
model = joblib.load('model.pkl')

# 加载特征缩放器,用于标准化输入数据,提高模型识别性能
scaler = joblib.load('scaler.pkl')

# 加载PCA模型,用于降维处理,减少计算复杂度并去除噪声
pca = joblib.load('pca.pkl')


# 定义函数:从给定路径加载参考照片并提取其面部特征
def load_reference_image(reference_path):
    # 使用OpenCV读取灰度图像作为参考照片
    reference_image = cv2.imread(reference_path, cv2.IMREAD_GRAYSCALE)

    # 利用预设的人脸检测器检测参考照片中的人脸
    reference_faces = face_cascade.detectMultiScale(reference_image)

    # 确保至少检测到一张人脸,否则抛出错误
    if len(reference_faces) == 0:
        raise ValueError("No face detected in reference image.")

    # 获取检测到的第一张人脸区域
    reference_face_roi = reference_image[
                         reference_faces[0][1]:reference_faces[0][1] + reference_faces[0][3],
                         reference_faces[0][0]:reference_faces[0][0] + reference_faces[0][2]
                         ]

    # 对提取的参考人脸区域进一步预处理,准备用于模型识别
    preprocessed_reference_face = preprocess_face(reference_face_roi)

    # 返回预处理后的面部特征数据
    return preprocessed_reference_face


# 定义函数:预处理输入的人脸图像,以便用于模型识别
def preprocess_face(face_image):
    # 确保图像尺寸与训练时一致(130x195)
    face_image_resized = cv2.resize(face_image, (130, 195))

    # 图像数据展平
    img_flattened = face_image_resized.flatten()  # 调整尺寸后,直接展平

    # 特征缩放
    img_scaled = scaler.transform(img_flattened.reshape(1, -1))

    # PCA降维
    img_pca = pca.transform(img_scaled)

    # 使用训练好的模型进行预测

    return img_pca


# 定义函数:识别视频流中的脸部并判断是否为目标人物
def recognize_faces(frame):
    # 将视频帧转换为灰度图像,便于人脸检测
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # 使用预定义的人脸级联分类器检测图像中的人脸
    face_rects = face_cascade.detectMultiScale(gray_frame, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
    # 遍历检测到的每一个人脸区域
    for (x, y, w, h) in face_rects:
        # 提取人脸区域
        face_roi = gray_frame[y:y + h, x:x + w]
        # 对该人脸区域进行预处理
        preprocessed_face = preprocess_face(face_roi)
        # 使用模型预测该人脸属于各个类别的概率
        probabilities = model.predict_proba(preprocessed_face.reshape(1, -1))[0]
        # 获取最可能的预测类别
        predicted_label = np.argmax(probabilities)
        # 若预测类别与目标人物标签匹配,则认为识别到了目标人物
        if predicted_label == target_person_label:
            return True
    # 若未识别到目标人物,则返回False
    return False


# 加载OpenCV预训练的人脸检测模型(基于Haar特征的级联分类器)
base_dir = r"D:\Pythonxiangmu\Python\renlian"
xml_path = os.path.join(base_dir, "haarcascade_frontalface_default.xml")
face_cascade = cv2.CascadeClassifier(xml_path)

# 设置目标人物在模型中的标签假设
target_person_label = 0

# 初始化Tkinter图形界面,用于展示视频流及识别结果
root = Tk()
root.title("Face Recognition System")
root.geometry("800x600")

# 创建一个Label控件用于动态显示视频帧
label = Label(root)
label.pack(fill="both", expand=True)

# 加载并预处理参考照片,获取其特征编码
photo_path = os.path.join(base_dir, "zhaopian.jpg")
reference_face_encoding = load_reference_image(photo_path)


# 定义视频流展示的回调函数,持续更新显示内容并执行人脸识别
def show_frame():
    # 从摄像头读取一帧图像
    ret, frame = cap.read()
    if ret:  # 确保成功读取到帧
        # 尝试识别当前帧中的人脸
        is_recognized = recognize_faces(frame)
        # 若识别到目标人物,弹出提示框
        if is_recognized:
            messagebox.showinfo("Recognition Result", "Face recognized!")
        # 转换图像色彩空间以适应Tkinter显示,并调整尺寸
        rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        pil_image = Image.fromarray(rgb_frame)
        resized_image = pil_image.resize((root.winfo_width(), root.winfo_height()))
        # 转换为Tkinter兼容的图像格式并更新显示
        tk_image = ImageTk.PhotoImage(image=resized_image)
        label.config(image=tk_image)
        label.image = tk_image  # 防止图像对象被提前释放
        # 定时调用自身以实现连续更新
        root.after(1, show_frame)


# 初始化摄像头设备
cap = cv2.VideoCapture(0)

# 启动视频流的显示循环
show_frame()

# 运行Tkinter事件循环
root.mainloop()

# 关闭摄像头资源
cap.release()

运行后就开始人脸识别,这样就完成啦!

注意,代码中的所有的路径都应该改成自己的路径!其中的像素可以修改,但是要注意训练脚本要和识别脚本的像素一致,否则会报错!

如果有什么问题欢迎在评论区提问,也可以发个人邮箱:linyuanda@linyuanda.com

与[Python急救站]人脸识别技术练习相似的内容:

[Python急救站]人脸识别技术练习

这段时间做了一个用于初学者学习人脸识别系统的程序,在上代码时,先给说说事前准备: 首先我们需要一个OpenCV的一个haarcascade_frontalface_default.xml文件,只要去GitHub上面即可下载:https://github.com/opencv/opencv 点击Cod

[Python急救站]基于Transformer Models模型完成GPT2的学生AIGC学习训练模型

为了AIGC的学习,我做了一个基于Transformer Models模型完成GPT2的学生AIGC学习训练模型,指在训练模型中学习编程AI。 在编程之前需要准备一些文件: 首先,先win+R打开运行框,输入:PowerShell后 输入: pip install -U huggingface_hu

音频文件降噪及python示例

操作系统 :Windows 10_x64 Python版本:3.9.2 noisereduce版本:3.0.2 从事音频相关工作,大概率会碰到降噪问题,今天整理下之前学习音频文件降噪的笔记,并提供Audacity和python示例。 我将从以下几个方面展开: noisereduce库介绍 使用Aud

Python按条件筛选、剔除表格数据并绘制剔除前后的直方图

本文介绍基于Python语言,读取Excel表格文件数据,以其中某一列数据的值为标准,对于这一列数据处于指定范围的所有行,再用其他几列数据的数值,加以数据筛选与剔除;同时,对筛选前、后的数据分别绘制若干直方图,并将结果数据导出保存为一个新的Excel表格文件的方法~

我从 Python 潮流周刊提取了 800 个链接,精选文章、开源项目、播客视频集锦

你好,我是豌豆花下猫。前几天,我重新整理了 Python 潮流周刊的往期分享,推出了第 1 季的图文版电子书,受到了很多读者的一致好评。 但是,合集和电子书的篇幅很长,阅读起来要花不少时间。所以,为了方便大家阅读,我打算将合集进一步整理,分门别类将原始内容的标题罗列出来。 本文总计约 800 个链接

从基础到高级应用,详解用Python实现容器化和微服务架构

本文分享自华为云社区《Python微服务与容器化实践详解【从基础到高级应用】》,作者: 柠檬味拥抱。 Python中的容器化和微服务架构实践 在现代软件开发中,容器化和微服务架构已经成为主流。容器化技术使得应用程序可以在任何环境中一致运行,而微服务架构通过将应用拆分成多个独立的服务,从而提升了系统的

Python循环控制

本文介绍了Python编程语言中关于for循环和if条件控制的一些基本使用。包含了单层循环的退出机制和多层循环的退出机制,使得我们在满足特定条件时,可以直接结束多层循环。

Python 潮流周刊#60:Python 的包管理工具真是多啊(摘要)

本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进 Python 技术,并增长职业和副业的收入。 本期周刊分享了 13 篇文章,13 个开源项目,全文 2300 字。 重要提醒:

推荐一款Python接口自动化测试数据提取分析神器!

1、引言 在处理JSON数据时,我们常常需要提取、筛选或者变换数据。手动编写这些操作的代码不仅繁琐,而且容易出错。Python作为一个功能强大的编程语言,拥有丰富的库和工具来处理这些数据。今天,将介绍一个实用的Python库——JMESPath,它为提取JSON数据提供了简洁而强大的语法。 2、JM

如何用python计算不定积分

本文详细介绍了如何用Python计算不定积分的方法,重点SymPy是一个用于符号数学的Python库,支持许多类型的数学对象,包括整数、有理数、实数、复数、函数、极限、积分、微分、方程、几何等,同时本文也介绍了多项式函数、指数函数和三角函数、换元积分、有理函数的不定积分的方法。