[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】基于动态规划和K聚类的彩色图片压缩算法

引言 当想要压缩一张彩色图像时,彩色图像通常由数百万个颜色值组成,每个颜色值都由红、绿、蓝三个分量组成。因此,如果我们直接对图像的每个像素进行编码,会导致非常大的数据量。为了减少数据量,我们可以尝试减少颜色的数量,从而降低存储需求。 1.主要原理 (一)颜色聚类(Color Clustering):

核对不同文件夹所含内容的差异并提取缺失内容:Python代码

本文介绍基于Python语言,以一个大文件夹作为标准,对另一个大文件夹所包含的子文件夹或文件加以查漏补缺,并将查漏补缺的结果输出的方法~

Python 引用不确定的函数

本文详细介绍了Python引用不确定的函数的表示方法、如何在Python中引用不确定的函数、如何在Python中调用不确定函数方法。

python 无监督生成模型

本文详细介绍了python 无监督生成模型,主要介绍了无监督生成模型是生成对抗网络(Generative Adversarial Networks, GANs)的方法。

Python 潮流周刊#58:最快运行原型的语言(摘要)

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

10分钟掌握Python缓存

全文速览 python的不同缓存组件的使用场景和使用样例 cachetools的使用 项目背景 代码检查项目,需要存储每一步检查的中间结果,最终把结果汇总并写入文件中 在中间结果的存储中 可以使用context进行上下文的传递,但是整体对代码改动比较大,违背了开闭原则 也可以利用缓存存储,处理完成之

python提取特定格式的数据

Excel Grid Data Converter 知识点总结 本文档总结了 ExcelGridConverter.py 脚本所涉及的关键 Python 知识点。该脚本用于从多个 Excel 文件中提取特定格式的数据并转换为一个新的 Excel 文件。 目录 导入库 Pandas 数据处理 Tkin

Python 潮流周刊#57:Python 该采用日历版本吗?

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