计算机视觉基础 第16章|EigenFace,FisherFace,LBPH传统人脸识别算法

摘要

本章区分人脸检测(定位人脸位置) 与**人脸识别(判断人脸身份)**两大核心环节。OpenCV 传统人脸识别提供 3 套算法:EigenFace(特征脸)、FisherFace、LBPH(局部二值模式直方图)。

一. 人脸检测: Haar 级联预训练 XML 分类器

人脸检测 ≠ 人脸识别。 人脸检测只定位图像中人脸所在坐标,输出人脸矩形框,无法判断这个人是谁。

1.1 预训练 XML 分类器介绍

OpenCV 官方提供大量已训练完成的 Haar / LBP 预训练分类器,以 .xml 文件格式保存,内部存储大量人脸正负样本训练得到的特征模板。常用人脸相关 XML 文件:

  • haarcascade_frontalface_default.xml:Haar 特征,正面人脸检测器,最常用。
  • haarcascade_frontalface_alt.xml:优化版正面人脸检测器。
  • lbpcascade_frontalface.xml:LBP 人脸检测器,速度更快。
  • lbpcascade_animeface.xml:动漫人脸检测器(网络寻找)

**文件获取方式:**方式一:OpenCV 源码包 data 目录自带这些 XML 文件;

方式二:OpenCV 官方 GitHub 仓库下载;

方式三:网络开源资源下载。

1.2 detectMultiScale 接口与参数详解

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| python faceCascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml") faces = faceCascade.detectMultiScale(gray, scaleFactor, minNeighbors, minSize, maxSize) |

|--------------|----------------------------------------------------------------|
| 参数 | 说明 |
| image | 输入图像,必须为灰度单通道图像。 |
| scaleFactor | 图像金字塔缩放系数,多尺度扫描图片时每次窗口的缩放比例。常用 1.05 或 1.1;数值越大检测速度越快,但更容易漏检人脸。 |
| minNeighbors | 候选框邻居阈值,重叠候选框数量大于等于该值才判定为人脸。数值越大误检越少,但容易漏检,常用取值 3--9。 |
| minSize | 人脸最小像素尺寸,小于该尺寸的目标直接过滤,可过滤微小噪声干扰。 |
| maxSize | 人脸最大像素尺寸,大于该尺寸的目标直接过滤;不需要时可省略。 |

返回值 faces : 数组,每一组 (x, y, w, h) 代表一张人脸:x、y 为人脸矩形左上角坐标,w 为人脸框宽度,h 为人脸框高度。

1.3 人脸检测完整代码

python 复制代码
import cv2

# 读取图像
image = cv2.imread("moreface.png")
# Haar 检测器要求输入灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 加载官方预训练正面人脸 xml 分类器(相对路径,xml 放在项目目录)
faceCascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")

# 多尺度人脸检测
faces = faceCascade.detectMultiScale(gray, scaleFactor=1.05, minNeighbors=9, minSize=(8, 38))

print(f"检测到 {len(faces)} 张人脸")
print(f"人脸位置信息(x,y,w,h):{faces}")

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

