Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之六 简单进行人脸训练与识别

news2024/10/7 10:23:04

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之六 简单进行人脸训练与识别

目录

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之六 简单进行人脸训练与识别

一、简单介绍

二、简单进行人脸训练与识别

1、LBPH(Local Binary Patterns Histograms)算法进行人脸训练和识别

2、实现步骤:

3、判断是谁的人脸:

案例中涉及的关键函数说明如下

1)准备训练数据集:load_training_data(data_dir)

2)预处理图像:preprocess_images(faces)

3)训练 LBPH 人脸识别器:train_lbph(faces, labels)

4)读取测试图像:load_test_image(image_path)

5)预处理测试图像:preprocess_test_image(test_image)

6)进行人脸识别:recognize_face(model, test_image)

7)测试人脸识别器:test_face_recognition(data_dir, test_image_path)

三、简单进行人脸训练与识别案例实现简单步骤

四、注意事项


一、简单介绍

Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python是一种解释型脚本语言,可以应用于以下领域: Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发、网络爬虫。

这里使用 Python  基于 OpenCV 进行视觉图像处理,......

OpenCV 提供了一些已经训练好的级联分类器,这些级联分类器以XML文件的方式保存在以下路径中:

...\Python\Lib\site-packages\cv2\data\

OpenCV提供了一些经过预训练的人脸检测器模型文件,这些文件通常包含在OpenCV的安装包中。你也可以在OpenCV的官方GitHub页面或者OpenCV官方网站的下载页面找到这些模型文件的下载链接。

一般来说,你可以从以下位置获取OpenCV的预训练模型文件:

  •         OpenCV GitHub Release 页面:在 Releases · opencv/opencv · GitHub 找到你需要的版本,然后在下载的压缩包中找到位于 opencv\data 目录下的人脸检测器模型文件。
  •         OpenCV 官方网站下载页面:访问 OpenCV 官方网站 Releases - OpenCV ,下载你需要的版本,并在相应的压缩包中查找人脸检测器模型文件。

请确保下载与你使用的OpenCV版本兼容的模型文件。

该案例效果

二、简单进行人脸训练与识别

人脸识别是一种生物特征识别技术,旨在识别和验证人类面部的身份。它利用计算机视觉和模式识别技术来识别人脸图像中的关键特征,并将其与事先存储的人脸模板或数据库中的其他人脸进行比较,以确定是否匹配。人脸识别技术通常包括以下步骤:

  1. 人脸检测:首先从图像或视频中检测出人脸的位置,通常使用级联分类器、深度学习模型或其他检测算法来实现。

  2. 人脸对齐:将检测到的人脸图像对齐,确保它们具有相似的尺寸、姿态和位置。这一步有助于提高后续特征提取的准确性。

  3. 特征提取:从对齐后的人脸图像中提取关键特征,例如人脸的轮廓、眼睛、鼻子、嘴巴等。常用的特征提取方法包括主成分分析(PCA)、局部二值模式(LBP)、深度神经网络等。

  4. 特征匹配:将提取的特征与事先存储的人脸模板或数据库中的其他人脸特征进行比较,并计算它们之间的相似度或距离。通常采用的方法包括欧氏距离、余弦相似度等。

  5. 决策阶段:根据特征匹配的结果,决定是否识别为已知身份。这一阶段通常会设置一个阈值来判断匹配结果的可信度,如果相似度超过阈值,则识别为已知身份;否则,识别为未知身份或拒绝识别。

人脸识别技术在安全门禁、支付验证、监控系统、社交媒体标记等领域有着广泛的应用。

1、LBPH(Local Binary Patterns Histograms)算法进行人脸训练和识别

