【计算机视觉】人脸识别

news2025/1/22 13:12:35

一、简介

人脸识别是将图像或者视频帧中的人脸与数据库中的人脸进行对比,判断输入人脸是否与数据库中的某一张人脸匹配,即判断输入人脸是谁或者判断输入人脸是否是数据库中的某个人。
人脸识别属于1:N的比对,输入人脸身份是1,数据库人脸身份数量为N,一般应用在办公室门禁,疑犯追踪;人脸验证属于1:1的比对,输入人脸身份为1,数据库中为同一人的数据,在安全领域应用比较多。
一个完整的人脸识别流程主要包括人脸检测、人脸对齐、特征提取、人脸对比几个部分。

二、人脸检测

人脸检测是寻找并定位人脸在输入图像中的位置。

传统人脸检测算法

Viola-Jones人脸检测活Haar特征级联分类器

import cv2

# 加载预训练模型
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_eye.xml')

# 读取输入图像
image_path = "path_to_image.jpg"  # 替换为你的图片路径
image = cv2.imread(image_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 转为灰度图

# 检测人脸
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

# 绘制人脸矩形框
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x+w, y+h), (255, 0, 0), 2)
    roi_gray = gray[y:y+h, x:x+w]
    roi_color = image[y:y+h, x:x+w]

    # 在每张人脸区域内检测眼睛
    eyes = eye_cascade.detectMultiScale(roi_gray)
    for (ex, ey, ew, eh) in eyes:
        cv2.rectangle(roi_color, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2)

# 显示结果
cv2.imshow("Detected Faces and Eyes", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

1. 加载预训练模型
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_eye.xml')
  • 功能:加载 OpenCV 提供的预训练 Haar 级联分类器模型,用于检测人脸和眼睛。
  • 参数
    • cv2.CascadeClassifier:加载 XML 模型文件。
    • cv2.data.haarcascades:OpenCV 提供的 Haar 分类器模型的默认路径。
    • 'haarcascade_frontalface_default.xml':用于检测正面人脸。
    • 'haarcascade_eye.xml':用于检测眼睛。
2. 读取并预处理图像
image_path = "path_to_image.jpg"  # 替换为你的图片路径
image = cv2.imread(image_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 转为灰度图
  • 功能
    1. 使用 cv2.imread 读取图像。
    2. 转换为灰度图(灰度图检测效率更高,级联分类器对彩色图像没有直接支持)。
  • 原因:级联分类器的训练和使用都基于灰度图像。
3. 检测人脸
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
  • 功能:检测图像中的所有人脸。
  • 参数
    • gray:输入的灰度图。
    • scaleFactor=1.1:每次图像缩小时的比例因子,较大的值降低检测时间但可能错过较小的人脸。
    • minNeighbors=5:每个候选矩形需满足的邻近矩形数量。值越大,检测结果越严格。
    • minSize=(30, 30):目标检测框的最小尺寸,用于过滤过小的区域。
  • 输出:返回一个列表,每个元素是一个 (x, y, w, h) 元组,表示检测到的人脸的矩形框。
4. 绘制人脸矩形框并检测眼睛
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x+w, y+h), (255, 0, 0), 2)
    roi_gray = gray[y:y+h, x:x+w]
    roi_color = image[y:y+h, x:x+w]
  • 功能
    • 遍历 faces 中的每个人脸检测框 (x, y, w, h)
    • 使用 cv2.rectangle 在原图上绘制蓝色框((255, 0, 0))表示人脸区域。
    • 提取每个人脸的灰度子图 roi_gray 和原图的子图 roi_color,用于后续的眼睛检测。
  • 原因:减少检测区域,提高眼睛检测的精度和速度。
5. 在每张人脸区域内检测眼睛
eyes = eye_cascade.detectMultiScale(roi_gray)
for (ex, ey, ew, eh) in eyes:
    cv2.rectangle(roi_color, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2)
  • 功能:使用 eye_cascade.detectMultiScale 在人脸区域内检测眼睛。
  • 参数:同人脸检测,输入的灰度子图为 roi_gray
  • 绘制结果:用绿色框((0, 255, 0))表示检测到的眼睛。
