python学opencv|读取图像(七十四)人脸识别:EigenFaces算法

news/2025/2/24 8:43:34

【1】引言

前序学习进程中,做的是检测,只是能检测出来由人脸、猫脸和行人,相关文章链接为:

python学opencv|读取图像(七十一)使用cv2.CascadeClassifier()函数+detectMultiScale()函数实现图像中的人脸检测-CSDN博客

python学opencv|读取图像(七十二)猫脸检测:使用cv2.CascadeClassifier()函数+detectMultiScale()函数实现图像中的猫脸检测-CSDN博客

python学opencv|读取图像(七十三)行人检测:使用cv2.CascadeClassifier()函数+detectMultiScale()函数实现图像中的行人检测-CSDN博客

更进一步,如果想在检测出来的人脸上识别出是谁的脸,就要用到人脸识别。

人脸识别的算法有三种,本次学习其中的EigenFaces算法。

【2】原理说明

人脸识别需要用到不同的算法,把算法理解成识别器。具体操作的时候,先挑选一种算法,然后使用这种算法进行训练,训练之后再去看识别效果。   

【3】官网教程

首先点击下方链接,直达人脸识别的说明页官网教程:

OpenCV: Face Recognition with OpenCV

在这里,非常清晰地说明了当前有三种人脸识别算法:

图1  人脸识别官网说明

官网页面内容非常丰富,但学习需要抓主要内容,因此只要关注Eigenfaces就可以。

当然,细心的朋友肯定也发现了,这个页面提供了一些照片集,大家可以自行下载。

继续下拉会看到,关于Eigenfaces给出了背后的算法证明:

图2  Eigenfaces算法证明

实际上,如果不是做研究,这个算法说空也不用太过深究,因为主要的精力要放在实现好的人脸识别上。

在这个页面之后,给出了C++的案例,就不继续研究这个页面了,请点击下方链接直达新的页面:

OpenCV: cv::face::EigenFaceRecognizer Class Reference

这个新页面给出了在python中如何通过Eigenfaces算法创建进人脸识别器:

图3  cv.face.EigenFaceRecognizer.create识别器

具体的,cv.face.EigenFaceRecognizer.create识别器有两个参数:

cv.face.EigenFaceRecognizer.create(    

num_components              #可选参数,PCA(主成分分析)中保留分量的个数

threshold  )                        #可选参数,人脸识别的阈值

创建识别器之后,需要对图像进行训练,所以还要用一个函数cv.face.FaceRecognizer.train()来创建训练器,点击下方链接直达:

OpenCV: cv::face::FaceRecognizer Class Reference

图4   用函数cv.face.FaceRecognizer.train()创建训练器

具体的,cv.face.FaceRecognizer.train()训练器有两个参数:

cv.face.FaceRecognizer.train( 

src                    #用来训练的样本图像,要求尺寸大小一致

labels )             #样本图像对应的标签

训练器训练完样本之后,可以使用cv.face.FaceRecognizer.predict()函数对待识别图像进行识别,点击下方链接,直达cv.face.FaceRecognizer.predict()函数的官网页面:

OpenCV: cv::face::FaceRecognizer Class Reference

具体的,cv.face.FaceRecognizer.predict()只有一个参数:

cv.face.FaceRecognizer.predict(

src            #待识别图像,要求与训练样本尺寸一致

)

cv.face.FaceRecognizer.predict(src)会输出两个结果:

label:待测图像和样本图像最佳匹配时,对应的样本图像标签值

confidence:匹配置信度,小于5000认为匹配效果好,0表示完全一样。

【4】代码测试

此处进行代码测试:

首先是引入必要的模块,定义两个空列表,分别用来存储图像和图像对应的标签:

import cv2 as cv #引入cv2模块
import numpy as np #引入numpy模块

photos = []  #定义photo空列表,用来存储图像
labels = []  #定义lables空列表,用来存储图像对应的标签

然后使用了3张图像作为样本来训练,这里要给出样本的存储地址:

