尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
MB_LBP+PCA+SVM:传统人脸识别流程详解
简介面向人脸识别方向的研究者、算法初学者与模式识别课程学习者这份PDF围绕多块局部二值模式MB_LBP与主成分分析PCA的融合算法展开。资源从LBP和PCA各自优缺点切入说明MB_LBP如何通过块级平均灰度比较增强局部特征稳定性再由PCA对人脸特征降维最终使用SVM完成分类与识别ORL人脸库实验显示该组合方法比传统PCA识别率提升13%以上。压缩包共1个PDF文件大小约850KB内容包含算法原理、实现流程、实验数据与结论结构完整适合作为人脸识别课题的参考文献、算法对比实验的起点、组会汇报素材或课程报告写作参考。文中对姿态变化、光照变化等识别难点也给出了针对性分析可帮助理解算法改进动机。已有126人学习适合希望快速建立方法框架并进一步复现实验的读者。1. 为什么人脸识别要回到 LBP 这条老路2016 年这篇论文在 ORL 人脸库上把识别率抬高了 13%放到今天看数字不算惊艳但它的思路在深度学习普及之前是工程落地最稳的一类方案不做端到端学习而是先用人工设计的特征描述人脸纹理再用线性降维压缩特征维度最后交给一个经典分类器完成判别。这套流程的价值在于可解释性和低资源依赖即便现在用 OpenCV 或树莓派做离线人脸识别依然绕不开 LBP 或其变体。MB_LBP 是对原始 LBP 的改进核心改动只有一处——把「单个像素对单个像素」的比较换成「像素块平均灰度对像素块平均灰度」的比较。这个改动的直接收益是抗噪能力提升代价是需要手动调分块大小。全文沿着特征提取、降维、分类这条主线展开适合两类读者一类是想复现传统人脸识别流程的入门者另一类是在嵌入式设备上做实时识别、需要控制计算量的工程师。2. LBP 到 MB_LBP从像素比较到块均值比较2.1 原始 LBP 的特征提取逻辑与噪声缺陷原始 LBP 对图像中每个像素计算一个二进制编码。取当前像素的灰度值为阈值与其半径为 R 的邻域内 P 个采样点的灰度值逐一比较邻域灰度大于等于中心灰度记为 1否则记为 0按固定顺序排列得到一个 P 位二进制数再转为十进制作为该像素的 LBP 值。这个编码描述的是局部纹理模式对单调灰度变化不敏感因此光照变化下仍能保持相对稳定。但原始 LBP 的缺陷也很明显。它假设中心像素本身是可靠的一旦中心像素恰好落在噪声点、反光区域或者传感器坏点上比较结果会被整体带偏。另一个问题是采样点落在非整数坐标时需要使用插值插值误差在小半径场景下会被放大。Ahonen 等人把人脸划分成不重叠区域在每个区域内统计 LBP 直方图再拼接成特征向量但这个做法解决不了单像素比较的不稳定性问题。2.2 MB_LBP 的公式化描述与参数含义MB_LBP 把比较粒度从像素提升到块。设中心块大小为s × s其平均灰度为g_c周围第 i 个块的大小同样为s × s平均灰度为g_i则中心像素的 MB_LBP 编码公式为MB_LBP(P, R, s) Σ_{i0}^{P-1} sign(g_i - g_c) · 2^i其中sign(x)在x ≥ 0时取 1否则取 0。P表示周围块的数量R表示周围块中心到中心块中心的距离。注意这里的 R 不再是像素半径而是块中心间距实际感受野比原始 LBP 大得多。论文中采用的矩形块划分方式计算块均值后进行比较。当s 1时MB_LBP 退化为原始 LBP所以原始 LBP 是 MB_LBP 的特例。增大 s 相当于对图像做了局部平滑能抑制高频噪声但 s 过大会把眼睛、鼻子边缘等真实纹理也抹掉导致人脸看起来“粒度化”。分块大小是一个需要针对人脸库分辨率调节的超参数论文实验部分对 ORL 库的 92×112 图像块大小取 3×3 或 5×5 是比较合理的起点。2.3 直方图特征的分块统计策略提取完整张图的 MB_LBP 响应图后还需要把响应图转化为特征向量。常见做法是把人脸图像划分为m × n个互不重叠的子区域对每个子区域统计 256 维的 MB_LBP 直方图再把所有子区域的直方图首尾拼接。若划分为4 × 4个子区域最终特征维度是16 × 256 4096维。这里有一个工程取舍子区域划分越多空间信息保留越完整但特征维度越高且每个子区域的统计样本越少直方图越稀疏。论文采用固定划分没有做自适应区域加权这在实际使用中是可以优化的点——眼睛、鼻子区域对人脸识别贡献更大可以赋予更高权重而额头和下巴区域权重可以降低。3. PCA 降维消除冗余保留主成分3.1 PCA 作用于 MB_LBP 特征而非原始像素论文的关键细节是PCA 不是直接作用在原始人脸图像上而是作用在 MB_LBP 直方图拼接后的高维特征上。这一步决定了整个算法的性质——MB_LBP 负责提取局部纹理信息PCA 负责去除特征维度间的相关性并压缩数据。原始像素经过 PCA 得到的是特征脸Eigenface反映的是整体灰度分布而 MB_LBP 特征经过 PCA 得到的是对局部纹理模式的主成分两者语义不同。3.2 协方差矩阵与特征降维的计算流程假设训练集有 N 张人脸图像每张图像经过 MB_LBP 处理后得到 D 维特征向量x_i构成数据矩阵X ∈ R^{N×D}。PCA 的完整计算步骤如下去均值计算所有训练样本的平均特征向量μ (1/N) Σ x_i每个样本减去平均特征x_i x_i - μ目的是让后续协方差计算不受整体亮度偏移影响。计算协方差矩阵C (1/N) X^T X这里X是去均值后的特征矩阵。协方差矩阵的对角线元素表示各维度的方差非对角线元素表示维度间的协方差PCA 的目标就是找到一组新基使得数据在新基上的方差最大化、协方差最小化。特征值分解对协方差矩阵做特征值分解得到特征值λ_1 ≥ λ_2 ≥ ... ≥ λ_D及对应的特征向量。特征值大小代表对应方向上方差的大小即信息量的多少。选择主成分个数 k取前 k 个最大特征值对应的特征向量构成投影矩阵W ∈ R^{D×k}k 的选取通常根据累计贡献率Σ_{i1}^k λ_i / Σ_{i1}^D λ_i ≥ 0.95来决定。投影降维将原始特征x_i投影到新空间y_i W^T x_i得到 k 维向量作为最终的人脸特征表示。3.3 为什么用奇异值分解而不是直接求协方差当 D 远大于 N 时协方差矩阵 C 的维度是D × D直接求特征值分解的计算量过大。论文原文提到对协方差矩阵进行奇异值分解SVD这是一种等价但更稳定的数值计算方法。SVD 将数据矩阵X分解为U Σ V^T其中 V 的列向量就是协方差矩阵的特征向量Σ 的对角元素是奇异值等于特征值的平方根。使用 SVD 避免了显式构造协方差矩阵数值稳定性更好尤其在特征维度高、样本数少的情况下优势明显。实际实现中直接调用numpy.linalg.svd即可不需要手写分解算法。import numpy as np from sklearn.decomposition import PCA # X_mb_lbp 是 MB_LBP 特征矩阵形状为 (N, D)N 为训练样本数 # 方法一直接调用 sklearn 封装的 PCA pca PCA(n_components0.95) # 保留 95% 累计方差贡献率 X_pca pca.fit_transform(X_mb_lbp) print(f降维前特征维度: {X_mb_lbp.shape[1]}) print(f降维后特征维度: {X_pca.shape[1]}) print(f各主成分解释方差比: {pca.explained_variance_ratio_}) # 方法二手动 SVD 实现便于理解内部逻辑 X_mean np.mean(X_mb_lbp, axis0) X_centered X_mb_lbp - X_mean U, S, Vt np.linalg.svd(X_centered, full_matricesFalse) # Vt 的行向量是特征向量按对应奇异值大小降序排列 # 累计贡献率达到 95% 时所需的主成分个数 cumsum_ratio np.cumsum(S**2) / np.sum(S**2) k np.argmax(cumsum_ratio 0.95) 1 W Vt[:k].T # 投影矩阵形状为 (D, k) X_pca_manual X_centered W代码中的n_components0.95表示自动选择使累计方差贡献率达到 95% 的主成分个数ORL 库上通常落在 40 到 80 之间。explained_variance_ratio_输出每个主成分单独解释的方差比例前几个主成分占比很大后续快速衰减验证了人脸特征在低维空间具有集中分布的特性。手动 SVD 版本中S**2对应特征值通过累计占比曲线可以直观看到 k 的选取依据。两种方式结果一致推荐使用 sklearn 版本做实验手动版本用于理解原理。4. SVM 分类器与 ORL 实验复现4.1 SVM 的人脸识别原理与核函数选择SVM 的核心思想是找到一个超平面使得两类样本之间的间隔最大化。人脸识别场景下降维后的特征向量输入 SVM通过核函数把低维空间中的非线性可分问题映射到高维空间在高维空间中构造线性分类超平面。论文采用的判别函数为f(x) sign(Σ_{i1}^{n} α_i y_i K(x_i, x) b)其中 K 是核函数用于计算两个样本在高维空间中的内积。对于人脸特征这类高维小样本数据径向基核函数RBF通常是默认选择K(x_i, x_j) exp(-γ ||x_i - x_j||²)RBF 核的优点是只有一个参数 γ 需要调而且能把特征映射到无限维空间表达能力比线性核强。但 γ 过大会导致过拟合——每个训练样本都成为支持向量测试时泛化能力差γ 过小则模型过于平滑无法区分相近的人脸。论文没有给出具体的 γ 和 C 参数这属于实现细节使用网格搜索可以从数据中确定。4.2 ORL 数据集上的训练流程ORL 人脸库包含 40 个不同人的 400 张灰度图像每人 10 张分辨率为 92×112 像素。实验通常采用留出法随机选取每人 5 张作为训练集剩余 5 张作为测试集这样训练集共 200 张测试集共 200 张。完整训练流程分为特征提取、降维、分类三个环节import cv2 import numpy as np from sklearn import svm from sklearn.model_selection import GridSearchCV, train_test_split from sklearn.decomposition import PCA from sklearn.metrics import accuracy_score def mb_lbp_feature(image, block_size3, sub_regions(4, 4)): 提取 MB_LBP 特征返回归一化直方图 h, w image.shape # 将图像划分为子区域在每个子区域内逐像素计算 MB_LBP histograms [] region_h, region_w h // sub_regions[0], w // sub_regions[1] for i in range(sub_regions[0]): for j in range(sub_regions[1]): region image[i*region_h:(i1)*region_h, j*region_w:(j1)*region_w] # 此处简化处理实际 MB_LBP 需要对每个像素计算块均值比较 # 完整实现使用积分图加速块均值计算 hist, _ np.histogram(region.ravel(), bins256, range(0, 256)) hist hist / (np.sum(hist) 1e-6) # 归一化消除光照幅度影响 histograms.extend(hist) return np.array(histograms) # 加载 ORL 数据集images 为 (400, 92, 112) 数组labels 为 (400,) 数组 # 假设 images 和 labels 已从 ORL 目录读取 X np.array([mb_lbp_feature(img) for img in images]) y labels # 划分训练集和测试集每人 5 张训练5 张测试 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.5, stratifyy, random_state42 ) # PCA 降维在训练集上拟合测试集用同一变换 pca PCA(n_components0.95, whitenTrue) X_train_pca pca.fit_transform(X_train) X_test_pca pca.transform(X_test) print(f降维后维度: {X_train_pca.shape[1]}) # 网格搜索找到最优 RBF 核参数 param_grid {C: [1, 10, 100], gamma: [0.001, 0.01, 0.1]} clf GridSearchCV(svm.SVC(kernelrbf), param_grid, cv5) clf.fit(X_train_pca, y_train) # 测试集上评估 y_pred clf.predict(X_test_pca) acc accuracy_score(y_test, y_pred) print(f测试集识别率: {acc:.4f}) print(f最优参数: {clf.best_params_})这段代码的要点在于stratifyy保证训练集和测试集中每类样本比例相同防止某个人的人脸全部落在训练集导致测试集失效whitenTrue对降维后的特征做标准化使得各维度方差一致避免数值范围差异影响 SVM 的间隔计算网格搜索的C是误分类惩罚系数C越大对错误分类的惩罚越重决策边界越复杂。4.3 识别率提升 13% 的构成分析论文给出的对比是 MB_LBPPCA 相对传统 PCA 识别率提升 13% 以上。这个提升来自两个环节的叠加MB_LBP 特征比原始像素特征对光照和姿态变化更鲁棒这是主要贡献PCA 在 MB_LBP 特征上降维比在原始像素上降维保留了更多的判别信息。还有一个隐性因素是 SVM 的强分类能力——传统 PCA 方法通常配合最近邻分类器SVM 的间隔最大化策略在小样本条件下比最近邻更稳定。复现时需要注意13% 的提升比例依赖具体的随机划分。如果训练集和测试集的划分不同提升幅度会有波动。论文没有披露是否采用多次随机实验取平均值实际复现建议做 5 次随机划分取均值减少因划分偶然性带来的偏差。5. 参数边界、光照场景与工程实现细节5.1 分块大小的取值边界MB_LBP 算法中分块大小直接决定感受野和抗噪能力。对于 92×112 分辨率的 ORL 图像建议测试 1×1、3×3、5×5、7×7 四组取值。实验规律一般是从 1×1 增大到 3×3 时识别率上升因为噪声被局部平均抑制继续增大到 7×7 时识别率开始下降因为眼睛、嘴巴等关键纹理被过度平滑个体差异性被抹除。如果人脸图像分辨率更高比如 128×128 以上可以尝试 5×5 到 9×9 的范围。提示分块大小的选取需要和人脸对齐质量联动。如果人脸检测框偏差较大较小的分块反而对位置偏移更敏感此时适当增大分块尺寸能提升鲁棒性。5.2 主成分个数 k 的验证方法PCA 降维的 k 值不一定要固定为 95% 累计贡献率可以用单变量搜索的方式验证不同 k 下的识别率变化。在 ORL 库上k 从 10 增长到 30 时识别率上升明显30 到 80 之间趋于平缓超过 80 后可能出现轻微下降——这是维度诅咒的表现特征维度过高而训练样本有限SVM 在高维空间中容易过拟合。绘制「k 值-识别率」曲线可以更直观地看到拐点位置作为最终参数选择依据。5.3 光照变化场景下的特征归一化MB_LBP 对单调光照变化天然不敏感因为比较操作去除了绝对灰度信息。但实际场景中光照往往是非均匀的人脸一侧亮一侧暗。处理办法是在 MB_LBP 直方图归一化基础上再做一次直方图均衡化或局部对比度归一化。另一种做法是把人脸图像划分成多个环形区域对每个区域分别做灰度归一化消除人脸两侧的光照梯度影响。这些改进方向在文章末尾提到了分块大小的讨论但归一化策略同样值得关注。5.4 计算效率对比与部署建议原始像素 PCA 需要对 92×11210304 维向量做协方差计算而 MB_LBP 特征经过 PCA 降维后仅保留几十个维度后续每次识别只涉及一次投影和一次 SVM 决策计算量低一个数量级。如果部署到树莓派或移动端建议进一步精简用积分图加速 MB_LBP 的块均值计算将每个子区域的直方图合并为统一编码映射表减少循环次数。实际工程中还可以把人脸检测和人脸识别串联在检测阶段用 Haar cascade 或 OpenCV 的 DNN 人脸检测器定位人脸再裁剪送入 MB_LBPPCA 流水线整体帧率在树莓派 4 上可以达到每秒 8 到 12 帧。本文还有配套的精品资源点击获取
RELATED

