| 基于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)原图像与背景图像的差则就是无效成分;采用最大熵算法确定奇异值个数: 
 基于最大熵的有效奇异值分解算法,能够较好的滤除图像椒盐噪点,使得图像变得更加平滑。 程序识别精度:0.9复制代码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 = [path, 's', num2str(i),'/'];
        for j=1:10
            im = imread([paths, num2str(j), '.BMP']);
            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);  % 选择一张图像
[U,S,V] = 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,[])
%% 最大熵
[U,S,V] = 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
[indexa,indexb] = max(dist);
figure,
plot(Hk,'b.-','linewidth',2)
hold on
plot([x1,x2],[y1,y2],'r-');
plot(indexb, Hk(indexb), 'ro')
hold off;
xlabel('奇异值个数'); ylabel('熵值');
% 测试一张图像
TestImage = testImages2D(:,:,2);  % 选择一张图像
[U,S,V] = 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);
    [SVDImage, ErrImage] = SVD_entropy(im);
    trainImages1D_SVD(:,i) = SVDImage(:);
end
%% 特征脸计算
numEigs = 199;   % 特征向量个数
[meanFace, WhiteFace, Eigenfaces] = EigenfaceCore(trainImages1D_SVD, numEigs);
%% 测试图像
TestImage = testImages2D(:,:, 3);  % 选择一张图像
[TestImage_SVD, ErrImage] = 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);  % 选择一张图像
    [TestImage_SVD, ErrImage] = 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)])
 
 
 
 
 
 |