# 定义图片路径列表
image_paths = [
    r"D:\python\pythonworkspace\pythonProject3\zyz\01.jpg",
    r"D:\python\pythonworkspace\pythonProject3\zyz\02.jpg",
    r"D:\python\pythonworkspace\pythonProject3\zyz\03.jpg"
]

为了把图像统一尺寸,需要先给定相关尺寸的约束条件:

#定义图像尺寸信息
width=600  #定义一个初始宽度量
height=800  #定义一个初始高度量
target_size = (width,height) #定义一个元组,存储宽度量和高度量

# 读取其余图片并调整尺寸
for path in image_paths[0:]:
    img = cv.imread(path, 0)
    if img is not None:
        # 调整图像尺寸为与第一张图片相同
        img = cv.resize(img, target_size)
        photos.append(img)
        labels.append(0)
    else:
        print(f"无法读取图片: {path}")

图像尺寸统一完成之后,需要给这一组图像加一个标签:

#定义标签
names = {"0": "su"}

然后创建人脸识别器:

# 创建人脸识别器
recognizer = cv.face.EigenFaceRecognizer.create()

然后训练人脸识别器:

# 训练人脸识别器
if photos and labels:
    recognizer.train(photos, np.array(labels)) #训练器读入人脸样本和对应标签

之后就是把待测图像拿进来进行测试。

先读取图像:

# 读取测试图片
    test_image_path = r"D:\python\pythonworkspace\pythonProject3\zyz\09.jpg"
    test_img = cv.imread(test_image_path, 0)

然后把图像尺寸修改成和样本统一的大小,之后就可以进行对比识别:

    if test_img is not None:
        # 调整测试图像尺寸与第一张图片一致
        test_img = cv.resize(test_img, target_size)
        label, confidence = recognizer.predict(test_img)

对于识别效果,需要按照匹配度再次处理:

# 设定识别阈值
        threshold = 5000  # 可根据实际情况调整
        if confidence > threshold:
            # 将灰度图转换为彩色图以便添加彩色文字
            test_img_color = cv.cvtColor(test_img, cv.COLOR_GRAY2BGR)
            # 添加未识别标记
            cv.putText(test_img_color, "Unrecognized", (10, 30), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
            output_img = test_img_color
        else:
            print(f'confidence={confidence}')
            print(names[str(label)])
            # 将灰度图转换为彩色图
            output_img = cv.cvtColor(test_img, cv.COLOR_GRAY2BGR)

最后是输出图像:

        # 输出图像
        cv.imshow('Result Image', output_img)
        cv.waitKey(0)
        cv.destroyAllWindows()
    else:
        print(f"无法读取测试图片: {test_image_path}")

为了更好地理解,直接给出完整代码:

import cv2 as cv #引入cv2模块
import numpy as np #引入numpy模块

photos = []  #定义photo空列表,用来存储图像
labels = []  #定义lables空列表,用来存储图像对应的标签

# 定义图片路径列表
image_paths = [
    r"D:\python\pythonworkspace\pythonProject3\zyz\01.jpg",
    r"D:\python\pythonworkspace\pythonProject3\zyz\02.jpg",
    r"D:\python\pythonworkspace\pythonProject3\zyz\03.jpg"
]

#定义图像尺寸信息
width=600  #定义一个初始宽度量
height=800  #定义一个初始高度量
target_size = (width,height) #定义一个元组,存储宽度量和高度量

# 读取其余图片并调整尺寸
for path in image_paths[0:]:
    img = cv.imread(path, 0)
    if img is not None:
        # 调整图像尺寸为与第一张图片相同
        img = cv.resize(img, target_size)
        photos.append(img)
        labels.append(0)
    else:
        print(f"无法读取图片: {path}")
#定义标签
names = {"0": "su"}

# 创建人脸识别器
recognizer = cv.face.EigenFaceRecognizer.create()

# 训练人脸识别器
if photos and labels:
    recognizer.train(photos, np.array(labels)) #训练器读入人脸样本和对应标签
    # 读取测试图片
    test_image_path = r"D:\python\pythonworkspace\pythonProject3\zyz\09.jpg"
    test_img = cv.imread(test_image_path, 0)
    if test_img is not None:
        # 调整测试图像尺寸与第一张图片一致
        test_img = cv.resize(test_img, target_size)
        label, confidence = recognizer.predict(test_img)

        # 设定识别阈值
        threshold = 5000  # 可根据实际情况调整
        if confidence > threshold:
            # 将灰度图转换为彩色图以便添加彩色文字
            test_img_color = cv.cvtColor(test_img, cv.COLOR_GRAY2BGR)
            # 添加未识别标记
            cv.putText(test_img_color, "Unrecognized", (10, 30), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
            output_img = test_img_color
        else:
            print(f'confidence={confidence}')
            print(names[str(label)])
            # 将灰度图转换为彩色图
            output_img = cv.cvtColor(test_img, cv.COLOR_GRAY2BGR)

        # 输出图像
        cv.imshow('Result Image', output_img)
        cv.waitKey(0)
        cv.destroyAllWindows()
    else:
        print(f"无法读取测试图片: {test_image_path}")

代码运行使用的训练样本均为女明星:

图5  训练样本

使用豆包AI生成的篮球明星进行识别,发现很好辨认出不是一个人:

图6 识别效果

【5】总结

掌握了python+opencv实现通过EigenFaces算法实现人脸识别的技巧。


http://www.niftyadmin.cn/n/5864123.html

相关文章

基于Python+django+mysql旅游数据爬虫采集可视化分析推荐系统

2024旅游推荐系统爬虫可视化(协同过滤算法) 基于Pythondjangomysql旅游数据爬虫采集可视化分析推荐系统 有文档说明 部署文档 视频讲解 ✅️基于用户的协同过滤推荐算法 卖价就是标价~ 项目技术栈 Python语言、Django框架、MySQL数据库、requests网络爬虫…

智能控制基础应用-C#Codesys共享内存实现数据高速交互

智能控制基础应用-C#&Codesys共享内存实现数据高速交互 文章目录 智能控制基础应用-C#&Codesys共享内存实现数据高速交互前言一、 Codesys共享内存程序实现二、Python共享内存程序实现2.1 界面说明 三、功能测试注意事项 前言 共享内存是一种高效的进程间通信&#xf…

基于传统信息检索算法 BM25 的检索器 和 基于大语言模型生成的文本嵌入(dense embeddings)来计算相似度的检索器 两者的区别和联系

首先给出示例代码: #### INDEXING ##### Load blog import bs4 from langchain_community.document_loaders import WebBaseLoader# 设置一个常见的浏览器 User-Agent 字符串 os.environ["USER_AGENT"] "Mozilla/5.0 (Windows NT 10.0; Win64; x64…

ZLMediaKi集群设置

要在集群环境中部署 ZLMediaKit,您可以按照以下步骤进行操作。ZLMediaKit 是一个高性能的流媒体服务器,支持 RTMP、RTSP、HLS 等协议。以下是一个详细的集群部署方案: ### 1. 环境准备 - **服务器**:准备多台服务器,…

使用 Power Automate 转换 HTML to PDF

前言 今天,我们看一下如何使用Adobe PDF服务,转换HTML到PDF。 正文 1.先在Flow的最上面,声明两个参数,如下图: 2.通过搜索找到Adobe PDF Services,如下图: 3.找到convert-static-html-to-pdf&am…

架构对比分析

您提到的两种架构描述本质上遵循相同的分层设计理念,但存在差异的原因在于 视角不同 和 硬件平台特性。以下是详细解析: 一、架构对比分析 1. 逻辑分层(通用软件设计视角) 应用层(UI/用户交互)↓ 业务逻辑…

Python selenium 库

Selenium 是一个用于自动化 Web 浏览器操作的强大工具,广泛应用于 Web 应用程序测试、网页数据抓取和任务自动化等场景。 Selenium 为各种编程语言提供了 API,用作测试。 目前的官方 API 文档有 C#、JavaScript、Java、Python、Ruby。 安装 Selenium 和…

第一届网谷杯

统计四场的所有题目(共计12题,四场比赛一共上了21题【包括换题】) 随便记记,以免老题复用(已经复用了) Web 文件包含 1 伪协议 http://120.202.175.143:8011/?cphp://filter/convert.base64-encode/reso…