【计算机视觉】人脸识别三大经典算法:LBPH、Eigenfaces、FisherFaces 原理与实战

人脸识别三大经典算法:LBPH、Eigenfaces、FisherFaces

  • [一、LBPH 算法(局部二值模式直方图)](#一、LBPH 算法(局部二值模式直方图))
    • [1. 基本原理](#1. 基本原理)
    • [2. 实现步骤](#2. 实现步骤)
    • [3. 代码实现](#3. 代码实现)
  • [二、Eigenfaces 算法(特征脸)](#二、Eigenfaces 算法(特征脸))
    • [1. 算法原理](#1. 算法原理)
    • [2. 特点分析](#2. 特点分析)
    • [3. 代码实现](#3. 代码实现)
  • [三、FisherFaces 算法(费舍尔脸)](#三、FisherFaces 算法(费舍尔脸))
    • [1. 算法原理](#1. 算法原理)
    • [2. 特点分析](#2. 特点分析)
    • [3. 代码实现](#3. 代码实现)
  • 四、三种算法对比总结

一、LBPH 算法(局部二值模式直方图)

1. 基本原理

LBPH(Local Binary Patterns Histograms,局部二值模式直方图)是一种经典的图像纹理特征提取方法,广泛应用于人脸识别领域。

其核心思想是:利用 LBP 算子 描述图像局部纹理特征。LBP 算子将每个像素与其邻域内的像素进行灰度值比较,将比较结果编码为二进制数。随后,通过统计这些二进制数的直方图分布来提取图像的局部纹理信息。

在人脸识别任务中,LBPH 算法将人脸图像划分为多个局部块(Block) ,分别计算每个块的 LBP 直方图,最后将所有块的直方图拼接组合,形成完整的特征向量用于识别。

2. 实现步骤

核心流程

  1. LBP 编码:以每个像素为中心,将其与周围邻域像素的灰度值进行比较,根据大小关系生成二进制编码,得到整幅图像的 LBP 编码图。

  2. 分块直方图统计:将 LBP 编码图划分为若干区域,统计每个区域的 LBP 直方图,再将所有区域的直方图拼接,得到整幅图像的完整直方图特征。

特点

LBPH 特征与 Haar 特征类似,本质上都是描述图像的灰度变化模式 。其最大优势在于鲁棒性------对光照变化、缩放、旋转和平移等干扰因素具有较强的抗干扰能力。通过比较不同人脸图像的 LBP 直方图差异,即可实现人脸识别。

3. 代码实现

python 复制代码
import cv2
import numpy as np

# 加载训练图像(灰度图)
images = []
images.append(cv2.imread('fmjj1.png', cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread('fmjj2.png', cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread('ss1.png', cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread('ss2.png', cv2.IMREAD_GRAYSCALE))

# 设置标签:前两张为"fmjj",后两张为"ss"
labels = [0, 0, 1, 1]
label_map = {0: 'fmjj', 1: 'ss', -1: '无法识别'}

# 待预测图像
predict_image = cv2.imread('fmjj.png', cv2.IMREAD_GRAYSCALE)

# 创建 LBPH 人脸识别器(设置置信度阈值 80)
recognizer = cv2.face.LBPHFaceRecognizer_create(threshold=80)

# 训练识别器
recognizer.train(images, np.array(labels))

# 预测
label, confidence = recognizer.predict(predict_image)
print('识别结果:', label_map[label])
print('置信度:', confidence)

# 在图像上显示识别结果
result_img = cv2.imread('fmjj.png').copy()
cv2.putText(result_img, label_map[label], (10, 30),
            cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
cv2.imshow('识别结果', result_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

二、Eigenfaces 算法(特征脸)

1. 算法原理

Eigenfaces 是一种基于主成分分析(PCA,Principal Component Analysis) 的人脸识别算法。其核心思想是:将高维的人脸图像数据通过 PCA 降维映射到低维空间,提取出人脸的主要特征方向(即"特征脸"),从而在保留关键信息的同时大幅降低计算复杂度。

2. 特点分析

优点 缺点
降维效果显著:将高维人脸数据压缩为低维特征,大幅减少计算量 对光照敏感:光照条件变化会显著改变人脸图像的主要特征向量
识别精度较高:提取的主要特征向量能够较好地区分不同人脸 对表情变化敏感:面部表情变化同样会影响特征向量的稳定性
计算效率高:训练和预测阶段均具有较快的处理速度 对姿态变化敏感:人脸朝向变化会影响识别效果

3. 代码实现

python 复制代码
import cv2
import numpy as np

def load_and_resize(image_path, size=(120, 180)):
    """加载图像并统一尺寸"""
    img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
    img = cv2.resize(img, size)
    return img

# 加载训练图像
images = []
images.append(load_and_resize('fmjj1.png'))
images.append(load_and_resize('fmjj2.png'))
images.append(load_and_resize('ss1.png'))
images.append(load_and_resize('ss2.png'))

# 标签
labels = [0, 0, 1, 1]
label_map = {0: 'fmjj', 1: 'ss'}

# 加载待预测图像
predict_image = load_and_resize('fmjj.png')

# 创建 Eigenfaces 识别器
recognizer = cv2.face.EigenFaceRecognizer_create()

# 训练
recognizer.train(images, np.array(labels))

# 预测
label, confidence = recognizer.predict(predict_image)
print('识别结果:', label_map[label])
print('置信度:', confidence)

# 显示结果
result_img = cv2.imread('fmjj.png').copy()
cv2.putText(result_img, label_map[label], (10, 30),
            cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
cv2.imshow('识别结果', result_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

三、FisherFaces 算法(费舍尔脸)

1. 算法原理

FisherFaces 算法基于线性判别分析(LDA,Linear Discriminant Analysis) 进行特征提取。与 Eigenfaces 的 PCA 不同,LDA 在降维过程中充分利用了类别标签信息,其优化目标为:

类内距离最小化:同一类别的样本在投影后尽可能聚集

类间距离最大化:不同类别的样本在投影后尽可能分散

通过 LDA 降维,FisherFaces 将原始人脸图像投影到低维判别空间,计算投影系数作为特征,从而实现高效识别。

2. 特点分析

优点 缺点
考虑类别信息:投影后的特征更具区分性,分类性能优于 PCA 计算复杂度较高:训练阶段需计算类内/类间散度矩阵
对光照和角度有一定鲁棒性:结合了人脸几何形状和纹理信息 小样本问题:当样本数少于特征维度时,散度矩阵可能奇异
识别准确率高:尤其在类别区分明显的任务中表现优异 需要较多训练样本:每个类别至少需要 2-3 个样本

3. 代码实现

python 复制代码
import cv2
import numpy as np

def load_and_resize(image_path, size=(120, 180)):
    """加载图像并统一尺寸"""
    img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
    img = cv2.resize(img, size)
    return img

# 加载训练图像
images = []
images.append(load_and_resize('fmjj1.png'))
images.append(load_and_resize('fmjj2.png'))
images.append(load_and_resize('ss1.png'))
images.append(load_and_resize('ss2.png'))

# 标签
labels = [0, 0, 1, 1]
label_map = {0: 'fmjj', 1: 'ss'}

# 加载待预测图像
predict_image = load_and_resize('fmjj.png')

# 创建 FisherFaces 识别器
recognizer = cv2.face.FisherFaceRecognizer_create()

# 训练
recognizer.train(images, np.array(labels))

# 预测
label, confidence = recognizer.predict(predict_image)
print('识别结果:', label_map[label])
print('置信度:', confidence)

# 显示结果
result_img = cv2.imread('fmjj.png').copy()
cv2.putText(result_img, label_map[label], (10, 30),
            cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
cv2.imshow('识别结果', result_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

四、三种算法对比总结

对比维度 Eigenfaces FisherFaces LBPH
核心原理 PCA 主成分分析 LDA 线性判别分析 局部二值模式直方图
特征类型 全局特征(特征脸) 全局特征(费舍尔脸) 局部纹理特征
是否使用标签 否(无监督) 是(有监督) 是(有监督)
降维效果 优秀 优秀 不适用(直方图)
光照鲁棒性 较差 中等 优秀
表情鲁棒性 较差 中等 优秀
姿态鲁棒性 较差 中等 良好
计算复杂度 较低 中等 较低
适用场景 大规模数据集、光照可控 注重分类性能 复杂环境、实时识别

Eigenfaces:适合处理大规模数据集,对光照和表情变化不敏感的场景,或作为基线算法快速验证。

FisherFaces:适合需要较高分类精度的任务,尤其当各类别样本分布较为清晰时,识别效果优于 Eigenfaces。

LBPH:适合复杂环境(光照、姿态、表情变化较大)下的人脸识别,鲁棒性强,且计算效率高,适合实时应用。

相关推荐
luckystar513~1 分钟前
Hermes 实战 :系列收官/生产化——安全审计与运维
运维·人工智能·安全·agent·智能体开发·hermes实战·智能体网关
Mickey Q18 分钟前
【深度学习】数值稳定性和模型初始化
人工智能·深度学习
冬奇Lab25 分钟前
Code Agent 解剖(20):从零扩展——给 agent 加一个新工具
人工智能·开源
论文复现现场26 分钟前
RTX 4090 24GB 能跑 Qwen3.8-27B 吗?单卡显存计算与云端部署指南
人工智能·python·云计算·llama·gpu算力
七牛云行业应用27 分钟前
Harness Engineering 是什么:从“写提示词“到“设计 Agent 边界“的工程方法论
人工智能·agent·ai编程
科技拓维者34 分钟前
短视频配音音效去哪里找比较好?短视频创作者音效指南
人工智能·音视频
cjy00011139 分钟前
2026AI 产品如何从一次性 Demo 变成可重复使用的业务工具?
前端·人工智能·fde
大模型码小白42 分钟前
AI大模型接入SDK:人工智能核心概念与发展史
大数据·运维·人工智能·安全·prompt
杀生丸学AI44 分钟前
【动态重建】Flow4DGS-SLAM:基于光流引导的4DGS-SLAM算法
人工智能·三维重建·扩散模型·4dgs·动态重建
IT_陈寒1 小时前
React的状态更新坑得我差点加班到天亮
前端·人工智能·后端