人脸识别之特征脸方法(Eigenface)

人脸识别之特征脸方法(Eigenface)

zouxy09@qq.com

http://blog.csdn.net/zouxy09

 

      因为需要,花了一点时间写了下经典的基于特征脸(EigenFace)的人脸识别方法的Matlab代码。这里仅把该代码分享出来。其实,在较新版本的OpenCV中已经提供了FaceRecognizer这一个类,里面不仅包含了特征脸EigenFace,还有FisherFace和LBPHFace这三种人脸识别方法,有兴趣的可以参考OpenCV的API手册,里面都有很详细的使用例程了。

 

一、特征脸

      特征脸EigenFace从思想上其实挺简单。就相当于把人脸从像素空间变换到另一个空间,在另一个空间中做相似性的计算。这么说,其实图像识别的基本思想都是一样的,首先选择一个合适的子空间,将所有的图像变换到这个子空间上,然后再在这个子空间上衡量相似性或者进行分类学习。那为什么要变换到另一个空间呢?当然是为了更好的做识别或者分类了。那为什么变换到一个空间就好识别或者分类了呢?因为变换到另一个空间,同一个类别的图像会聚到一起,不同类别的图像会距离比较远,或者在原像素空间中不同类别的图像在分布上很难用个简单的线或者面把他们切分开,然后如果变换到另一个空间,就可以很好的把他们分开了。有时候,线性(分类器)就可以很容易的把他们分开了。那既然人类看起来同类的图像本来就是相似的,不同类的图像就不太相似,那为什么在原始的像素空间他们同类不会很近,不同类不会很远,或者他们为什么不好分开呢?因为图像各种因素的影响,包括光照、视角、背景和形状等等不同,会造成同一个目标的图像都存在很大的视觉信息上的不同。如下图所示。

       世界上没有存在任何两片完全相同的叶子,虽然他们都是叶子。万千世界,同一类事物都存在共性,也存在个性,这就是这个世界多彩的原因。那怎么办呢?很自然,只要在我们想要的粒度上把同一类目标的共性找出来就好了,而且这个共性最好和我们要区分的类是不一样的。什么叫我们想要的粒度?我理解和我们的任务相关的。例如我们要区分人和车,那人的共性就是有脸、有手、有脚等等。但如果我们要区分亚洲人和非洲人,那么亚洲人的共性就是黄色皮肤等等。可以试着想象,上帝把世界万物组织成一个树状结构,树的根就是万物之源,下一层可以分成生物和非生物,再下一层将生物分为……(囧,想象不到),直到最底层,万物,你我,为树的一片普通得再普通的叶子。树越往下,粒度越小,分类越细(哈哈,自己乱扯的)。停!废话多了点,跑题了,回到刚才的问题,重头戏来了,要变换到什么空间,才具备上述这种良好类内相似、类间区分的效果?到这,我就只能say sorry了。计算机视觉领域发展了几十年,就为了这一个问题倾注了无数研究者的智慧与心血。当然了,也诞生和孕育了很多经典和有效的解答。(个人理解,上述说的实际上就是特征提取)。从一开始的颜色特征(颜色直方图)、纹理特征(Harr、LBP、HOG、SIFT等)、形状特征等到视觉表达Bag of Words,再到特征学习Deep Learning,技术的发展总能带给人希望,曙光也越来越清晰,但路还很远,是不?      

       扯太多了,严重离题了。上面说到,特征脸EigenFace的思想是把人脸从像素空间变换到另一个空间,在另一个空间中做相似性的计算。EigenFace选择的空间变换方法是PCA,也就是大名鼎鼎的主成分分析。它广泛的被用于预处理中以消去样本特征维度之间的相关性。当然了,这里不是说这个。EigenFace方法利用PCA得到人脸分布的主要成分,具体实现是对训练集中所有人脸图像的协方差矩阵进行本征值分解,得对对应的本征向量,这些本征向量(特征向量)就是“特征脸”。每个特征向量或者特征脸相当于捕捉或者描述人脸之间的一种变化或者特性。这就意味着每个人脸都可以表示为这些特征脸的线性组合。实际上,空间变换就等同于“搞基”,原始像素空间的基就是单位“基”,经过PCA后空间就是以每一个特征脸或者特征向量为基,在这个空间(或者坐标轴)下,每个人脸就是一个点,这个点的坐标就是这个人脸在每个特征基下的投影坐标。哦噢,说得有点绕。

      下面就直接给出基于特征脸的人脸识别实现过程:

1)将训练集的每一个人脸图像都拉长一列,将他们组合在一起形成一个大矩阵A。假设每个人脸图像是MxM大小,那么拉成一列后每个人脸样本的维度就是d=MxM大小了。假设有N个人脸图像,那么样本矩阵A的维度就是dxN了。

2)将所有的N个人脸在对应维度上加起来,然后求个平均,就得到了一个“平均脸”。你把这个脸显示出来的话,还挺帅的哦。

3)将N个图像都减去那个平均脸图像,得到差值图像的数据矩阵Φ。

4)计算协方差矩阵C=ΦΦT。再对其进行特征值分解。就可以得到想要的特征向量(特征脸)了。

5)将训练集图像和测试集的图像都投影到这些特征向量上了,再对测试集的每个图像找到训练集中的最近邻或者k近邻啥的,进行分类即可。

      算法说明白了都是不明白的,所以还是得去看具体实现。因此,可以对照下面的代码来弄清楚这些步骤。

      另外,对于步骤4),涉及到求特征值分解。如果人脸的特征维度d很大,例如256x256的人脸图像,d就是65536了。那么协方差矩阵C的维度就是dxd=65536x65536。对这个大矩阵求解特征值分解是很费力的。那怎么办呢?如果人脸的样本不多,也就是N不大的话,我们可以通过求解C’=ΦTΦ矩阵来获得同样的特征向量。可以看到这个C’=ΦTΦ只有NxN的大小哦。如果N远远小于d的话,那么这个力气就省得很值了。那为什么求解C’=ΦTΦ矩阵的特征向量可以获得C=ΦΦT的特征向量?万众瞩目时刻,数学以完美舞姿登上舞台。证明如下:

      其中,ei是C’=ΦTΦ的第i个特征向量,vi是C=ΦΦT的第i个特征向量,由证明可以看到,vi=Φei。所以通过求解C’=ΦTΦ的特征值分解得到ei,再左乘Φ就得到C=ΦΦT的特征向量vi了。也就是我们想要的特征脸。

 

二、Matlab实现

      下面的代码主要是在著名的人脸识别数据库YaleB中进行实现。用的是裁切后的人脸数据库,可以点击CroppedYale下载。共有38个人的人脸,人脸是在不同的光照下采集的,每个人脸图像是32x32个像素。实验在每一个的人脸图像中随机取5个作为训练图像,剩下的作为测试图像。当然了,实际过程中这个过程需要重复多次,然后得到多次准确率的均值和方差才有参考意义,但下面的demo就不做这个处理了。计算相似性用的是欧氏距离,但编程实现的时候为了加速,用的是简化版,至于如何简化的,考验你的时候到了。

