ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Matlab人脸识别课设实战:PCA特征脸、参数调优与避坑指南

Matlab人脸识别课设实战:PCA特征脸、参数调优与避坑指南 简介这是一套基于MATLAB平台的人脸识别系统实现方案与课程设计报告面向图像处理、模式识别方向的课程设计学生和Matlab入门开发者帮助理解从图像预处理、特征提取到模式匹配的完整工作流。资源包共136个文件约2.43MB以105张bmp人脸样本图像为主配合2个m源码文件、1个fig图形文件、1份pdf和1份md课程设计文档另有zbak备份文件覆盖样本数据、程序实现与说明文档三大类。系统涵盖图像预处理、特征提取与模式匹配等模块代码遵循规范的编程准则关键算法步骤均配有详细注释并经过反复调试可在常规Matlab环境下稳定运行。已有26人学习适合作为课程设计参考、算法复现练习或答辩准备资料。配套设计报告系统阐述了理论基础、算法选择依据、系统架构设计及性能评估方法读者可结合源码对照学习也可参考其报告组织方式完成自己的课程设计文档。1. 基于Matlab的人脸识别系统课设从“能跑”到“能答辩”差在哪课程设计选人脸识别方向的人每年都很多但答辩现场翻车的更多。不少同学从网上拼一段代码跑ORL库报个98%识别率老师一调摄像头换个人、换个光照系统直接乱认。问题不在算法不够先进而在多数人只做到了“代码能跑”没做到“系统能讲”。下面这条实现链路基于Matlab把人脸识别从原理拆到落地先说清PCA特征脸为什么能在课设里立住再给出从ORL数据集训练到摄像头实时识别的完整代码随后把降维维数、距离度量、数据划分三个参数逐个调给你看避坑章收录了五个最典型的翻车现场。新手能照着敲完熟手可以直接抄走参数表和排错思路。2. 人脸识别原理与Matlab选型特征脸为什么还是课设的主线人脸识别到今天的深度学习方案确实猛普通人脸库里随便一个CNN都能做到99%以上但课程设计选Matlab加特征脸仍然是最稳妥的组合。原因有三一是Matlab对传统图像处理函数的封装非常完整几十行就能把从图像输入到分类输出的链路走通二是PCA特征脸涉及矩阵分解、特征值、降维这些线性代数和数字图像处理的核心考点报告能写深答辩能展开三是ORL这类小型人脸库上PCA加最近邻的识别率做到90%以上并不难加上LDA改进后可以摸到95%和深度学习的差距没有想象中那么大但原理完全在课设知识范围内。先把系统拆成流程再对比两种主流特征提取算法最后交代Matlab环境要准备哪些工具箱。这样你写报告的时候原理部分和实现部分不会两张皮。市面上人脸识别门禁机、考勤机的算法主干也基本是这个流程Matlab方案正好充当嵌入式门禁方案的算法验证原型。2.1 人脸识别四步流程拆解检测、对齐、特征提取、分类各自干什么一套传统人脸识别系统不管怎么改主干都离不开四步人脸检测、人脸对齐、特征提取、分类判决。与其把代码东一块西一块凑在一起不如按这四步去组织你的函数和报告目录写出来才像一套系统而不是测试脚本。人脸检测这一步解决“人脸在哪”。Matlab里最直接的方式是调用vision.CascadeObjectDetector它实现的是Viola-Jones检测器基于Haar特征和AdaBoost级联。检测器返回一组边界框坐标形式是[x y width height]。课程设计只需要用它框出人脸区域不要求自己实现级联分类器这部分属于Computer Vision Toolbox。人脸对齐解决“人脸摆正没有”。理论上要检测眼睛、鼻子等关键点再通过仿射变换把人脸转到标准位置。课设阶段很多人会省略这一步但省略的代价是识别率对姿态和光照敏感后面避坑章会专门讲。实现上可以用眼睛检测模型找到眼睛位置再estimateGeometricTransform做射影变换。我一般建议课设至少做一步简单的尺寸归一化加直方图均衡成本低、收益明显。特征提取和分类是重头。特征提取把一张112×92、总共10304像素的人脸图像压缩成几十上百维的向量这一步做得好坏直接决定识别效果。PCA把人脸投影到特征脸空间LDA再投影一次让类间距离最大、类内距离最小。分类阶段最简单且有效的是最近邻即计算测试样本与所有训练样本的距离取最近的那个当结果。四步逻辑理清楚后选型就顺理成章了。2.2 特征脸(PCA)与Fisher脸(LDA)对比什么时候选PCA、什么时候补LDAPCA和LDA是两种特征提取策略。PCA是无监督的只盯着全体数据的方差投影方向让数据重构误差最小LDA是有监督的把类别信息拉进来让不同人的投影尽量分开、同一个人的投影尽量聚拢。听起来LDA更划算但LDA有一个前提类内散度矩阵必须可逆这对小样本高维数据极其苛刻。课程设计用ORL这类40人乘10张的小库每类只有10个样本直接算类内散度矩阵维度是10304×10304奇异性几乎是必然的。主流做法是两段式先用PCA把维度压到40到100再做LDAFisher判别的数值稳定性就上来了。如果嫌麻烦只做PCA加最近邻也能到90%以上做课设完全够用。报告里把PCA基线和PCA加LDA改进两种都跑了识别率有个提升梯度答辩时有话讲。对比项特征脸(PCA)Fisher脸(PCALDA)监督信息无监督只看方差有监督利用类别标签数值稳定性用SVD稳定小样本下易奇异ORL库经验识别率约90%到95%约94%到98%实现复杂度低中课设推荐度必做基线作为改进方案表格里的识别率是经验区间不同数据划分差异大别当硬指标写进报告自己跑出来的数字才算数。如果问哪个更值得写进报告我的答案是两个都写。原理部分对比这两种算法实验部分给出PCA和PCA加LDA两条识别率曲线这是很像样的课设工作量。很多高分课设报告本质上就是把“基线、改进、对比”这套实验逻辑走完整了。2.3 Matlab环境与工具箱装哪些组件、什么版本能跑、硬件够不够开始写代码之前先把环境确认一遍。Matlab版本不是越新越好r2018a以上其实都够用新版r2023b、r2026b在webcam函数和App Designer上体验更好但老版本配Computer Vision Toolbox跑人脸检测也没问题。最重要的是工具箱别漏装Image Processing Toolbox、Statistics and Machine Learning Toolbox、Computer Vision Toolbox、Camera Support Package这四样基本是标配。安装时工具箱没勾全运行到对应函数才报错来回补装很耽误事。硬件方面课设阶段完全不需要GPU。ORL全库400张图训练PCA普通笔记本算SVD也就是秒级到十秒级的事。如果换成自拍高清大图1920×1080全尺寸进PCA协方差矩阵会非常大内存占用问题在避坑章详细展开。内存8G跑ORL绰绰有余16G想怎么折腾都行。有两个小习惯建议先养成。一是脚本里所有路径用相对路径或统一用fullfile拼接避免换机器跑就报找不到文件。二是Matlab中文注释在老版本里偶尔会乱码特别是r2018a到r2022b这一段如果被注释问题干扰要么用英文注释要么直接升到r2023b以上。这些对后面几个章节的复现体验影响很大。3. 用Matlab实现人脸识别核心代码ORL数据集训练与摄像头实时识别现在开始写代码。这一章按数据准备、训练与测试、摄像头实时识别的顺序推进每段代码都给出能直接运行的函数和调用方式。ORL数据库在课设里很常见老师一般会随课件一起发如果手里没有用自己拍的10个人每人10张照片组成小库也能跑通流程只是预处理成本更高新手不建议从自采数据开始。3.1 数据准备ORL人脸库读取、灰度化、尺寸归一化的标准操作ORL库每张图像是112×92的8位灰度pgm格式40人每人10张目录结构一般是s1/1.pgm到s40/10.pgm。第一步是把400张图读进来、展平成列向量、组装成特征矩阵X每一列是一张图同时记录标签向量。% trainFaceModel.m - 训练主函数 % dataDir: ORL数据根目录k: 保留的主成分个数 function model trainFaceModel(dataDir, k) numClasses 40; % ORL库共40个人 numPerClass 10; % 每人10张 imgRows 112; imgCols 92; % ORL每张图固定尺寸 X zeros(imgRows * imgCols, numClasses * numPerClass); labels zeros(numClasses * numPerClass, 1); col 1; for i 1:numClasses for j 1:numPerClass imgPath fullfile(dataDir, sprintf(s%d/%d.pgm, i, j)); img imread(imgPath); img imresize(img, [imgRows imgCols]); % 防御性统一尺寸 X(:, col) double(img(:)); % 展平成列向量 labels(col) i; col col 1; end end % 后续PCA代码见3.2节这段代码有两点值得说明。一是X用预分配的zeros而不是循环里动态拼X(:, end1)数据量大时后者会反复申请内存慢且容易触发内存碎片。二是imread读进来是uint8直接做减法运算容易溢出所以存进X前用double转换。sprintf里%d.pgm这种路径格式依赖ORL库默认的文件名如果你手里的库是别的命名规则改成对应格式即可。如果你混入了彩色图imresize会在后面矩阵运算时报维度错误建议加一行assert(ndims(img) 2)。3.2 训练与测试PCA投影加最近邻分类的完整Matlab代码模型的核心结构很简单均值脸、投影矩阵W、训练样本的投影特征Y和标签。用SVD而不是直接对协方差矩阵做特征分解数值上更稳、速度也更快避坑章会展开讲为什么不能用cov加eig。% 训练PCA模型 meanFace mean(X, 2); % 均值脸用于后续中心化 Xc X - meanFace; % 中心化 [U, S, ~] svd(Xc, econ); % 经济型SVD只算有效分量 W U(:, 1:k); % 取前k个特征向量作为投影矩阵 model.W W; model.meanFace meanFace; model.YTrain W * Xc; % 训练集投影到特征脸空间k x N model.trainLabels labels; endsvd(Xc, econ)返回的U是d乘min(d, N)的矩阵d等于10304N等于400这里U就是10304×400。取前k列作为W每一列对应一个最大方差方向的特征脸。训练样本被投影成k维向量存成YTrain供测试时算距离。k是最重要的超参数第4章专门讲怎么定。测试函数接受一张图像矩阵投影后和所有训练样本比距离。% recognizeFace.m - 识别单张人脸 % model: trainFaceModel返回的结构体img: 112x92灰度图 function label recognizeFace(model, img) img imresize(img, [112 92]); % 统一输入尺寸 x double(img(:)) - model.meanFace; % 中心化 y model.W * x; % 投影到特征脸空间 d sqrt(sum((model.YTrain - y) .^ 2, 1)); % 欧氏距离 [~, idx] min(d); label model.trainLabels(idx); % 返回最近邻的标签 end用欧氏距离做最近邻是特征脸方案最经典的默认设置。sum(..., 1)按列求和得到当前测试样本与全部400个训练样本的距离向量min取最近的索引再映射到标签。调用方式就三行% 主脚本 main.m model trainFaceModel(ORL, 40); testImg imread(fullfile(ORL, s1, 2.pgm)); % 拿某人第2张测试 label recognizeFace(model, testImg); fprintf(识别结果: 第%d号真实类别: 1\n, label);提示第一次运行时建议先打印model.YTrain的尺寸确认投影维度常见错误是把k设得比训练样本数还大导致W * Xc维度对不上。3.3 扩展用webcam和CascadeObjectDetector做实时人脸识别训练完就要演示演示就得摄像头实时识别。Matlab里摄像头采集用webcam函数人脸检测用vision.CascadeObjectDetector这两个函数分属不同工具箱缺一个都会在运行时报Undefined function。% liveRecognition.m - 实时识别演示脚本 cam webcam(1); % 1为设备序号只有一个摄像头时写1 detector vision.CascadeObjectDetector(FrontalFaceCART); model trainFaceModel(ORL, 40); % 训练一次后续帧只做预测 for i 1:300 frame snapshot(cam); % 采集一帧uint8彩色图 bbox detector(frame); % 检测人脸返回Nx4矩阵 if ~isempty(bbox) % 取面积最大的人脸框避免把背景误检当主目标 areas bbox(:, 3) .* bbox(:, 4); [~, bi] max(areas); face imcrop(frame, bbox(bi, :)); % 按框裁剪 face imresize(face, [112 92]); if size(face, 3) 3 face rgb2gray(face); % 彩色转灰度 end label recognizeFace(model, face); % 识别 frame insertObjectAnnotation(frame, rectangle, ... bbox(bi, :), sprintf(ID: %d, label), Color, green); end imshow(frame); drawnow; % 强制刷新画面 endvision.CascadeObjectDetector的构造参数FrontalFaceCART是预训练的人脸检测模型比默认的FrontalFace检测率更高误检略多。检测器对小于20×20像素的人脸直接忽略webcam(1)的序号可以执行webcamlist查看。imcrop的bbox坐标必须严格是[x y width height]索引用错会在裁剪后取到空白或越界图像。这个脚本跑起来后就能在视频流里框出人脸并标出ID。两个注意点一是每次循环新建摄像头对象是常见的性能陷阱正确做法是循环外只开一次二是在for循环里用imshow加drawnow虽然直观但速度偏慢追求流畅度可以用vision.VideoPlayer替代。实时识别对光照的敏感度比静态库大得多建议在recognizeFace之前加一步adapthisteq直方图均衡能明显压低侧光和逆光的影响代价只是每帧多几毫秒。4. 识别率调优的三个关键参数降维维数、距离度量、数据划分代码跑通后识别率不一定好看甚至可能出现训练集接近100%、测试集只有60%这种尴尬结果。问题大概率出在三个参数上PCA保留多少维、最近邻用什么距离、训练测试集怎么划分。这三个参数相互牵连逐个调完识别率通常能提升5到10个百分点。4.1 降维维数的选择特征值能量比与识别率曲线的结合判断PCA保留的主成分数k是最敏感的参数。k太小丢信息太多不同人脸在低维空间挤成一团k太大噪声和光照差异又混进来等价于没有降维。常见的定法有两种按特征值能量比或扫识别率曲线。SVD求出的奇异值S对应特征向量的能量能量比直接反映当前k个主成分抓住了原始数据多大的方差比例。% 按能量比选取k的参考代码 [~, S, ~] svd(Xc, econ); energy cumsum(diag(S).^2) / sum(diag(S).^2); k95 find(energy 0.95, 1); % 95%能量 k99 find(energy 0.99, 1); % 99%能量 fprintf(k95%% %d, k99%% %d\n, k95, k99);奇异值平方等于特征值cumsum计算累加占比find找到第一个超过阈值的索引。ORL上经验值通常是k95在30到50之间k99在60到100之间。课设建议以识别率曲线为准能量比例只作为初值参考因为抓住方差和分类正确并不完全等价。识别率曲线是更直接的做法k从5扫到100每次用固定划分做一遍测试画识别率随k变化的曲线曲线峰值对应的k就是最优值。你会发现曲线往往是先涨后跌峰值后下跌就是过拟合了噪声。% 扫描k并记录识别率 ks 5:5:100; accs zeros(size(ks)); for idx 1:length(ks) model trainFaceModel(ORL, ks(idx)); acc testAll(model, ORL); % 用测试集统计识别率 accs(idx) acc; end plot(ks, accs, o-); xlabel(降维维数k); ylabel(识别率); grid on;提示如果跑出来的曲线从某个k之后识别率剧烈震荡先检查是不是训练集和测试集划分不稳定见4.3节。4.2 距离度量对比欧氏距离、曼哈顿距离、余弦相似度的课设实验距离度量决定了“最近邻”的“最近”是什么含义。欧氏距离对每个维度的绝对差敏感适合特征脸空间里方差近似各向同性的情况曼哈顿距离是各维度绝对差求和对离群点更鲁棒余弦相似度只看方向不看模长对光照造成的整体亮度变化相对不敏感。课设实验里把三种距离都跑一遍是性价比极高的内容。实现只需要改recognizeFace里的距离计算。% 三种距离的最近邻写法只列距离核心行 diffMat model.YTrain - y; % y: 测试投影 eucl sqrt(sum(diffMat.^2, 1)); % 欧氏距离 manh sum(abs(diffMat), 1); % 曼哈顿距离 cosSim (model.YTrain * y) ./ (sqrt(sum(model.YTrain.^2, 1)) * norm(y) eps); cosDist 1 - cosSim; % 转成距离越小越近cosSim计算中model.YTrain * y得到N×1的内积列向量分母是各训练样本模长乘测试样本模长加上eps防止除以0。余弦相似度越大越相近习惯上转成1减cosSim当作距离使用。三种距离里曼哈顿的识别结果往往和欧氏非常接近但运行时间略慢因为abs运算比平方慢。实测经验是训练样本充足、光照归一化做得好的前提下欧氏距离已经够了。如果识别率被光照明显压制优先做adapthisteq而不是换距离度量。把三种距离的对比放进报告的实验结果表答辩老师会觉得你做的是完整系统而不是单一脚本。4.3 训练集与测试集划分留一法和随机划分的利弊取舍划分策略决定了你报出去的识别率有多少可信度。最不可取的做法是把训练集拿去当测试集ORL上闭着眼睛都是100%老师现场拍一张就穿帮。课设一般用两种划分固定比例随机划分或者留一法。留一法的逻辑是每人10张里轮流取1张做测试、剩余9张训练循环10次最后平均。样本利用率最高评估偏差小代价是训练时间约为固定划分的10倍。ORL规模下训练PCA很快这个代价完全可接受。% 留一法评估框架结构清晰优先函数细节省略 function acc leaveOneOut(dataDir, k) numClasses 40; numPerClass 10; hit 0; total 0; for i 1:numClasses for testIdx 1:numPerClass trainIdx setdiff(1:numPerClass, testIdx); % 组装训练矩阵Xtr与标签训练模型 model trainFaceModelIdx(dataDir, k, i, trainIdx); % 取当前测试图识别 pred testFaceModelIdx(model, dataDir, i, testIdx); hit hit (pred i); total total 1; end end acc hit / total; endtrainFaceModelIdx接受一个具体的人和一批训练索引避免每次重新读全库。留一法跑完ORL需要400次训练每次SVD在10304×360的规模上约零点几秒整体一两分钟能跑完课设完全扛得住。随机划分比如每人7张训练、3张测试速度快代码简单但小样本下每次划分结果波动可能达到两三个百分点。建议报告里以留一法作为最终识别率随机划分用来展示划分不同结果有波动这个现象。两种都写进实验章节也是加分点。5. Matlab人脸识别课设避坑指南五个翻车现场与对应修法代码跑通只是开始答辩前你一定会撞上几个坑。这一章写五个翻车现场每条都按现象、原因、解决给修法对照自己的代码逐条查能省下大半天调试时间。5.1 翻车现场一图像尺寸不一致导致矩阵拼接报错现象运行trainFaceModel时Matlab报Error using vertcat或dimensions must agree断点停在对X(:, col)赋值的行。原因ORL库本身是整齐的112×92但如果你把自拍图或网络图混进来imresize只写在某个分支里或者整库循环里只有部分样本被resize维度不一致在拼接瞬间就炸了。解决在赋值前强制统一尺寸并把类型检查写进读取函数。最常用的写法是3.1节里的imresize(img, [112 92])同时加一句断言img imread(fullfile(dataDir, sprintf(s%d/%d.pgm, i, j))); assert(ndims(img) 2, 输入不是灰度图); % 防止彩色图混入 img imresize(img, [112 92]);这样不管原始图是彩色、还是尺寸不齐都会在训练前被纠正并明确报错。如果你用视频帧做训练集记得先抽帧再走同一套预处理函数不要边读边处理。5.2 翻车现场二大图训练时内存溢出协方差矩阵算不动现象换成自拍的高清图库后trainFaceModel直接内存不足或者SVD算到一半Matlab卡死。原因如果走cov(X)加eig这条路中间会产生d×d矩阵。d是展平后的像素数1920×1080灰度图展平约207万维207万乘207万乘8字节约3.4TB任何普通电脑都扛不住。解决不要对d×d矩阵做特征分解改用转置技巧或直接svd(Xc, econ)。svd的econ模式只生成d乘min(d, N)的结果内存占用大幅下降。更省的做法是先算小矩阵Xc * Xc维度是N×N几个MB再做特征分解把特征向量映射回原空间% 小样本PCA替代写法N远小于d时用 G Xc * Xc; % N x NN是样本数 [V, D] eig(G); % 对NxN矩阵求特征分解 [~, order] sort(diag(D), descend); V V(:, order); % 特征向量U Xc * V * diag(1 ./ sqrt(diag(D) eps))注意特征值太小的列会放大噪声 U Xc * V * diag(1 ./ sqrt(diag(D) eps)); W U(:, 1:k);这段代码在N远小于d时非常重要课设用ORL的话svd的econ模式就够了但报告里能把两种做法的内存差异写清楚属于原理加分项。实际使用建议只保留特征值大于某个小阈值的列比如1e-6否则数值噪声会被放大。5.3 翻车现场三摄像头采集的彩色帧直接喂给分类器现象实时识别脚本一运行就报错常见的是Subscript dimensions mismatch或者矩阵维度对不上识别率奇低。原因webcam的snapshot返回的是height×width×3的RGB uint8矩阵而训练时的X是H×W的灰度向量。三维矩阵直接展平后维度是灰度图的3倍和投影矩阵W的维度完全对不上矩阵乘法第一步就垮了。解决按固定顺序处理先裁剪、再灰度化、再resize最后转double。顺序反了会导致rgb2gray作用在错误维度上或者resize把颜色通道搅乱。face imcrop(frame, bbox(bi, :)); face rgb2gray(face); % 先转灰度 face imresize(face, [112 92]); % 再resize face double(face(:)); % 最后展平如果摄像头拍出来的人脸偏暗可以在imresize后、向量化前加face adapthisteq(face);。训练端也要做同样的处理两边一致才不会出现特征空间偏移。5.4 翻车现场四同一个人两次识别结果不一样光照和对齐问题现象同一个人站在摄像头前稍微转个头或者换一盏灯识别结果就在两个ID之间来回跳甚至认错人。原因课设阶段的系统通常没有做严格的关键点对齐人脸在框里的上下位置和旋转角度一变特征向量就跟着变PCA对全局亮度变化也敏感光照一变投影坐标就跑偏。解决分两步。第一步做光照归一化推荐adapthisteq训练样本和测试样本都要加两边一致性是关键只给测试端加反而会拉低识别率。第二步做简单的对齐用检测器拿到的人脸框尽量统一到同一位置和比例比如以两眼间距为基准把脸缩放到固定尺寸再裁剪比想象中能显著提升稳定性。如果时间不够最低限度是框出的人脸区域要包含完整面部不要带额头外过多的背景。5.5 翻车现场五课程设计报告里识别率100%反而被质疑现象报告写“ORL库识别率100%”答辩老师一问数据划分答不上来或者老师当场拿一张库外照片测试系统给出一个错误ID且没有拒绝能力。原因识别率100%往往意味着训练测试同源或者只挑了最容易的样本做测试。另一个隐患是最近邻分类器没有拒识机制无论来什么脸都会硬归到40个人之一库外脸出结果只能是错。解决报告里识别率必须标注划分方式“留一法平均识别率XX%”比“识别率98%”可信得多。同时给系统加一个距离阈值当最近邻距离超过阈值时输出未注册人员[minDist, idx] min(d); if minDist threshold label -1; % -1表示未注册 else label model.trainLabels(idx); end阈值怎么定用库内样本距离分布来标定统计所有正确匹配的最小距离取95%分位数作为阈值。这一步写进报告系统的完整性立刻上一个台阶答辩时主动演示拒识比被动被老师考倒强得多。6. 用App Designer封装识别演示答辩现场不翻车的加分做法答辩最怕的不是算法讲不清而是现场演示翻车。把系统封装成带按钮的图形界面一是操作可重复二是看起来像系统实现而不是脚本运行。App Designer在Matlab r2016a之后都有布局和回调比老版GUIDE友好得多。一个最小可用的界面只需要三个组件一个坐标轴显示视频帧一个“开始识别”按钮一个文本框显示结果。回调代码的核心是把摄像头采集、检测、识别串起来% App Designer回调骨架实际开发时写在对应回调函数中 function StartButtonPushed(app, event) model load(faceModel.mat); % 训练好的模型存成mat detector vision.CascadeObjectDetector(FrontalFaceCART); cam webcam(1); for i 1:200 frame snapshot(cam); bbox detector(frame); if ~isempty(bbox) [~, bi] max(bbox(:,3) .* bbox(:,4)); face imresize(rgb2gray(imcrop(frame, bbox(bi,:))), [112 92]); [label, minDist] recognizeFaceWithDist(model, face); if minDist model.threshold text 未注册人员; else text sprintf(识别为第 %d 号成员, label); end app.ResultLabel.Text text; frame insertObjectAnnotation(frame, rectangle, ... bbox(bi,:), text, Color, yellow); end imshow(app.UIAxes, frame); drawnow; end endrecognizeFaceWithDist是第5章加了阈值版本的识别函数返回label和最近邻距离两个值。启动前把模型、模型阈值、摄像头对象都在startupFcn里初始化好不要在每次按钮回调里重复加载否则按钮响应会有肉眼可感的延迟。封装完界面之后答辩演示的顺序建议固定成三步第一步演示训练集内识别和识别率统计这步必然成功第二步演示摄像头实时识别顺便说明光照归一化处理第三步主动演示拒识效果拿一张不在库里的照片系统显示未注册人员。我的教训是当年只演示了前两步老师随手递过来一张照片系统硬认成库里的某个人场面一度很尴尬。后来把阈值拒识加进去同样的场景反而成了亮点。识别系统做到能演示、能解释、能应对反例才算真正闭环希望帮到你。本文还有配套的精品资源点击获取
返回列表