LBPH(Local Binary Patterns Histograms)算法是一种用于人脸识别的经典算法,它结合了局部二值模式(Local Binary Patterns,LBP)和直方图统计的技术。下面详细介绍LBPH算法的原理、实现步骤以及判断是谁的人脸的过程:

  1. 局部二值模式(LBP)

    • LBP 是一种用于纹理分析的特征描述方法。它通过比较像素点与其邻域像素的灰度值来描述图像的局部纹理特征。将每个像素与其邻域像素进行比较,并根据比较结果得到一个二进制数值,将这个数值作为该像素的特征描述。LBP 算法可以有效地捕获图像的纹理信息。
  2. 直方图统计

    • 在 LBP 算法的基础上,LBPH 算法将每个图像分割成多个局部区域,并计算每个局部区域的 LBP 特征直方图。这些直方图描述了每个局部区域的纹理分布情况,从而将图像的纹理信息转化为了直方图的形式。
  3. 人脸识别

    • 对于训练数据集中的每张人脸图像,LBPH 算法首先提取其局部纹理特征,并计算每个局部区域的 LBP 特征直方图。然后,利用这些直方图作为特征向量进行训练。在识别阶段,LBPH 算法对输入的测试图像进行同样的处理,提取其局部纹理特征,并计算每个局部区域的 LBP 特征直方图。接着,通过比较测试图像的特征向量与训练集中已知人脸的特征向量,利用一定的分类算法(如K最近邻算法)进行匹配和判别,从而确定测试图像属于哪个人。

2、实现步骤:

  1. 准备训练数据集

    • 收集包含多个人脸图像的数据集,并为每张图像标注对应的人物标签。
  2. 提取局部纹理特征

    • 对于每张人脸图像,利用 LBP 算法提取其局部纹理特征,得到每个局部区域的 LBP 特征描述。
  3. 构建特征向量

    • 将每个局部区域的 LBP 特征直方图组合成一个完整的特征向量,作为该图像的特征描述。
  4. 训练模型

    • 利用训练数据集中的特征向量,通过一定的机器学习算法(如K最近邻算法、支持向量机等)训练模型,得到人脸识别模型。
  5. 人脸识别

    • 对于新的测试图像,同样提取其局部纹理特征,并计算每个局部区域的 LBP 特征直方图。然后,利用训练好的模型对测试图像的特征向量进行匹配和判别,确定其所属的人物标签。

3、判断是谁的人脸:

  1. 训练模型

    • 在训练阶段,LBPH 算法利用已知的人脸图像数据集,构建了一个能够将人脸图像特征与对应人物标签关联起来的模型。
  2. 测试识别

    • 在识别阶段,LBPH 算法对输入的测试图像提取特征,并利用训练好的模型对其进行匹配和判别。根据匹配结果,确定测试图像属于哪个已知的人物标签。
  3. 置信度评估

    • LBPH 算法通常会返回识别结果的置信度(confidence)值,用于评估识别的准确度。较高的置信度值表示模型对于当前图像的识别结果较为自信,而较低的置信度值可能表示模型对于当前图像的识别困难程度较大。

案例中涉及的关键函数说明如下

1)准备训练数据集:load_training_data(data_dir)

参数:

  • data_dir(字符串):包含训练图像的目录路径。

功能: 该函数用于加载训练数据集。它遍历指定目录下的图像文件,并将每个图像转换为灰度图像。每个图像的路径提供了标签信息,标签即为图像所在的目录名称。

注意事项:

  • data_dir 应包含不同类别的图像,每个类别的图像应放置在以其类别名称命名的子目录中。
2)预处理图像:preprocess_images(faces)

参数:

  • faces(列表):包含原始训练图像的灰度图像列表。

功能: 该函数用于对训练图像进行预处理。它将每个图像调整为相同的大小(这里是100x100像素)。

注意事项:

  • 输入的 faces 列表应包含灰度图像,且每个图像的尺寸可以不同。
  • 预处理后的图像会覆盖原始图像,因此建议在调用该函数前备份原始图像数据。
3)训练 LBPH 人脸识别器:train_lbph(faces, labels)

参数:

  • faces(列表):包含预处理后的训练图像的灰度图像列表。
  • labels(列表):包含每个训练图像对应的标签列表。