% Face recognition using eigenfacesclose all, clear, clc;%% 20 random splits
num_trainImg = 5;
showEigenfaces = true;%% load data
disp('loading data...');
dataDir = './CroppedYale';
datafile = 'Yale.mat';
if ~exist(datafile, 'file')readYaleDataset(dataDir, datafile);
end
load(datafile);%% Five images per class are randomly chosen as the training
%% dataset and remaining images are used as the test dataset
disp('get training and testing data...');
num_class = size(unique(labels), 2);
trainIdx = [];
testIdx = [];
for i=1:num_classlabel = find(labels == i);indice = randperm(numel(label));trainIdx = [trainIdx label(indice(1:num_trainImg))];testIdx = [testIdx label(indice(num_trainImg+1:end))];
end%% get train and test data
train_x = double(data(:, trainIdx));
train_y = labels(trainIdx);
test_x = double(data(:, testIdx));
test_y = labels(testIdx);%% computing eigenfaces using PCA
disp('computing eigenfaces...');
tic;
[num_dim, num_imgs] = size(train_x);   %% A: #dim x #images
avg_face = mean(train_x, 2); 			 %% computing the average face
X = bsxfun(@minus, train_x, avg_face); %% computing the difference images%% PCA
if num_dim <= num_imgs C = X * X';[V, D] = eig(C);
elseC = X' * X; [U, D] = eig(C);V = X * U;
end
eigenfaces = V;
eigenfaces = eigenfaces ./ (ones(size(eigenfaces,1),1) * sqrt(sum(eigenfaces.*eigenfaces)));
toc;%% visualize the average face
P = sqrt(numel(avg_face));
Q = numel(avg_face) / P;
imagesc(reshape(avg_face, P, Q)); title('Mean face');
colormap('gray');%% visualize some eigenfaces
figure;
num_eigenfaces_show = 9;
for i = 1:num_eigenfaces_showsubplot(3, 3, i)imagesc(reshape(eigenfaces(:, end-i+1), P, Q));title(['Eigenfaces ' num2str(i)]);
end
colormap('gray');%% transform all training images to eigen space (each column for each image)
disp('transform data to eigen space...');
X = bsxfun(@minus, train_x, avg_face);
T = eigenfaces' * X;%% transform the test image to eigen space
X_t = bsxfun(@minus, test_x, avg_face);
T_t = eigenfaces' * X_t;%% find the best match using Euclidean distance
disp('find the best match...');
AB = -2 * T_t' * T;       % N x M
BB = sum(T .* T);         % 1 x M
distance = bsxfun(@plus, AB, BB);        % N x M
[score, index] = min(distance, [], 2);   % N x 1%% compute accuracy
matchCount = 0;
for i=1:numel(index)predict = train_y(index(i));if predict == test_y(i)matchCount = matchCount + 1;end
endfprintf('**************************************\n');
fprintf('accuracy: %0.3f%% \n', 100 * matchCount / numel(index));
fprintf('**************************************\n');

      下面是将CroppedYale的图像读入matlab的代码。

function readYaleDataset(dataDir, saveName)dirs = dir(dataDir);data = [];labels = [];for i = 3:numel(dirs)imgDir = dirs(i).name;imgDir = fullfile(dataDir, imgDir);imgList = dir(fullfile(imgDir, '*.pgm'));for j = 1:numel(imgList)imgName = imgList(j).name;if strcmp('Ambient.pgm',  imgName(end-10:end))continue;endim = imread(fullfile(imgDir, imgName));if size(im, 3) ==3im = rgb2gray(im);endim = imresize(im, [32 32]);im = reshape(im, 32*32, 1);data = [data im];endlabels = [labels ones(1, numel(imgList)-1) * (i-2)];endsave(saveName, 'data', 'labels');
end

 

三、实验结果

      首先来个帅帅的平均脸:

      然后来9个帅帅的特征脸:

      在本实验中,实验结果是30.126%左右。如果加上了某些预处理,这个结果就可以跑到62%左右。只是这个预处理我有点解析不通,所以就没放在demo上了。

      本文如果有什么不对的地方,还望大家指正。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/12502.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

face_recognition 人脸识别

前言 之前实践了下face在线人脸识别版本&#xff0c;这回做一下离线版本。github 上面有关于face_recognition的相关资料&#xff0c;本人只是做个搬运工&#xff0c;对其中的一些内容进行搬运&#xff0c;对其中一些例子进行实现。 官方描述&#xff1a; face_recognition …

chatgpt赋能python:Python人脸追踪:技术介绍与应用

