Halcom 发表于 2018-1-9 22:23:13

基于PCA和奇异值分解SVD的人脸识别

基于PCA和奇异值分解SVD的人脸识别
视频链接:https://pan.baidu.com/s/1pMCsJFl
录制的视频是算法底层原理讲解,底层代码实现,方便大家真正掌握算法实质,开发出更加出色的算法。录制视频的初衷是:避免读者朋友利用大把时间学习已有常见算法,本系列视频旨在让读者朋友快速深入了解这些常见算法原理,有更多的时间去研究更加高大上算法(价值)。

具体链接在halcom.cn论坛,联系人QQ:3283892722
该论坛是一个学习交流平台,我会逐一的和大家分享学习。
欢迎大家录制视频,并提交给我,我来设置视频,你可在论坛进行打赏分享。
视频专用播放器:http://halcom.cn/forum.php?mod=viewthread&tid=258&extra=page%3D1

运行环境:win7+32bit+matlab2014a

       SVD分解提取图像的主要成分,主要根据图像的奇异值相关,一般根据图像的熵来进行选取SVD的奇异值个数,根据选择的奇异值k值个数,再进行PCA分析。       矩阵分解后较大的奇异值代表了原矩阵的主要信息,而较小的奇异值反映其细节信息,根据奇异值的这一性质,通过选取较大的k个奇异值组成新的成分集Skxk。就可以在误差允许范围内近似还原矩阵的主要信息:Imxn = Umxk* Skxk * Vkxn   (1)      因为奇异值从大到小依次排列,所以选取的k个奇异值即为前k个奇异值。      据奇异值分解重建背景的具体步骤如下:1)对原图像I的像素矩阵进行SVD处理,计算正交阵U和V、奇异值矩阵S;2)保留S中选取的k个用于重建背景的有效奇异值,其余置零,得到新奇异值矩阵S;3)根据得到的新奇异值矩阵S和式(1)进行背景重建,得到重建的背景。4)原图像与背景图像的差则就是无效成分;      采用最大熵算法确定奇异值个数:
基于最大熵的有效奇异值分解算法,能够较好的滤除图像椒盐噪点,使得图像变得更加平滑。clc,clear,close all
warning off
path = './ORL92112/bmp/';
if(exist('ORL92112.mat'))
    load('ORL92112.mat')
else
    k1 = 1; k2=1;
    for i=1:40
      paths = ;
      for j=1:10
            im = imread();
            if(mod(j,2))% train
                trainImages2D(:,:,k1) = im;
                trainImages1D(:,k1) = im(:);
                trainLabels(k1) = i;
                k1=k1+1;
            else      % test
                testImages2D(:,:,k2) = im;
                testImages1D(:,k2) = im(:);
                testLabels(k2) = i;
                k2=k2+1;
            end
      end
    end
    save ORL92112.mat trainImages2D trainImages1D trainLabels testImages2D testImages1D testLabels
end
%% SVD图像分解计算
% 测试一张图像
TestImage = testImages2D(:,:,2);% 选择一张图像
= svd( double(TestImage) );
k = 50;% 前k个奇异值
for i=k:min(size(S,1), size(S,2))
    S(i,i) = 0;
end
SVDImage = uint8( U*S*V' );
ErrImage = TestImage-SVDImage;
% figure,
% subplot(311), imshow(TestImage,[])
% subplot(312), imshow(SVDImage,[])
% subplot(313), imshow(ErrImage,[])

%% 最大熵
= svd( double(TestImage) );
lamda = diag(S);% 奇异值
for k=1:min(size(S,1), size(S,2))-2
    pB= sum( lamda(1:k) ) ./ sum(lamda);
    pE = 1-pB;
    Xk = -pB*log(pB+eps);
    Yk = -pE*log(pE+eps);
    Hk(k) = (Xk+Yk)./(Xk.^2+Yk.^2+eps);
end
% 首尾两点直线
x1 = 1;         y1 = Hk(1);
x2 = length(Hk);y2 = Hk(end);
kline = (y2-y1)./(x2-x1+eps);
for i=1:length(Hk)
    dist(i) = abs( kline*(i-x1)+y1-Hk(i) )./ sqrt(kline^2+1);
end
= max(dist);
figure,
plot(Hk,'b.-','linewidth',2)
hold on
plot(,,'r-');
plot(indexb, Hk(indexb), 'ro')
hold off;
xlabel('奇异值个数'); ylabel('熵值');

% 测试一张图像
TestImage = testImages2D(:,:,2);% 选择一张图像
= svd( double(TestImage) );
k = indexb;% 前k个奇异值
for i=k:min(size(S,1), size(S,2))
    S(i,i) = 0;
end
SVDImage = uint8( U*S*V' );
ErrImage = TestImage-SVDImage;
figure,
subplot(311), imshow(TestImage,[])
subplot(312), imshow(SVDImage,[])
subplot(313), imshow(ErrImage,[])

%% SVD+PCA
for i=1:size(trainImages2D, 3)
    im = trainImages2D(:,:,i);
    = SVD_entropy(im);
    trainImages1D_SVD(:,i) = SVDImage(:);
end
%% 特征脸计算
numEigs = 199;   % 特征向量个数
= EigenfaceCore(trainImages1D_SVD, numEigs);
%% 测试图像
TestImage = testImages2D(:,:, 3);% 选择一张图像
= SVD_entropy(TestImage);
Recognized_index = Face_Recognition(TestImage_SVD, meanFace, WhiteFace, Eigenfaces);
SelectedImage = trainImages2D(:,:,Recognized_index);
figure,
subplot(121),imshow(TestImage,[]); title('测试图像')
subplot(122),imshow(SelectedImage,[]); title('识别匹配图像')
%% 遍历
for i=1:size(testImages2D,3)
    TestImage = testImages2D(:,:, i);% 选择一张图像
    = SVD_entropy(TestImage);
    Recognized_index = Face_Recognition(TestImage_SVD, meanFace, WhiteFace, Eigenfaces);
    testSimu(1,i) = Recognized_index;
end
accuracy = AccCompute( testSimu, testLabels );
disp(['测试精度:',num2str(accuracy)])程序识别精度:0.9









页: [1]
查看完整版本: 基于PCA和奇异值分解SVD的人脸识别