功能: 该函数创建 LBPH 人脸识别器,并使用给定的训练数据集进行训练。

注意事项:

  • faceslabels 应具有相同的长度,且一一对应。
  • 训练数据集应包含足够多的样本,并且覆盖各种姿态、光照和表情等变化。
4)读取测试图像:load_test_image(image_path)

参数:

  • image_path(字符串):测试图像文件的路径。

功能: 该函数用于加载测试图像,并将其转换为灰度图像。

注意事项:

  • 输入的测试图像应为灰度图像。
5)预处理测试图像:preprocess_test_image(test_image)

参数:

  • test_image(二维数组):灰度测试图像。

功能: 该函数用于对测试图像进行预处理,将其调整为与训练图像相同的大小。

注意事项:

  • 输入的测试图像应为灰度图像。
  • 预处理后的测试图像会覆盖原始图像数据,因此建议在调用该函数前备份原始测试图像数据。
6)进行人脸识别:recognize_face(model, test_image)

参数:

  • model(cv2.face_LBPHFaceRecognizer):训练好的 LBPH 人脸识别器。
  • test_image(二维数组):预处理后的测试图像。

功能: 该函数使用训练好的 LBPH 人脸识别器对预处理后的测试图像进行识别,并返回预测的标签和置信度。

注意事项:

  • 输入的 test_image 应为预处理后的灰度图像。
  • 人脸识别器的模型应已经经过训练。
7)测试人脸识别器:test_face_recognition(data_dir, test_image_path)

参数:

  • data_dir(字符串):包含训练图像的目录路径。
  • test_image_path(字符串):测试图像文件的路径。

功能: 该函数是主函数,用于测试人脸识别器。它调用了前面定义的各个功能函数,并输出识别结果。

注意事项:

  • data_dir 应包含不同类别的图像,每个类别的图像应放置在以其类别名称命名的子目录中。
  • 测试图像应为单个灰度图像文件。

三、简单进行人脸训练与识别案例实现简单步骤

1、准备训练数据

这里使用1文件夹 汤姆汉克斯的头像,2 文件夹皮特的头像

2、待测试的是 2 皮特的头像

3、编写代码

3、运行结果

识别还是对了的,你们也可以试试其他图片

4、编辑代码

"""
简单进行人脸训练与识别
    1、准备训练数据集:
    2、提取局部纹理特征:
    3、构建特征向量:
    4、训练模型:
    5、人脸识别:
"""

import cv2
import os
import numpy as np


def load_training_data(data_dir):
    """
    从指定目录加载训练数据集
    :param data_dir:(str) 包含训练图像的目录路径
    :return:tuple 包含训练图像和对应标签的元组 (faces, labels)
    """

    if not isinstance(data_dir, str) or not data_dir.strip():
        raise ValueError("Invalid data directory path.")

    faces = []  # 存储人脸图像
    labels = []  # 存储人脸标签

    for root, dirs, files in os.walk(data_dir):
        for file in files:
            if file.endswith('.jpg') or file.endswith('.png'):
                img_path = os.path.join(root, file)
                label = os.path.basename(root)
                face_img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
                if face_img is not None:
                    faces.append(face_img)
                    labels.append(int(label))

    if not faces or not labels:
        raise ValueError("No valid training data found in the directory:", data_dir)

    return faces, labels


def preprocess_images(faces):
    """
    对图像列表进行预处理,调整图像大小为100x100像素
    :param faces: (list) 包含人脸图像的列表
    :return: list 预处理后的人脸图像列表
    """
    if not isinstance(faces, list) or not faces:
        raise ValueError("Invalid input: faces must be a non-empty list of images.")

    preprocessed_faces = []
    for face in faces:
        if face is not None:
            face = cv2.resize(face, (100, 100))  # 调整图像大小
            preprocessed_faces.append(face)
    return preprocessed_faces


