【计算机视觉】人脸识别三大经典算法: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:适合复杂环境(光照、姿态、表情变化较大)下的人脸识别,鲁棒性强,且计算效率高,适合实时应用。

相关推荐
安吉升科技1 小时前
图书馆、博物馆双目ai客流统计摄像头技术机理与运行架构解析
人工智能
武子康1 小时前
低延迟不是更快地猜:EOU / Barge-in / Turn Protocol 必须统一(4 种结束 + Generation Fencing + 9 类可复现场景)
人工智能·后端·llm
您^_^1 小时前
使用技巧(十一):Claude Code 最强审问官 —— grill-me 深度指南,装完先别写代码
人工智能·windows·个人开发·claudecode·deepseek v4 pro
Lumos1861 小时前
嵌入式常用滤波算法与控制算法(5)卡尔曼滤波(下)
算法
ye小杰榨 问鼎中原ZP1 小时前
初探:用 FastAPI 搭建你的第一个 AI Agent 接口
人工智能·fastapi
Lumos1861 小时前
嵌入式常用滤波算法与控制算法(6)互补滤波
算法
AOwhisky1 小时前
AI审AI:GitLab上线AI代码审查,开发者可以松一口气了吗?
人工智能·gitlab
Asize1 小时前
别只会改 Prompt:用 AI Loop 把大模型变成可验收的执行系统
人工智能
东风破_1 小时前
Temperature 越高越有创造力吗?从概率分布、Top-K 到 LangChain 工作流
人工智能