基于K-L变换的人脸识别

原理介绍

K-L变换是模式识别中常用的一种特征提取方法,出发点是从一组特征中计算出一组按重要性从大到小排列的新特征,它们是原有特征的线性组合,并且相互之间是不相关的,实现数据的降维。

在人脸识别中,可以用K-L变换对人脸图像的原始空间进行转换,即构造人脸图像数据集的协方差矩阵,求出协方差矩阵的特征向量,再依据特征值的大小对这些特征向量进行排序,这些特征向量表示特征的一个集合,它们共同表示一个人脸图像。在人脸识别领域,人们常称这些特征向量为特征脸。每一个体人脸图像都可以确切地表示为一组特征脸的线性组合。

本实验首先下载ORL人脸数据集,构建人脸训练数据库和测试数据库,采用K-L变换进行特征脸提取,并使用K近邻算法实现人脸识别。

算法具体步骤

1、读入人脸数据库

读入时,将每个人脸图像转化为一维的列向量。本次实验参与训练的人脸图像有N个,每个图像大小为(R×L)。则训练图像可以表示为一个(R×L)×N的矩阵X。其中,第i个人脸可以表示为x^i=X(:,i)=[x_1^i,x_2^i,...,x_{R \times L}^i],(i=1,2,...,N)

2、人脸数据K-L变换

计算所有人脸图像的平均值向量u=\frac{1}{N}\sum_{i=1}^Nx^i,选择数据的协方差矩阵作为K-L变换的产生矩阵 \sum=\frac{1}{N}\sum_{i=1}^N(x_i-u)(x_i-u)^T=\frac{1}{N}XX^T,Σ的维数为(R \times L) \times (R \times L)。如果直接对样本进行降维,需要求解Σ的正交归一的特征向量,由于矩阵维数高,直接计算困难。

现考查由样本集构成的另一个矩阵S=X^TX,它的维数是N \times N。通常N \times N << (R \times L) \times (R \times L)。矩阵S的特征方程是X^TXv_i=\lambda_iv_i,两边同时左乘X,得XX^TXv_i=\lambda_iXv_i,即\sum Xv_i = \lambda _i Xv_i,记u_i=Xv_i,则上式变成\sum u_i = \lambda _i u _ i,这就是\sum的特征方程。

因此,N \times N维矩阵X^TX(R \times L) \times (R \times L)维矩阵XX^T具有相同的特征值,特征向量的关系为u_i=Xv_i。将\lambda_i的值从大到小排序,选取前Z个特征值,使其满足,\frac{\sum_{i=1}^Z \lambda _ i}{\sum_{j=1}^N \lambda _ j} \geqslant \alpha,这里的α表示前Z个特征所能代表的样本间的差异信息占全部差异信息的比例。本次实验选取的α为97%。然后,计算u{_i^'} = Xv_i \lambda {_i ^ {}\frac{1}{2}} , i=1,2,...,Z,则组成了新的正交归一的特征空间W=\{u{_1^'}, u{_2^'},...,u{_Z'}\},也就是原始特征空间向K-L变换后特征空间的投影矩阵。

投影

将每一幅人脸与平均脸μ的差值矢量d_i投影到新的特征空间,得到第i个人脸的特征脸向量表示为:p_i=W^Td_i(i=1,2,...,N)

%======================================================
% KLFaceRecognition.m 基于KL变换的人脸识别
% Envirment:MATLAB R2017a
% DATE:2018/11/02
%======================================================

%======================================================
% 第一步:读入ORL人脸数据集
%======================================================
clear
close all;
clc

f1 = dir('ORL');
f2 = dir([f1(4).folder '\' f1(3).name]);
face = cell(1, 1); 
AllData = zeros(2, 2);
LabelList = zeros(1, 1);
num = 0;
for i = 3 : length(f2)
    fi = dir([f2(i).folder '\' f2(i).name]);
    for j = 3 : length(fi)
        num = num + 1;
        face{i - 2, j - 2} = imread([fi(j).folder '\' fi(j).name]);
        fileName = sprintf('f%d.png', j);
        imwrite(face{i - 2, j - 2}, [fi(j).folder '\' fileName]);
        if num == 1
            [Len, Wid] = size(face{i - 2, j - 2});
        end
        AllData(1: Len * Wid, num) = reshape(face{i - 2, j - 2}, ...
            [Len * Wid, 1]);
        LabelList(1, num) = i-2;
        % imshow(face{i - 2, j - 2});
    end
end

[W, Y] = KLTransform(AllData' * AllData, 10000);

U = AllData * (Y .* (1./sqrt(W')));

for i = 1 : length(U)
    I = reshape(U(:, i), [Len, Wid]);
    figure(), imshow(I);
    fileName = sprintf('p%d.png', i);
    imwrite(I, fileName);
    if sum(W(1: i)) / sum(W) > 0.97
        break;
    end
end

Acc = kFoldTest([AllData; LabelList], @FaceClassify, [2, 4, 6, 8, 10]);
Acc = cell2mat(Acc);
averAcc = sum(Acc, 2)/size(Acc, 2);



function [l, U] = KLTransform( OriginX, e )
%========================================================
% function [U, l] = KLTransform( OriginX ):K-L变换
% 输入参数:OriginX  进行K-L变化的矩阵,要为方阵
%          e  变换后特征值占据的比例
% 输出参数:l  特征值向量
%          U  特征值向量对应的特征矩阵
% 编程环境 MATLAB R2017a
% Date:2018/11/1
%========================================================

[UU, ll] = eig(OriginX);
ll = diag(ll)';

for i = 1 : length(ll)
    for j = i+1 : length(ll)
        if ll(i) < ll(j)
            temp = ll(i);
            ll(i) = ll(j);
            ll(j) = temp;
            temp = UU(:, i);
            UU(:, i) = UU(:, j);
            UU(:, j) = temp;
        end
    end
end

% for i = 1 : length(ll)
%     if ~ (sum(ll(1: i)) / sum(ll) < e)
%         l = ll(1: i);
%         U = UU(:, 1: i);
%         break;
%     end
% end
l = ll;
U = UU;

end

 

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值