def train_lbph(faces, labels):
    """
    使用 LBPH 算法训练人脸识别器
    :param faces: (list) 包含训练图像的列表
    :param labels: (list) 包含训练图像对应标签的列表
    :return: cv2.face_LBPHFaceRecognizer: 训练完成的 LBPH 人脸识别器模型
    """
    if not isinstance(faces, list) or not faces:
        raise ValueError("Invalid input: faces must be a non-empty list of images.")

    if not isinstance(labels, list) or not labels:
        raise ValueError("Invalid input: labels must be a non-empty list of integers.")

    if len(faces) != len(labels):
        raise ValueError("Mismatch in the number of faces and labels.")

    model = cv2.face.LBPHFaceRecognizer_create()
    model.train(faces, np.array(labels))
    return model


def load_test_image(image_path):
    """
    加载测试图像
    :param image_path: (str) 测试图像文件路径
    :return: numpy.ndarray 加载的测试图像
    """
    if not isinstance(image_path, str) or not image_path.strip():
        raise ValueError("Invalid image path.")

    test_image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
    if test_image is None:
        raise ValueError("Failed to load test image from path:", image_path)
    return test_image


def preprocess_test_image(test_image):
    """
    预处理测试图像,调整大小为100x100像素
    :param test_image: (numpy.ndarray) 待处理的测试图像
    :return: numpy.ndarray 预处理后的测试图像
    """

    if test_image is None:
        raise ValueError("Invalid input: test_image is None.")

    test_image = cv2.resize(test_image, (100, 100))  # 调整图像大小
    return test_image


def recognize_face(model, test_image):
    """
    使用训练好的模型识别人脸
    :param model: (cv2.face_LBPHFaceRecognizer) 训练完成的 LBPH 人脸识别器模型
    :param test_image: (numpy.ndarray) 待识别的测试图像
    :return: tuple 识别结果的标签和置信度 (label, confidence)
    """
    if model is None or not isinstance(model, cv2.face_LBPHFaceRecognizer):
        raise ValueError("Invalid model: model must be a trained LBPH face recognizer.")

    if test_image is None:
        raise ValueError("Invalid input: test_image is None.")

    label, confidence = model.predict(test_image)
    return label, confidence


def test_face_recognition(data_dir, test_image_path):
    """
    测试人脸识别器
    :param data_dir: (str) 包含训练图像的目录路径
    :param test_image_path: (str) 测试图像文件路径
    :return: tuple 识别结果的标签和置信度 (label, confidence)
    """
    # 加载训练数据集
    faces, labels = load_training_data(data_dir)

    # 预处理训练数据集
    preprocessed_faces = preprocess_images(faces)

    # 训练 LBPH 人脸识别器
    model = train_lbph(preprocessed_faces, labels)

    # 读取测试图像
    test_image = load_test_image(test_image_path)

    # 预处理测试图像
    preprocessed_test_image = preprocess_test_image(test_image)

    # 进行人脸识别
    label, confidence = recognize_face(model, preprocessed_test_image)

    return label, confidence


# 测试人脸识别器
if __name__ == "__main__":
    data_dir = "Images/Face/Train"
    test_image_path = "Images/Face/Test/Test_Peter.png"
    label, confidence = test_face_recognition(data_dir, test_image_path)
    print("Predicted label:", label)
    print("Confidence:", confidence)

四、注意事项

  1. 确保训练数据集包含足够多的人脸图像,并且标签信息正确。
  2. 对训练图像进行预处理时,要保持图像大小的一致性,以便于训练模型。
  3. 在训练 LBPH 人脸识别器时,要确保提供正确的训练数据集和标签信息。
  4. 测试图像的加载和预处理要正确,避免出现图像加载失败或尺寸不匹配的问题。
  5. 人脸识别结果的可信度(confidence)值可以用于评估识别的准确度,较低的可信度值可能表示模型对于当前图像的识别困难程度较大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1624855.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Spring Boot的考研资讯平台设计与实现

