我们要用电脑识别照片或视频中的人脸,并知道是谁的脸。就像手机相册能自动识别照片里的人是谁一样。
🔍 人脸检测(找脸)
目标:在图片中找到人脸的位置
怎么做:
-
用MATLAB的"人脸扫描仪"(
vision.CascadeObjectDetector
) -
这个扫描仪的工作原理:
-
像在图片上移动一个"放大镜"🔍
-
检查每个区域是否符合人脸特征(眼睛、鼻子、嘴巴的排列)
-
发现人脸就用方框标出来
-
举个栗子🌰:
你给电脑一张班级合照,它会在每个人脸上画个红框。
👤 人脸识别(认人)
目标:认出这是谁的脸
步骤:
-
准备"人脸相册":
收集每个人的多张照片(不同角度、表情) -
提取"人脸指纹":
-
电脑不是记整张脸,而是记关键特征
-
两种常用方法:
-
HOG特征:记录脸部轮廓线条的方向(像画简笔画✏️)
-
LBP特征:记录皮肤纹理的斑点图案(像记雀斑位置)
-
-
-
训练"人脸识别专家":
-
用SVM(支持向量机)算法
-
把"张三"的脸部特征和名字关联起来
-
就像教小孩:"这种眼睛+鼻子组合是张三"
-
-
识别新人脸:
-
当看到新照片时:
-
先找到人脸位置(检测)
-
提取这个人的"脸部指纹"
-
问SVM专家:"这个指纹最像相册里的谁?"
-
-
💡 技术亮点
-
Viola-Jones算法(找脸神器):
-
超快扫描,能处理模糊/侧脸
-
原理:用多个简单特征快速排除非人脸区域
-
-
HOG+LBP(黄金组合):
-
HOG:擅长捕捉轮廓(适合辨认脸型)
-
LBP:擅长记录纹理(适合辨认皮肤细节)
-
合起来=看脸型+看肤质,双保险
-
-
SVM分类器(最强大脑):
-
在特征空间画"分界线"
-
例如:张三的脸部特征在A区,李四的在B区
-
新人脸落在哪个区就判断是谁
-
🚀 实际应用场景
-
手机解锁:检测到人脸→提取特征→匹配机主
-
门禁系统:识别员工自动开门
-
相册整理:自动把奶奶的照片归类
-
会场签到:扫一眼就知道谁到场了
⚠️ 注意事项
-
光线问题:暗光下可能认不出(就像你看不清暗处的人脸)
-
双胞胎难题:长得太像可能分不清(需要更多细节特征)
-
戴口罩:遮住大半脸会困难(就像你认不出戴口罩的朋友)
🔧 如何提高准确率
-
更多照片:每人提供20张不同角度的照片
-
光线均衡:避免阴阳脸、背光脸
-
人脸对齐:把眼睛鼻子摆到标准位置再识别
-
更新相册:定期增加新照片(比如换了发型)
以下是完整代码演示
人脸检测部分(Viola-Jones算法)
% 创建人脸检测器
detector = vision.CascadeObjectDetector();
% 读取测试图像
img = imread('test_face.jpg');
% 检测人脸
bboxes = step(detector, img);
% 显示结果
detectedImg = insertObjectAnnotation(img, 'rectangle', bboxes, 'Face');
imshow(detectedImg);
title('Detected Faces');
人脸识别部分(HOG特征 + SVM分类器)
%% 数据集准备
% 假设数据集结构为:dataset/class/personXX_imYY.png
datasetPath = 'att_faces'; % ORL数据集路径
imds = imageDatastore(datasetPath, ...
'IncludeSubfolders', true, ...
'LabelSource', 'foldernames');
% 划分训练集和测试集(80%训练,20%测试)
[trainSet, testSet] = splitEachLabel(imds, 0.8, 'randomized');
%% 特征提取 - HOG
cellSize = [4 4]; % 特征单元尺寸
hogFeatureSize = 5184; % 根据图像大小计算得到
% 提取训练集HOG特征
trainFeatures = zeros(numel(trainSet.Files), hogFeatureSize, 'single');
for i = 1:numel(trainSet.Files)
img = readimage(trainSet, i);
img = im2gray(img);
trainFeatures(i, :) = extractHOGFeatures(img, 'CellSize', cellSize);
end
% 获取训练标签
trainLabels = trainSet.Labels;
%% 训练多类SVM分类器
classifier = fitcecoc(trainFeatures, trainLabels);
%% 测试集评估
testFeatures = zeros(numel(testSet.Files), hogFeatureSize, 'single');
for i = 1:numel(testSet.Files)
img = readimage(testSet, i);
img = im2gray(img);
testFeatures(i, :) = extractHOGFeatures(img, 'CellSize', cellSize);
end
testLabels = testSet.Labels;
predictedLabels = predict(classifier, testFeatures);
% 计算准确率
accuracy = sum(predictedLabels == testLabels) / numel(testLabels);
fprintf('识别准确率: %.2f%%\n', accuracy * 100);
% 显示混淆矩阵
confMat = confusionmat(testLabels, predictedLabels);
figure;
confusionchart(confMat);
title('混淆矩阵');
完整人脸检测+识别流程
% 1. 加载预训练模型
load('faceRecognitionModel.mat'); % 包含classifier和hog参数
% 2. 读取测试图像
testImg = imread('group_photo.jpg');
% 3. 人脸检测
detector = vision.CascadeObjectDetector();
bboxes = detector(testImg);
% 4. 对每个检测到的人脸进行识别
recognizedImg = testImg;
for i = 1:size(bboxes, 1)
% 裁剪人脸区域
face = imcrop(testImg, bboxes(i, :));
% 预处理
faceGray = im2gray(face);
faceResized = imresize(faceGray, [112 92]); % ORL数据集尺寸
% 提取HOG特征
features = extractHOGFeatures(faceResized, 'CellSize', cellSize);
% 预测标签
label = predict(classifier, features);
% 标记结果
recognizedImg = insertObjectAnnotation(recognizedImg, ...
'rectangle', bboxes(i, :), char(label), ...
'FontSize', 16, 'TextBoxOpacity', 0.8);
end
% 显示最终结果
figure;
imshow(recognizedImg);
title('人脸识别结果');
技能点实现说明
-
Viola-Jones人脸检测
-
使用
vision.CascadeObjectDetector
实现 -
基于Haar级联分类器,适合实时检测
-
-
HOG特征提取
-
extractHOGFeatures
函数提取梯度方向直方图 -
参数
CellSize
控制特征粒度(常用[4×4]或[8×8])
-
-
SVM分类器
-
使用
fitcecoc
训练多类SVM(支持向量机) -
ECOC(Error-Correcting Output Codes)处理多分类问题
-
-
模型评估
-
混淆矩阵可视化分类性能
-
计算测试集准确率
-
优化方向
-
添加人脸对齐预处理
-
尝试LBP特征替代HOG:
extractLBPFeatures
-
使用深度学习模型(AlexNet/ResNet迁移学习)
% 迁移学习示例
net = alexnet;
layers = net.Layers(1:end-3);
layers(end+1) = fullyConnectedLayer(numClasses);
layers(end+1) = softmaxLayer();
layers(end+1) = classificationLayer();
注意事项
-
训练前统一图像尺寸(建议与ORL数据集一致)
-
光照归一化可提升识别率
-
人脸检测阶段可添加
MergeThreshold
参数调整灵敏度