相关推荐

OFDM物理层链路级仿真:基于802.11a/g的完整代码解析

OFDM物理层链路级仿真:基于802.11a/g的完整代码解析

从我在通信专业折腾物理层仿真的经验说起。无论你是在准备课程设计,还是刚进无线通信实验室想找个靠谱的起点,大概率都遇到过这种尴尬:想找一套能真正讲清楚“比特是怎么变成无线信号、又是怎么变回来的”的IEEE 802.11a/g ERP-OFDM物理层链路…

📅 2026/9/19 15:48:34
LeetCode 673 题解:最长递增子序列的个数(LIS 双状态动态规划)

LeetCode 673 题解:最长递增子序列的个数(LIS 双状态动态规划)

LeetCode 673 题解:最长递增子序列的个数(LIS 双状态动态规划) 【免费下载链接】leetcode LeetCode Solutions: A Record of My Problem Solving Journey.( leetcode题解,记录自己的leetcode解题之路。) 项目地址: https://gitc…

📅 2026/9/19 15:48:34
GoogleTest gMock(Google Mock)C++ 模拟框架实战指南:从 Mock 类编写到期望验证

GoogleTest gMock(Google Mock)C++ 模拟框架实战指南:从 Mock 类编写到期望验证

GoogleTest gMock(Google Mock)C 模拟框架实战指南:从 Mock 类编写到期望验证 【免费下载链接】googletest GoogleTest - Google Testing and Mocking Framework 项目地址: https://gitcode.com/gh_mirrors/googl/googletest gMock&am…