基于Spring Boot的考研资讯平台设计与实现 开发语言:Java框架:springbootJDK版本:JDK1.8数据库工具:Navicat11开发软件:eclipse/myeclipse/idea 系统部分展示 系统功能界面图,在系统首页可以查看首页、考…

公司服务器中的kafka消息中间件挂了,我是如何修复的?

今天的公司的system系统服务在运行过程中,提示连接不上kafuka的消息中间件。但是负责kafka的同事已经离职了,询问公司开发也不知道如何处理,我是如何重启kafka消息中间件使system系统服务正常运行? 查看kafka的安装位置 在下面的…

【UE5】蓝图通信方式

目录 1、直接通信 2、getAllActorsOfClass 3、getAllActorsOfClassWithTag 4、通过射线检测 5、接口 6、事件分发器 7、SpawnActor 8、调用控制台命令 9、关卡蓝图中直接调用 创建两个Actor蓝图 1、直接通信 场景中 2、getAllActorsOfClass 3、getAllActorsOfClassWit…

编写一个Java类 输入手机号码,验证其是否合法的完整实例

每个人的手机号码都是不一样的,那我们该如何保证用户输入的是合法的手机号码呢?这就需要我们在代码中对这个手机号进行验证,不能随便输入11位数字就行了。这时,就需要对用户传递过来的字符串参数进行校验。 下面我们介绍使用Java…

【Java数据结构】初步认识ArrayList与顺序表

前言~🥳🎉🎉🎉 hellohello~,大家好💕💕,这里是E绵绵呀✋✋ ,如果觉得这篇文章还不错的话还请点赞❤️❤️收藏💞 💞 关注💥&#x…

从零开始安装 stable diffusion webui v1.9.3 (windows10)

从零开始安装 stable diffusion webui v1.9.3 (windows10) CUDA 安装 CUDA 12.1 | https://developer.nvidia.com/cuda-toolkit-archive CUDNN 8.x | https://developer.nvidia.com/rdp/cudnn-archive 安装路径 F:/CUDA/v12.1 安装git git官网 | https://git-scm.com/ 安…

html显示PDF并兼容IE浏览器的解决方案

方案一、vue-pdf插件 缺点&#xff1a;IE11显示空白&#xff0c;编译后的Edge测试环境可以正常线上&#xff0c;打到线上报错&#xff0c;谷歌和百分浏览器显示完美 1、vue 只显示核心代码&#xff0c;需要安装vue-pdf插件 <vue-pdf :src"ivcPdfUrl"></v…

决策树分析及其在项目管理中的应用

决策树分析是一种分类学习方法&#xff0c;其主要用于解决分类和回归问题。在决策树中&#xff0c;每个内部节点表示一个属性上的测试&#xff0c;每个分支代表一个属性输出&#xff0c;而每个叶节点则代表类或类分布。通过从根节点到内部节点的路径&#xff0c;可以构建一系列…

commvault学习(6):备份oracle(包括oracle的安装)

1.环境 CS、MA&#xff1a;一台windows server2012 客户端&#xff1a;2台安装了oracle11g的windows server2008 1.1 windows server2008安装oracle11g &#xff08;1&#xff09;右击安装包内的setup&#xff0c;以管理员方式运行 &#xff08;2&#xff09;取消勾选接收安…

PFA容量瓶耐受强酸强碱进口特氟龙材质定容瓶

PFA容量瓶&#xff0c;也叫特氟龙容量瓶&#xff0c;是用于配制标准浓度溶液的实验室器皿&#xff0c;是有着细长颈、梨形肚的耐强腐蚀平底塑料瓶&#xff0c;颈上有标线&#xff0c;可直接配置标准溶液和准确稀释溶液以及制备样品溶液。 因其有着不易碎、材质纯净、化学稳定性…

用docker方式安装openGauss数据库的事项记录

