1案例背景
1.1人脸识别概述
人脸识别作为一个复杂的模式识别问题,近年来受到了广泛的关注,识别领域的各种方法在这个问题上各显所长,而且发展出了许多新方法,大大丰富和拓宽了模式识别的方向。人脸识别、检测,跟踪、特征定位等技术近年来一直是研究的热点。人脸识别是人脸应用研究中重要的第一步,目的是从图像中分割出不包括背景的人脸区域。由于人脸形状的不规则性以及光线和背景条件多样性,现有的人脸研究算法都是在试图解决某些特定实验环境下的一些具体问题,对人脸位置和状态都有一定的要求。而在实际应用中,大量图像和视频源中人脸的位置、朝向和旋转角度都不是固定的,这就大大增加了人脸识别的难度。
在人脸识别领域的众多研究方向中,人脸朝向分析一直是一个少有人涉及的领域。在以往的研究成果中,一些研究者谈及了人脸朝向问题,但其中绝大多数都是希望在人脸识别过程中去除人脸水平旋转对识别过程的不良影响。但是,实际问题要复杂得多,人脸朝向是一个无法回避的问题。因此,对于人脸朝向的判断和识别,将会是一件非常有意义的工作。
1.2问题描述
现采集到一组人脸朝向不同角度时的图像,图像来自不同的10个人,每人5幅图像,人脸的朝向分别为:左方、左前方、前方、右前方和右方,如图27-1所示。试创建一个LVQ神经网络,对任意给出的人脸图像进行朝向预测和识别。
2模型建立
2.1 设计思路
2.2设计步骤
1)人脸特征向量提取
如设计思路中所述,当人脸朝向不同时,眼睛在图像中的位置会有明显的差别。因此,只需要将描述人眼位置信息的特征向量提取出来即可。方法是将整幅图像划分成6行8列,人眼的位置信息可以用第2行的8个子矩阵来描述(注意:针对不同大小的图像,划分的网格需稍作修改),边缘检测后8个子矩阵中的值为“1”的像素点个数与人脸朝向有直接关系,只要分别统计出第2行的8个子矩阵中的值为“1”的像素点个数即可。
2)训练集/测试集产生
为了保证训练集数据的随机性,随机选取图像库中的30幅人脸图像提取出的特征向量作为训练集数据,剩余的20幅人脸图像提取出来的特征向量作为测试集数据。
3)LVQ 网络创建
LVQ神经网络的优点是不需要将输人向量进行归一化、正交化,利用MATLAB自带的神经网络工具箱函数newlvq()可以构建一个LVQ神经网络,关于该函数的用法及说明在第26章中已作详细说明,此处不再赘述。
4)LVO网络训练
网络创建完毕后,便可以将训练集输入向量送入到网络中,利用LVQ1或LVQ2算法对网络的权值进行调整,直到满足训练要求迭代终止。
5.人脸识别测试
网络训练收敛后,便可以对测试集数据进行预测,即对测试集的图像进行人脸朝向识别。对于任意给出的图像,只需要将其特征向量提取出来,便可对其进行识别。
3 MATLAB实现
利用MATLAB神经网络工具箱提供的函数可以方便地在 MATLAB环境下实现上述设计步骤,代码如下:
%% LVQ神经网络的预测——人脸识别%% 清除环境变量
clear all
clc%% 人脸特征向量提取
% 人数
M = 10;
% 人脸朝向类别数
N = 5;
% 特征向量提取
pixel_value = feature_extraction(M,N);%% 训练集/测试集产生
% 产生图像序号的随机序列
rand_label = randperm(M*N);
% 人脸朝向标号
direction_label = repmat(1:N,1,M);
% 训练集
train_label = rand_label(1:30);
P_train = pixel_value(train_label,:)';
Tc_train = direction_label(train_label);
T_train = ind2vec(Tc_train);
% 测试集
test_label = rand_label(31:end);
P_test = pixel_value(test_label,:)';
Tc_test = direction_label(test_label);%% 创建LVQ网络
for i = 1:5rate{i} = length(find(Tc_train == i))/30;
end
net = newlvq(minmax(P_train),20,cell2mat(rate),0.01,'learnlv1');
% 设置训练参数
net.trainParam.epochs = 100;
net.trainParam.goal = 0.001;
net.trainParam.lr = 0.1;%% 训练网络
net = train(net,P_train,T_train);%% 人脸识别测试
T_sim = sim(net,P_test);
Tc_sim = vec2ind(T_sim);
result = [Tc_test;Tc_sim]%% 结果显示
% 训练集人脸标号
strain_label = sort(train_label);
htrain_label = ceil(strain_label/N);
% 训练集人脸朝向标号
dtrain_label = strain_label - floor(strain_label/N)*N;
dtrain_label(dtrain_label == 0) = N;
% 显示训练集图像序号
disp('训练集图像为:' );
for i = 1:30 str_train = [num2str(htrain_label(i)) '_'...num2str(dtrain_label(i)) ' '];fprintf('%s',str_train)if mod(i,5) == 0fprintf('\n');end
end
% 测试集人脸标号
stest_label = sort(test_label);
htest_label = ceil(stest_label/N);
% 测试集人脸朝向标号
dtest_label = stest_label - floor(stest_label/N)*N;
dtest_label(dtest_label == 0) = N;
% 显示测试集图像序号
disp('测试集图像为:');
for i = 1:20 str_test = [num2str(htest_label(i)) '_'...num2str(dtest_label(i)) ' '];fprintf('%s',str_test)if mod(i,5) == 0fprintf('\n');end
end
% 显示识别出错图像
error = Tc_sim - Tc_test;
location = {'左方' '左前方' '前方' '右前方' '右方'};
for i = 1:length(error)if error(i) ~= 0% 识别出错图像人脸标号herror_label = ceil(test_label(i)/N);% 识别出错图像人脸朝向标号derror_label = test_label(i) - floor(test_label(i)/N)*N;derror_label(derror_label == 0) = N;% 图像原始朝向standard = location{Tc_test(i)};% 图像识别结果朝向identify = location{Tc_sim(i)};str_err = strcat(['图像' num2str(herror_label) '_'...num2str(derror_label) '识别出错.']);disp([str_err '(正确结果:朝向' standard...';识别结果:朝向' identify ')']);end
end
% 显示识别率
disp(['识别率为:' num2str(length(find(error == 0))/20*100) '%']);
上述为主函数代码,完整代码和数据集下载方式:
【免费】基于LVQ神经网络的人脸朝向识别matlab代码
运行结果:
result =
2 5 1 3 4 4 5 1 1 3 2 4 3 4 4 3 4 5 5 2
2 5 1 3 4 4 5 1 1 3 2 4 3 4 4 3 4 5 5 2
训练集图像为:
1_3 1_5 2_1 2_2 2_3
3_1 3_4 4_1 4_2 5_1
5_2 5_5 6_3 6_4 6_5
7_1 7_2 7_3 7_4 7_5
8_2 8_3 8_5 9_1 9_2
9_5 10_1 10_2 10_3 10_4
测试集图像为:
1_1 1_2 1_4 2_4 2_5
3_2 3_3 3_5 4_3 4_4
4_5 5_3 5_4 6_1 6_2
8_1 8_4 9_3 9_4 10_5
识别率为:100%
从以上结果可以看出,当训练目标 net, trainPararm. goal 设置为0.0001时,识别准确率可以达到100%。因此,利用LVQ神经网络对人脸作识别是可行且有效的。要注意的一点是,当训练集较少时,比如说只取1~2个人脸的图像特征向量参与训练,识别率会相对较低些。因此,在防止出现过拟合的同时,应尽量增加训练集的样本数目。
4案例扩展
由于无需对数据进行预处理、可以处理复杂模型且对噪声干扰有一定的抑制,LVQ神经网络的应用也越来越广泛。近年来,许多专家学者将LVQ神经网络与其他方法相结合,成功地解决了很多现实问题。例如,由于传统LVQ神经网络存在神经元未被充分利用以及算法对初值敏感的问题,利用遗传算法优化网络的初始值可以迅速得到最佳的神经网络初始权值向量,从而使得分析速度和精度都有较大的提高。