Python人脸追踪&#xff1a;技术介绍与应用 Python作为一门极为流行的编程语言&#xff0c;其在人工智能领域的应用也不断得到拓展和应用&#xff0c;其中Python人脸追踪技术已经成为广泛应用的一个领域。本篇文章将介绍Python人脸追踪技术的原理和应用&#xff0c;以便读者更…

face_recognition结合opencv进行多人脸识别

目录 step1&#xff1a;准备好opencv&#xff0c;numpy和face_recognition三个库 step2&#xff1a;准备好人脸图像 step3&#xff1a;利用opencv读取三张图片 step4&#xff1a;将图片转为特征向量&#xff0c;并将向量和名字添加到列表中&#xff0c;一一对应 step5&#…

chatgpt赋能Python-python人脸识别步骤

简介 Python是一种优秀的编程语言&#xff0c;它广泛应用于人工智能、数据科学、Web应用程序开发等领域。其中&#xff0c;人脸识别是Python应用程序中的重要一环。 本文将介绍Python人脸识别的具体步骤&#xff0c;希望对初学者有所帮助。 Python人脸识别步骤 安装必要的库…

chatgpt赋能Python-python3人脸识别

人脸识别的python3应用&#xff1a;一步步实现高精度的面部识别 Python3作为一种高效的编程语言&#xff0c;具有广泛的应用场景。近年来&#xff0c;人脸识别技术在安防、金融、医疗等领域中逐渐普及&#xff0c;运用Python3进行人脸识别具有巨大的潜力。本文将介绍如何使用P…

万字科普ChatGPT-4为何会颠覆人类社会

来源&#xff1a;图灵人工智能 视频来源&#xff1a;超智能体 视频是关于GPT的底层原理和未来影响。将抛开技术细节&#xff0c;少用专业名词&#xff0c;在整体功能上讲解 ChatGPT 的「工作原理」「制造过程」「涌现的能力」「未来的影响」以及「如何应对」&#xff1a; 1、Ch…

断案三字诀

2019独角兽企业重金招聘Python工程师标准>>> 孟一刀&#xff1a;断案三字诀 2012-11-20 孟黎明&#xff0c;1973年6月生&#xff0c;1992年8月起至今在法院工作&#xff0c;曾任安吉法院调解中心主任、民一庭庭长&#xff0c;现任院党组成员、纪检组长。2010年2月…

科研如断案

最近我又把《神探狄仁杰》第一部看完了&#xff0c;觉得确实很不错。狄仁杰身为一朝宰相&#xff0c;拥有“一人之下&#xff0c;万人之上”的权力。他始终以百姓的安居乐业和天下的兴亡为己任。在电视剧里面&#xff0c;他与坏人斗智斗勇&#xff0c;时时险象环生&#xff0c;…

c语言经典断案程序、杨辉三角程序、跳水概率程序