文章目录 &#xff08;一&#xff09;背景&#xff08;二&#xff09;安装&#xff08;2.1&#xff09;安装docker&#xff08;2.2&#xff09;安装openGauss &#xff08;三&#xff09;运行&#xff08;3.1&#xff09;运行openGauss镜像&#xff08;3.2&#xff09;连接open…

docker安装【zookeeper】【kafka】【provectuslabs/kafka-ui】记录

目录 1.安装zookeeper:3.9.2-jre-172.安装kafka:3.7.03.安装provectuslabs/kafka-ui &#xff08;选做&#xff09;新环境没有jdk&#xff0c;安装jdk-17.0.10备用 mkdir -p /export/{data,apps,logs,conf,downloads}cd /export/downloadscurl -OLk https://download.oracle.…

ABAP json解析使用引用代替预定义数据结构

背景&#xff1a;在解析JSON数据时&#xff0c;通常会事先为定义相应的ABAP数据结构。但是&#xff0c;当遇到一些结构纵深较为复杂的情况时&#xff0c;会比较麻烦。 处理&#xff1a;使用引用类型来定义结构中的纵深部分来达到“省事”的目的&#xff0c;缺点在于访问时需要使…

rust中结构体的属性默认是不能修改的,要想修改可以有两种方式

Rust中结构体里面的属性默认是不支持修改的&#xff0c;而且默认不是pub的&#xff0c;要想修改的话&#xff0c;有两种方式&#xff0c;我以为和python里面的类似呢&#xff0c;但是还是需要一点技术含量的。如果想在引到外部修改&#xff0c;需要声明pub&#xff0c;如果想在…

Qt xml示范

1.数据格式 #ifndef XML_DATA_H #define XML_DATA_H#include<QWidget>struct Student {int s_id;QString s_name;double s_math_score;double s_english_score;}; struct Teacher{int t_id;QString t_name;QVector<Student> t_students_v; };#endif // XML_DATA_H…

论文解读:(VPT)Visual Prompt Tuning

文章汇总 要解决的问题 大型模型应用于下游任务本身就存在挑战。最明显的(通常也是最有效的)适应策略是对预先训练好的模型进行全面的端到端微调。 动机 只微调参数的一个子集 解决的办法 只在输入空间中引入少量特定于任务的可学习参数&#xff0c;而在下游训练期间冻结…

STM32的GPIO控制寄存器开发

寄存器GPIO控制 寄存器地址 寄存器地址计算 某个寄存器地址&#xff0c;由三个参数决定&#xff1a;1、总线基地址&#xff08;BUS_BASE_ADDR&#xff09;&#xff1b;2&#xff0c;外设基于总线基地址的偏移量&#xff08;PERIPH_OFFSET&#xff09;&#xff1b;3&#xff…

书生·浦语 大模型(学习笔记-8)Lagent AgentLego 智能体应用搭建

目录 一、智能体出现的原因 二、智能体的定义 三、智能体的组成 四、Lagent 五、AgentLego 六、实战一&#xff08;Lagent&#xff09; 环境配置及安装 安装依赖 准备 Tutorial Lagent Web Demo AgentLego 使用 图片推理&#xff08;结果&#xff09;&#xff1a; …

C#基础之函数基础

函数 文章目录 1、函数基础1、概念2、函数位置3、基本语法4、实际运用5、return 2、ref 和 out1、ref 和 out 使用2、区别思考 登录 3、变长参数和参数默认值1、变长参数2、参数默认值 4、函数重载5、递归函数思考1 阶乘思考2 阶乘相加思考3 竹竿减半思考4 递归循环输出 1、函数…

diskMirror-backEnd-spring-boot | diskMirror 后端服务器 SpringBoot 版本!

diskMirror-backEnd-spring-boot diskMirror 后端服务器的 SpringBoot 版本&#xff0c;此版本中拓展了 DiskMirrorBackEnd&#xff0c;是一个完全的SpringBoot项目&#xff01; 目录 文章目录 diskMirror-backEnd-spring-boot目录我如何部署与配置docker 方式部署 diskMirro…