6. 显示结果
cv2.imshow("Detected Faces and Eyes", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 功能
    1. 使用 cv2.imshow 显示图像。
    2. cv2.waitKey(0):等待用户按键关闭窗口。
    3. cv2.destroyAllWindows:销毁所有窗口,释放资源。
总结
  1. 输入:一张图片(RGB 格式)。
  2. 处理
    • 转为灰度图。
    • 使用预训练的 Haar 级联模型检测人脸和眼睛。
    • 在检测到的区域绘制矩形框。
  3. 输出:在窗口中显示标注了人脸和眼睛的图片。

基于深度学习的人脸检测算法

基于深度学习的人脸检测算法经历了从传统方法到现代深度学习方法的演变,其发展历程可以划分为几个重要阶段。以下是基于深度学习的人脸检测算法的主要发展历史:

1. 传统方法阶段(2000年以前)
  • 特点
    • 依赖于手工设计特征和传统机器学习方法(如 Haar 特征、HOG 特征)。
    • 算法代表:Haar 级联分类器(Viola-Jones,人脸检测的重要突破)。
  • 局限
    • 对光照、姿态、遮挡等情况敏感。
    • 检测速度快但精度有限。

这一阶段虽然不基于深度学习,但奠定了人脸检测的基础。

2. 深度学习的初步应用(2012年左右)
  • 背景:2012年 AlexNet 在 ImageNet 比赛中获胜,深度学习开始广泛应用于计算机视觉。
  • 特点
    • 使用卷积神经网络(CNN)作为特征提取器。
    • 算法代表:DeepFace(Facebook, 2014)
      • 使用深度神经网络(DNN)对人脸检测和识别进行处理。
      • 首次将深度学习应用于人脸检测和识别任务,性能显著提升。
  • 局限
    • 网络规模较小,无法应对复杂场景(如多角度、遮挡)
3. 基于回归的方法(2015年左右)
  • 背景:深度学习框架和硬件性能的进步,使得更复杂的网络架构成为可能。
  • 特点
    • 使用 CNN 直接回归人脸框的坐标。
    • 算法代表:
      • Cascade CNN(2015):使用多个 CNN 逐步回归人脸位置,提高检测精度。
      • MTCNN(Multi-task Cascaded CNN, 2016):结合多任务学习,联合进行人脸检测和关键点定位。
        • 特点:多阶段检测框架,利用级联网络逐步细化结果。
        • 优点:检测速度和精度兼顾,成为经典方法。
4. 单阶段和双阶段目标检测器的引入(2016年-2018年)
  • 背景:通用目标检测器如 Faster R-CNN、SSD、YOLO 等在物体检测任务中的成功,推动了它们在人脸检测领域的应用。
  • 特点
    • 单阶段方法:如 SSD 和 YOLO,将人脸检测视为通用物体检测任务。
    • 双阶段方法:如 Faster R-CNN,将区域建议网络(RPN)与分类器结合。
  • 算法代表
    • Face R-CNN:使用 Faster R-CNN 对人脸进行检测。
    • S3FD(Single Shot Scale-invariant Face Detector, 2017):基于 SSD 的改进,解决了人脸大小变化的问题。
    • RetinaFace(2019):结合关键点检测,性能优异。
5. 基于关键点检测和自监督学习(2018年后)
  • 特点
    • 强调对复杂场景(如遮挡、多角度、低光照)的鲁棒性。
    • 将人脸关键点检测和人脸检测结合,进一步提升精度。
  • 算法代表
    • DSFD(Dual Shot Face Detector, 2019):多分辨率特征融合,更适合检测小人脸。
    • CenterFace(2020):轻量级人脸检测器,结合人脸框和关键点检测,适合实时应用。
    • SCRFD(2021):针对边缘设备优化的高效人脸检测器。
6. 大模型和自监督学习的影响(2021年后)
  • 背景:大规模预训练模型(如 Vision Transformer, CLIP)的兴起,为人脸检测带来了新的可能性。
  • 特点
    • 使用自监督学习方法,通过大规模无标签数据学习强大的特征表征。
    • 将 Transformer 等新架构引入人脸检测任务。
  • 算法代表
    • DEtection TRansformer (DETR):结合 Transformer 架构的人脸检测方法。
    • YOLO 系列最新版本:如 YOLOv5、YOLOv8,在人脸检测任务中的应用。

三、人脸对齐

人脸对齐是将检测得到的人脸图像变换到标准正脸姿态,在实际图片中,由于头部姿态各异、人脸尺度不一,所呈现的形式也各不相同。

  1. 人脸检测
    • 检测人脸框,提取人脸区域。
    • 使用 OpenCV 提供的 Haar 或 DNN 检测器。
  2. 关键点检测
    • 使用关键点检测模型提取人脸的关键点(如眼睛、鼻尖等)。
    • 关键点可以用 Dlib 或深度学习模型(如 MTCNN)提取。
  3. 仿射变换
    • 根据检测到的关键点,定义源点(人脸关键点)和目标点(标准模板关键点)。
    • 计算仿射变换矩阵并应用变换,将人脸对齐。

四、特征提取

特征提取是将输入的人脸图像用一个高维特征向量来表示;如果同一个人,则两个高维特征向量的距离近;如果不同,则距离远。人脸特征提取的方法也可以分为传统方法和深度学习两大类。
人脸特征提取算法经历了从早期的几何特征分析到现代深度学习的转变,其发展历史可以分为以下几个阶段:

1. 几何特征阶段(20世纪70-90年代)
代表方法
  • 几何特征分析
    • 利用人脸的几何属性(如眼睛间距、鼻梁长度、脸型轮廓)作为特征。
    • 通过手工定义的特征点计算欧氏距离等度量方式。
  • 模板匹配
    • 使用平均脸模板,匹配输入人脸与模板的相似度。
优缺点
  • 优点:简单直观,计算量小。
  • 缺点:对光照、姿态和遮挡不鲁棒,特征维度较低。
代表研究
  • 1973年,Bledsoe 提出的人脸几何模型匹配方法
  • 1987年,Sirovich 和 Kirby 提出的脸空间方法,为 PCA 奠定了基础。
2. 统计学习阶段(1990-2010年)
代表方法
  • 主成分分析(PCA)
    • 把人脸图像作为高维向量,降维成低维特征表示(如特征脸)。
    • 1991年,Turk 和 Pentland 提出了Eigenfaces 方法
  • 线性判别分析(LDA)
    • 增强类间区分能力,用于人脸识别。
    • 解决了 PCA 的类间可分性不足问题。
  • 独立成分分析(ICA)
    • 分离人脸的非高斯成分,适合表情和姿态变化分析。
  • 局部二值模式(LBP)
    • 基于纹理模式的人脸描述,提取局部区域的纹理特征。
  • Fisherfaces
    • 综合 PCA 和 LDA 方法,提升对光照变化的鲁棒性。
优缺点
  • 优点:提出了许多经典算法,对光照、姿态变化有一定鲁棒性。
  • 缺点:对非线性特征无法很好建模,提取的特征不够高维,难以处理复杂场景。
代表研究
  • 1991年,Eigenfaces。
  • 1997年,Belhumeur 提出的 Fisherfaces。
  • 2002年,LBP 被引入人脸识别领域。
3. 局部特征阶段(2000-2015年)
代表方法
  • SIFT (Scale-Invariant Feature Transform)
    • 提取图像中的局部关键点和特征描述。
    • 对光照、尺度、旋转变化鲁棒。
  • HOG (Histogram of Oriented Gradients)
    • 提取梯度方向分布,用于描述人脸的全局形状。
  • Gabor 特征
    • 模拟人类视觉皮层特性,用 Gabor 滤波器提取人脸纹理。
优缺点
  • 优点:提升了对光照和局部细节的鲁棒性。
  • 缺点:局部特征无法很好表达全局信息,算法复杂度较高。
代表研究
  • 2004年,Lowe 提出的 SIFT。
  • 2005年,Dalal 和 Triggs 提出的 HOG。
  • 2006年,Gabor 特征被广泛应用于人脸识别。
4. 深度学习阶段(2014年至今)
关键技术
  • 卷积神经网络(CNN)
    • 自适应提取多层次特征,捕捉人脸的纹理、形状、表情等信息。
    • 提取的特征更具辨别性。
  • 预训练模型
    • 使用大规模人脸数据集进行训练,如 LFW、CASIA-WebFace 等。
    • 模型具备迁移学习能力。
代表算法
  • DeepFace (2014, Facebook)
    • 首个端到端人脸识别深度学习模型。
    • 采用卷积神经网络,实现接近人类的识别精度。
  • DeepID (2014-2015, 中国科学院)
    • 提出多层 CNN 架构,特征更加鲁棒。
    • 引入多个子网络对不同区域进行特征提取。
  • FaceNet (2015, Google)
    • 基于深度学习的人脸特征提取算法。
    • 使用 Triplet Loss 学习特征嵌入,支持高效人脸验证和聚类。
  • ArcFace (2018, InsightFace)
    • 提出了 Additive Angular Margin Loss,进一步优化特征的判别性。
    • 被广泛用于工业人脸识别系统。
  • CosFace、SphereFace
    • 聚焦于特征分布的角度约束,提升类间分离度。
优缺点
  • 优点:特征表示能力强,适用于大规模人脸识别。
  • 缺点:需要大量数据和计算资源,可能存在隐私问题。
代表研究
  • 2014年,Facebook 提出 DeepFace。
  • 2015年,Google 提出 FaceNet。
  • 2018年,ArcFace 成为人脸识别领域的主流算法。

五、人脸比对

获取了人脸特征后,对于不同人脸图像,通过比对其人脸特征之间的距离远近,就可以判断人脸身份。
在 Python 中,OpenCV 提供的 cv2.FaceRecognizerSF 模块可以用于人脸识别任务,match 是其方法之一,用于比较两个特征向量之间的相似度。以下是 facerecognizer.match 方法的详细介绍:

函数原型
cv2.FaceRecognizerSF.match(face1: numpy.ndarray, face2: numpy.ndarray, disType: int = 0) -> float
参数说明
  1. face1

    • 类型: numpy.ndarray
    • 描述: 第一个人脸的特征向量。
      • 特征向量通常由 cv2.FaceRecognizerSF.feature() 方法生成,表示人脸的深度特征。
  2. face2

    • 类型: numpy.ndarray
    • 描述: 第二个人脸的特征向量。
      • 同样通过 feature() 方法提取,用于与 face1 比较。
  3. disType

    • 类型: int
    • 描述: 指定距离度量的类型,用于衡量两个特征向量之间的相似性。
    • 可选值:
      • 0 (cv2.FaceRecognizerSF.FR_COSINE): 使用余弦相似度。
      • 1 (cv2.FaceRecognizerSF.FR_NORM_L2): 使用 L2 范数(欧几里得距离)。
返回值
  • 类型: float
  • 描述: 返回两个特征向量的相似度分数。
    • 对于余弦相似度,值越大表示越相似(最大值为1)。
    • 对于 L2 范数,值越小表示越相似。

六、开源项目盘点

  • CompreFace
  • Deepface
  • InsightFace
  • Face Recognition
  • FaceNet
  • OpenFace

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

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

相关文章

linux-NFS网络共享存储服务配置

1.NFS服务原理 NFS会经常用到,用于在网络上共享存储,这样讲,你对NFS可能不太了解,举一个例子, 加入有三台机器A,B,C,它们需要访问同一个目录,目录中都是图片,传统的做法是把这些 图…

Jenkins 启动

废话 这一阵子感觉空虚,心里空捞捞的,总想找点事情做,即使这是一件微小的事情,空余时间除了骑车、打球,偶尔朋友聚会 … 还能干什么呢? 当独自一人时,究竟可以做点什么,填补这空虚…

消息队列篇--原理篇--Pulsar(Namespace,BookKeeper,类似Kafka甚至更好的消息队列)

Apache Pulusar是一个分布式、多租户、高性能的发布/订阅(Pub/Sub)消息系统,最初由Yahoo开发并开源。它结合了Kafka和传统消息队列的优点,提供高吞吐量、低延迟、强一致性和可扩展的消息传递能力,适用于大规模分布式系…

Python配置MITMPROXY中间人监听配置

1、安装python 环境,此处可以使用conda安装:conda create --name my_new_env python3.12 2、pip安装mitmproxy:pip install mitmproxy,安装后如果使用mitmproxy --version 成功返回结果,说明已经在环境变量路径中,如果…

Java-数据结构-二叉树习题(2)

第一题、平衡二叉树 ① 暴力求解法 📚 思路提示: 该题要求我们判断给定的二叉树是否为"平衡二叉树"。 平衡二叉树指:该树所有节点的左右子树的高度相差不超过 1。 也就是说需要我们会求二叉树的高,并且要对节点内所…

【网络原理】万字详解 HTTP 协议

🥰🥰🥰来都来了,不妨点个关注叭! 👉博客主页:欢迎各位大佬!👈 文章目录 1. HTTP 前置知识1.1 HTTP 是什么1.2 HTPP 协议应用场景1.3 HTTP 协议工作过程 2. HTTP 协议格式2.1 fiddler…

基于STM32的智能寝室控制系统设计(论文+源码)

1 .系统整体设计 通过需求分析,本设计基于STM32的智能寝室控制系统整体架构如图2.1所示,整系统利用DHT11温湿度传感器获取室内环境数据,并通过OLED显示,提供用户实时信息,火焰传感器和烟雾传感器用于监测火灾情况&…

日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件

日历热力图,月度数据可视化图表,vue组件 先看效果👇 在线体验https://www.guetzjb.cn/calanderViewGraph/ 日历图简单划分为近一年时间,开始时间是 上一年的今天,例如2024/01/01 —— 2025/01/01,跨度刚…

铁电存储器FM25CL64B简介及其驱动编写(基于STM32 hal库)

铁电存储器FM25CL64B简介及其驱动编写(基于STM32 hal库) 文章目录 铁电存储器FM25CL64B简介及其驱动编写(基于STM32 hal库)前言一、FM25CL64B简介二、驱动代码1.头文件2.c文件 总结 前言 FM25CL64B是赛普拉斯cypress出品的一款铁…

基于微信小程序的科创微应用平台设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…

HarmonyOS Next 最强AI智能辅助编程工具 CodeGenie介绍

随着大模型的兴起,在智能编码领域首先获得了应用。 市面上从Microsoft Copilot到国内阿里通义,字节marscode等,都提供了copilot方式的智能编码工具。HarmonyOS Next作为诞生一年的新事物,由于代码量和文档迭代原因,在智…

WPF2-1在xaml为对象的属性赋值.md

1. AttributeValue方式 1.1. 简单属性赋值1.2. 对象属性赋值 2. 属性标签的方式给属性赋值3. 标签扩展 (Markup Extensions) 3.1. StaticResource3.2. Binding 3.2.1. 普通 Binding3.2.2. ElementName Binding3.2.3. RelativeSource Binding3.2.4. StaticResource Binding (带参…

Appium(四)

一、app页面元素定位 1、通过id定位元素: resrouce-id2、通过ClassName定位:classname3、通过AccessibilityId定位:content-desc4、通过AndroidUiAutomator定位5、通过xpath定位xpath、id、class、accessibility id、android uiautomatorUI AutomatorUI自…

Windows图形界面(GUI)-QT-C/C++ - Qt List Widget详解与应用

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 QListWidget概述 使用场景 常见样式 QListWidget属性设置 显示方式 (Display) 交互行为 (Interaction) 高级功能 (Advanced) QListWidget常见操作 内容处理 增加项目 删除项目…

Oracle 创建并使用外部表

目录 一. 什么是外部表二. 创建外部表所在的文件夹对象三. 授予访问外部表文件夹的权限3.1 DBA用户授予普通用户访问外部表文件夹的权限3.2 授予Win10上的Oracle用户访问桌面文件夹的权限 四. 普通用户创建外部表五. 查询六. 删除 一. 什么是外部表 在 Oracle 数据库中&#x…

靠右行驶数学建模分析(2014MCM美赛A题)

笔记 题目 要求分析: 比较规则的性能,分为light和heavy两种情况,性能指的是 a.流量与安全 b. 速度限制等分析左侧驾驶分析智能系统 论文 参考论文 两类规则分析 靠右行驶(第一条)2. 无限制(去掉了第一条…

Kafka 源码分析(一) 日志段

首先我们的 kafka 的消息本身是存储在日志段中的, 对应的源码是下面这段代码: class LogSegment private[log] (val log: FileRecords,val lazyOffsetIndex: LazyIndex[OffsetIndex],val lazyTimeIndex: LazyIndex[TimeIndex],val txnIndex: TransactionIndex,val baseOffset:…

【番外篇】实现排列组合算法(Java版)

一、说明 在牛客网的很多算法试题中,很多试题底层都是基于排列组合算法实现的,比如最优解、最大值等常见问题。排列组合算法有一定的难度,并不能用一般的多重嵌套循环解决,没有提前做针对性的学习和研究,考试时候肯定…

Linux - 线程池

线程池 什么是池? 池化技术的核心就是"提前准备并重复利用资源". 减少资源创建和销毁的成本. 那么线程池就是提前准备好一些线程, 当有任务来临时, 就可以直接交给这些线程运行, 当线程完成这些任务后, 并不会被销毁, 而是继续等待任务. 那么这些线程在程序运行过程…

【K8S系列】K8s 领域深度剖析:年度技术、工具与实战总结

引言 Kubernetes作为容器编排领域的行业标准,在过去一年里持续进化,深刻推动着云原生应用开发与部署模式的革新。本文我将深入总结在使用K8s特定技术领域的进展,分享在过去一年中相关技术工具及平台的使用体会,并展示基于K8s的技术…