/* 5位运动员参加了10米台跳水比赛&#xff0c;有人让他们预测比赛结果 A选手说&#xff1a;B第二&#xff0c;我第三&#xff1b; B选手说&#xff1a;我第二&#xff0c;E第四&#xff1b; C选手说&#xff1a;我第一&#xff0c;D第二&#xff1b; D选手说&#xff1a;C最后…

蓝桥杯07 java 断案

题目描述 公安人员审问甲、乙、丙、丁四个嫌疑犯&#xff0c;已确知&#xff0c;这四个人当中仅有一人是偷窃者&#xff0c;还知道这四个人的答话&#xff0c;要么完全诚实&#xff0c;要么完全说谎。在回答公安人员的问话中&#xff1a; 甲说&#xff1a;“乙没有偷&#xf…

试题 算法提高 断案

问题描述   公安人员审问甲、乙、丙、丁四个嫌疑犯&#xff0c;已确知&#xff0c;这四个人当中仅有一人是偷窃者&#xff0c;还知道这四个人的答话&#xff0c;要么完全诚实&#xff0c;要么完全说谎。在回答公安人员的问话中&#xff1a;   甲说&#xff1a;“乙没有偷&a…

论文投稿指南——中国(中文EI)期刊推荐(第6期)

&#x1f680; EI是国际知名三大检索系统之一&#xff0c;在学术界的知名度和认可度仅次于SCI&#xff01;&#x1f384;&#x1f388; 【前言】 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊。其中&#xf…

关于网页版chatgpt喂投的一些讲解

ChatGPT云炬学长 喂投的定义及使用场景&#xff1a; 这一部分主要是解决这三个问题&#xff1a;啥是喂投。我们为什么要喂投。以及什么场景下面会用到喂投。 从AI专业名词的角度来说&#xff0c;并不存在“喂投”这么一个行为&#xff0c;这是一个不太专业化的俗称&#xff…

老马闲评数字化(4)做数字化会不会被供应商拿捏住

“老马闲评数字化”系列文章正在“深圳行云创新”公众号连载&#xff0c;感兴趣的朋友请关注我们的公众号&#xff0c;不迷路…… 导语 开年过后业务特别的繁忙&#xff0c;出差也比较多&#xff0c;所以有段时间没更新了&#xff0c;对不住大家&#xff01; 上一集&#xff08…

被遗忘的技术支持岗位

文/明道云创始人任向晖 我发现一个现象。在我们行业&#xff0c;谈论营销获客、销售增长、产品思维等话题的文章很多&#xff0c;但是谈论技术支持&#xff08;Technical Support&#xff09;话题的文章几乎没有。似乎我们行业根本没有这个职能一样。在企业内部&#xff0c;技术…

《软件工程导论》期末复习总结

《软件工程导论》期末复习总结 适用教材&#xff1a;《软件工程与实践&#xff08;第3版》&#xff0c;贾铁军、李学相、王学军主编&#xff0c;清华大学出版社 提示&#xff1a;与教材内容不完全匹配&#xff0c;有所取舍。 写在前面&#xff1a; 这份复习总结是笔者根据老师…

巴比特 | 元宇宙每日必读:传苹果MR头显敲定年内上线,库克认为此时值得进场,预计第一年的销量仅为100万台左右...

摘要&#xff1a;据财联社报道&#xff0c;苹果的MR头显曾多次跳票&#xff0c;最新消息称&#xff0c;苹果CEO蒂姆•库克下场拍板——2023年推出首款MR产品。库克认为此时值得进场&#xff0c;且并不介意初始销量惨淡。据两位熟悉苹果计划的人士透露&#xff0c;苹果预计所述设…

招标 | 近期隐私计算项目招标中标32(江阴智慧港口、广西壮族自治区公安厅、湛江市政务服务数据管理局、深圳信息职业技术学院等)

开放隐私计算 1 招标 1、江阴智慧港口公共服务平台 项目名称&#xff1a;江阴智慧港口公共服务平台 公告日期&#xff1a;2023-03-11 采购单位&#xff1a;江阴港口发展有限公司 项目编号&#xff1a;QYYC23-031 项目投资&#xff1a;3200万元&#xff08;人民币&#xff09; …

2022元宇宙十大 “闪光时刻”

图片来源&#xff1a;由无界版图 AI 绘画工具生成 2022年&#xff0c;“元宇宙”一词从头火到脚&#xff0c;但就像每一次新事物诞生之初&#xff0c;变局与骗局&#xff0c;永远是一枚硬币的两个面。毫无疑问&#xff0c;围绕“元宇宙”出现了太多的骗子和骗局&#xff0c;太多…

Character.AI成为新晋AI聊天应用爆款;谷歌推出 Google Slides AI 图像生成

&#x1f989; AI新闻 &#x1f680; Character.AI&#xff1a;首周下载量超越ChatGPT&#xff0c;成为新晋AI聊天应用爆款 摘要&#xff1a;Character.AI是一款受欢迎的人工智能聊天应用&#xff0c;用户可以自由创建AI角色&#xff0c;并与它们聊天。该应用于2023年5月23日…