📅 2026/9/19 15:43:34
MORE NEWS

更多资讯

📰

一文读懂CMake:跨平台构建系统生成器核心概念与实战指南

弄懂CMake是什么,看完这篇就够了!第一次正经接触CMake,是在一个需要跨平台编译的C项目里。项目从Windows迁到Linux,Makefile那套东西变得极其难维护,同事丢过来一个CMakeLists.txt说“用这个”,我盯着那堆大…

📰

CANN Runtime Event 管理 API 模块化拆分指南:22 个 ACL 接口的批次规划、归属判定与三阶段迁移实践

CANN Runtime Event 管理 API 模块化拆分指南:22 个 ACL 接口的批次规划、归属判定与三阶段迁移实践 【免费下载链接】runtime 本项目提供CANN运行时组件和维测功能组件。 项目地址: https://gitcode.com/cann/runtime CANN Runtime 的 Event 管理模块面向用…

📰

GitHub Copilot替代工具实测:VS Code与Edge场景下的免费方案盘点

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

ESP32-P4 USB Host鼠标开发全栈排错指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

BrewUI:给Homebrew加可视化界面,让包管理和依赖清理更安全

1. BrewUI是什么,以及它瞄准的三个真实痛点先交代一下背景。我在macOS上用了三年多的Homebrew,日常维护的软件包早就超过了200个,每次想理清楚某个工具是被谁依赖的、哪些包该升级、哪些包该清理,都要在终端里敲一串brew deps --t…

📰

Grafana Tempo 中的 OTLP 指标名转换:深入解析 otlptranslator 的 Prometheus 命名规范化

后端可观测性链路追踪 【免费下载链接】tempo Grafana Tempo is a high volume, minimal dependency distributed tracing backend. 项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo 点击查看 免费下载 导读 本篇文章围绕 Tempo 仓库中随 vendored 引…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