cv2.imshow("face_detect", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

二. 传统人脸识别总览

人脸检测拿到人脸区域之后,裁剪人脸 ROI,送入人脸识别模型完成身份判断。

2.1 三大传统人脸识别算法对比

|----------------|-------------------|-----------------|---------------|-----------|----------------|
| 算法 | 核心原理 | 图像约束 | 优点 | 缺点 | 适用场景 |
| EigenFace(特征脸) | PCA 主成分分析,全局像素降维 | 训练集图片必须统一宽高、灰度图 | 计算速度快,原理简单 | 对光照变化非常敏感 | 光照稳定的室内场景 |
| FisherFace | LDA 线性判别分析,拉大类别间距 | 训练集图片必须统一宽高、灰度图 | 小样本分类效果较好 | 对光照敏感 | 样本数量较少的分类任务 |
| LBPH | 局部二值模式直方图,提取纹理特征 | 无强制尺寸要求 | 抗光照、表情变化,鲁棒性强 | 运算速度略慢 | 普通非受控环境,工程优先选用 |

2.2 统一执行流程

  1. 准备人脸样本,转为灰度图像。
  2. 构造人脸图片列表 images 与标签列表 labels,同一个人分配同一个数字标签。
  3. 创建识别器对象。
  4. 调用 recognizer.train(images, np.array(labels)) 执行训练。
  5. 调用 label, confidence = recognizer.predict(test_gray_img) 执行预测。

返回值说明:

  • label:预测输出的数字标签。
  • confidence:代表距离,不是概率,数值越小代表匹配相似度越高。EigenFace 置信度范围 0--20000,一般小于 5000 认为匹配可靠;LBPH 置信度一般小于 80 认为匹配可靠。不同算法置信度范围不能直接对比。

三. EigenFace 特征脸实战

原理:PCA 主成分分析,将高维人脸像素映射到低维特征脸子空间,计算距离完成匹配。训练集、预测图片尺寸必须完全一致。

python 复制代码
import cv2
import numpy as np

# 构建训练人脸样本
images = []
a = cv2.imread("zhaoliyin1.png", cv2.IMREAD_GRAYSCALE)
a = cv2.resize(a, (120, 180))
b = cv2.imread("zhaoliyin2.png", cv2.IMREAD_GRAYSCALE)
b = cv2.resize(b, (120, 180))
c = cv2.imread("yangmi1.png", cv2.IMREAD_GRAYSCALE)
c = cv2.resize(c, (120, 180))
d = cv2.imread("yangmi2.png", cv2.IMREAD_GRAYSCALE)
d = cv2.resize(d, (120, 180))

images.append(a)
images.append(b)
images.append(c)
images.append(d)

labels = [0, 0, 1, 1]
name_dict = {0: "zhaoliyin", 1: "yangmi", -1: "unknown"}

# 待预测图片,尺寸与训练样本保持一致
predict_image = cv2.imread("zhaoliyin3.png", cv2.IMREAD_GRAYSCALE)
predict_image = cv2.resize(predict_image, (120, 180))

# 创建 EigenFace 识别器并训练
recognizer = cv2.face.EigenFaceRecognizer_create()
recognizer.train(images, np.array(labels))

# 执行预测
label, confidence = recognizer.predict(predict_image)
print("识别结果:", name_dict[label])
print(f"置信度(距离): {confidence:.2f}")

# 在原图绘制识别文字
src_show = cv2.imread("zhaoliyin3.png").copy()
cv2.putText(src_show, name_dict[label], (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)

cv2.imshow("eigen_result", src_show)
cv2.waitKey(0)
cv2.destroyAllWindows()

四. LBPH 局部二值模式直方图实战

LBPH(Local Binary Patterns Histograms)提取人脸局部纹理特征,抗光照、表情干扰,不需要强制统一图片尺寸,是传统人脸识别工程优先选择。

python 复制代码
import cv2
import numpy as np

images = []
images.append(cv2.imread("zhaoliyin1.png", cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread("zhaoliyin2.png", cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread("yangmi1.png", cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread("yangmi2.png", cv2.IMREAD_GRAYSCALE))

labels = [0, 0, 1, 1]
name_dict = {0: "zhaoliyin", 1: "yangmi", -1: "unknown"}

predict_image = cv2.imread("zhaoliyin3.png", cv2.IMREAD_GRAYSCALE)

# 创建 LBPH 识别器,训练模型
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.train(images, np.array(labels))

# 预测
label, confidence = recognizer.predict(predict_image)
print("识别结果:", name_dict[label])
print(f"置信度(距离): {confidence:.2f}")

五. 常见问题总结

  • XML 分类器读取失败:检查文件路径,博客与项目开发建议使用相对路径,XML 文件放置项目根目录。
  • EigenFace / FisherFace:训练样本、预测样本图片尺寸必须完全一致,只能输入灰度图像,否则运行报错;LBPH 无强制尺寸约束。
  • confidence 不是概率:它代表特征空间距离,数值越小相似度越高,不同算法置信阈值不能互相混用。
  • Haar 检测器容易误检人脸:调大 minNeighbors、设置合理 minSize 过滤噪声。
  • 传统人脸识别短板:对侧脸、强光照、人脸遮挡识别效果差;现代项目大多采用深度学习人脸识别方案。

六. 本章小结

  • Haar 预训练 XML 分类器实现人脸检测,只输出人脸位置框,不能识别人的身份;XML 文件使用相对路径更适合博客与项目迁移。
  • EigenFace、FisherFace 基于全局像素降维,对光照敏感,要求样本尺寸统一;LBPH 提取局部纹理,鲁棒性更好,工程优先选用。
  • 业务标准流程:先检测人脸,裁剪人脸区域,再做人脸识别。
  • confidence 是距离度量,数值越小匹配度越高,不同算法阈值不通用。
相关推荐
zyseo81 小时前
GEO 内容可引用性体检:5 分钟检查页面是否容易被 AI 引用
大数据·人工智能
luoganttcc1 小时前
算子融合:从数学等价到编译器合法性的严格推导
人工智能
桃西西呀1 小时前
语义缓存:命中率上去了,却把问「今天天气」的人答成了「明天天气」
人工智能·llm·ai编程
GlobalInfo1 小时前
机器人强化学习平台 专精特新小巨人专项报告:细分市场占有率、行业位次与主导地位证明
人工智能·ai·机器人
Nil2081 小时前
leetcode 72编辑距离
算法·leetcode·职场和发展
Highcharts.js1 小时前
AI图表开发工具Highcharts Assist|自然语言生成图表代码
javascript·人工智能·highcharts·开发神器
嘟哩DuliDuli1 小时前
AI创作工作区的项目上下文与多模态任务边界
android·人工智能·安全·ai·软件工程
const_qiu1 小时前
第 2.5 章 2.5.4-2.5.5:JWT 双 Token 与声明式权限守卫
java·人工智能
阿Q的AI笔记1 小时前
13.7个百分点、6天16.7万星、99.9百分位会话超45分钟:Harness Engineering完全指南
人工智能·深度学习