最近看到一篇介紹利用「主成份分析實現人臉識別」的matlab應用實例。數據庫
學習了一遍,對主成份分析和圖像識別有了一個概念性的認識。api
這個例子多是最簡單的人臉識別例子了,暫且不考慮實用性,單單起到認識和了解主成份分析法和圖像識別的做用。less
主成分分析法是將原先較多的關聯性較強的變量變換爲數量較少的互不相關的少數幾個綜合變量的過程和方法ide
圖像識別,尤爲是人臉識別不太可能使用點對點的像素比較實現,某些統一格式的大頭照片也會存在瞳距等天然誤差,函數
所以必須避免直接圖片比較。學習
下面matlab程序進行學習註釋,但願能幫助記憶。同時增強交流。測試
程序使用的人臉庫來自Essex大學的人臉數據庫的face94部分。選擇了10我的,每人選擇3張照片。1張放入測試集合。ui
2張放入訓練集合。照片比較理想化,綠色背景的大頭照片,表情略有不一樣,光照均勻。idea
程序的連接以下:spa
http://www.mathworks.com/matlabcentral/fileexchange/17032-pca-based-face-recognition-system/all_files
內部包含的文件以下
紅色的文件是主程序,綠色的是測試集合,藍色的是訓練集合。
license.txt PCA_based Face Recognition System/CreateDatabase.m PCA_based Face Recognition System/EigenfaceCore.m PCA_based Face Recognition System/example.m PCA_based Face Recognition System/Readme.txt PCA_based Face Recognition System/Recognition.m PCA_based Face Recognition System/TestDatabase/1.jpg PCA_based Face Recognition System/TestDatabase/10.jpg PCA_based Face Recognition System/TestDatabase/2.jpg PCA_based Face Recognition System/TestDatabase/3.jpg PCA_based Face Recognition System/TestDatabase/4.jpg PCA_based Face Recognition System/TestDatabase/5.jpg PCA_based Face Recognition System/TestDatabase/6.jpg PCA_based Face Recognition System/TestDatabase/7.jpg PCA_based Face Recognition System/TestDatabase/8.jpg PCA_based Face Recognition System/TestDatabase/9.jpg PCA_based Face Recognition System/TrainDatabase/1.jpg PCA_based Face Recognition System/TrainDatabase/10.jpg PCA_based Face Recognition System/TrainDatabase/11.jpg PCA_based Face Recognition System/TrainDatabase/12.jpg PCA_based Face Recognition System/TrainDatabase/13.jpg PCA_based Face Recognition System/TrainDatabase/14.jpg PCA_based Face Recognition System/TrainDatabase/15.jpg PCA_based Face Recognition System/TrainDatabase/16.jpg PCA_based Face Recognition System/TrainDatabase/17.jpg PCA_based Face Recognition System/TrainDatabase/18.jpg PCA_based Face Recognition System/TrainDatabase/19.jpg PCA_based Face Recognition System/TrainDatabase/2.jpg PCA_based Face Recognition System/TrainDatabase/20.jpg PCA_based Face Recognition System/TrainDatabase/3.jpg PCA_based Face Recognition System/TrainDatabase/4.jpg PCA_based Face Recognition System/TrainDatabase/5.jpg PCA_based Face Recognition System/TrainDatabase/6.jpg PCA_based Face Recognition System/TrainDatabase/7.jpg PCA_based Face Recognition System/TrainDatabase/8.jpg PCA_based Face Recognition System/TrainDatabase/9.jpg
訓練集合照片
10我的的訓練集合照片差異是比較大的,表情、頭部的位置都不相同。
測試集合照片 的差異也是比較大的,與訓練集合類似度也不大,遠遠達不到利用像素對比實現圖像識別的能力。
主程序包含下面幾個文件
PCA_based Face Recognition System/example.m
用於設定訓練集合目錄、測試集合目錄,連接其他函數。
PCA_based Face Recognition System/CreateDatabas.m
用於將訓練集合照片轉爲灰度照片,而後將照片轉換爲列向量,最後將全部的訓練集合照片造成矩陣
PCA_based Face Recognition System/EigenfaceCore.m
用於對訓練集合矩陣標準化,而後求標準化矩陣的相關矩陣的特徵根和特徵向量。
根據特徵值的貢獻率,選擇大於1的特徵根做爲主成份份量。 組合主成份份量對應的特徵向量爲特徵向量矩陣。
標準化後的訓練集合矩陣與特徵向量矩陣相乘獲得特徵臉核函數。
PCA_based Face Recognition System/Recognition.m
將原始的訓練集合彩色照片與特徵臉核函數相乘,映射訓練集合照片到特徵臉空間中。
將測試照片與特徵臉核函數相乘,映射測試照片到特徵臉空間中。
在特徵臉空間求測試照片與每個訓練集合照片的方差,方差最小的訓練集合照片編號,就是測試照片鑑別結果。
下面對代碼進行註釋
example.m
% A sample script, which shows the usage of functions, included in
% PCA-based face recognition system (Eigenface method)
%
% See also: CREATEDATABASE, EIGENFACECORE, RECOGNITION
% Original version by Amir Hossein Omidvarnia, October 2007
% Email: aomidvar@ece.ut.ac.ir
// 清理運行環境
clear all
clc
close all
// 定義訓練集合、測試集合的位置以及測試照片的編號
% You can customize and fix initial directory paths
TrainDatabasePath = uigetdir('D:\Program Files\MATLAB\R2006a\work', 'Select training database path' );
TestDatabasePath = uigetdir('D:\Program Files\MATLAB\R2006a\work', 'Select test database path');
prompt = {'Enter test image name (a number between 1 to 10):'};
dlg_title = 'Input of PCA-Based Face Recognition System';
num_lines= 1;
def = {'1'};
TestImage = inputdlg(prompt,dlg_title,num_lines,def);
TestImage = strcat(TestDatabasePath,'\',char(TestImage),'.jpg');
// 讀入測試照片
im = imread(TestImage);
// 將訓練集合照片轉換爲灰度的訓練集合矩陣.
T = CreateDatabase(TrainDatabasePath);
// 將灰度的訓練集合矩陣轉換爲特徵臉核函數
[m, A, Eigenfaces] = EigenfaceCore(T);
//將測試照片 訓練集合 利用特徵臉核函數進行鑑別
OutputName = Recognition(TestImage, m, A, Eigenfaces);
//根據鑑別結果從訓練集合中選擇原始照片
SelectedImage = strcat(TrainDatabasePath,'\',OutputName);
SelectedImage = imread(SelectedImage);
//輸出鑑別結果
figure
imshow(im)
title('Test Image');
figure,imshow(SelectedImage);
title('Equivalent Image');
str = strcat('Matched image is : ',OutputName);
disp(str)
CreateDatabas.m
// 定義函數,輸入變量爲訓練集合路徑
function T = CreateDatabase(TrainDatabasePath)
% Align a set of face images (the training set T1, T2, ... , TM )
%
% Description: This function reshapes all 2D images of the training database
% into 1D column vectors. Then, it puts these 1D column vectors in a row to
% construct 2D matrix 'T'.
%
%
% Argument: TrainDatabasePath - Path of the training database
%
% Returns: T - A 2D matrix, containing all 1D image vectors.
% Suppose all P images in the training database
% have the same size of MxN. So the length of 1D
% column vectors is MN and 'T' will be a MNxP 2D matrix.
%
% See also: STRCMP, STRCAT, RESHAPE
% Original version by Amir Hossein Omidvarnia, October 2007
% Email: aomidvar@ece.ut.ac.ir
%%%%%%%%%%%%%%%%%%%%%%%% File management
//獲得訓練集合的文件
TrainFiles = dir(TrainDatabasePath);
Train_Number = 0;
for i = 1:size(TrainFiles,1)
if not(strcmp(TrainFiles(i).name,'.')|strcmp(TrainFiles(i).name,'..')|strcmp(TrainFiles(i).name,'Thumbs.db'))
Train_Number = Train_Number + 1; % Number of all images in the training database
end
end
%%%%%%%%%%%%%%%%%%%%%%%% Construction of 2D matrix from 1D image vectors
// 將訓練集合照片拼接爲矩陣
T = [];
for i = 1 : Train_Number
% I have chosen the name of each image in databases as a corresponding
% number. However, it is not mandatory!
// 拼接訓練集合照片 路徑和文件名
str = int2str(i);
str = strcat('\',str,'.jpg');
% strg = strcat('\',str,'_g.jpg');
str = strcat(TrainDatabasePath,str);
% strg = strcat(TrainDatabasePath,strg);
//讀取訓練照片,並轉爲灰度照片
img = imread(str);
img = rgb2gray(img);
% imwrite(img,strg);
[irow icol] = size(img);
// 將照片轉爲列向量,按照先行再列的順序轉換爲irow*icol行的列向量
temp = reshape(img',irow*icol,1); % Reshaping 2D images into 1D image vectors
//拼接列向量爲矩陣
T = [T temp]; % 'T' grows after each turn
end
EigenfaceCore.m
// 定義函數,輸入爲的訓練集合照片灰度矩陣
輸出m爲訓練集合照片灰度矩陣的行均值的列向量
輸出A爲訓練集合照片灰度矩陣的誤差矩陣
輸出Eigenfaces 爲訓練集合獲得的特徵臉核函數
function [m, A, Eigenfaces] = EigenfaceCore(T)
% Use Principle Component Analysis (PCA) to determine the most
% discriminating features between images of faces.
%
% Description: This function gets a 2D matrix, containing all training image vectors
% and returns 3 outputs which are extracted from training database.
%
% Argument: T - A 2D matrix, containing all 1D image vectors.
% Suppose all P images in the training database
% have the same size of MxN. So the length of 1D
% column vectors is M*N and 'T' will be a MNxP 2D matrix.
%
% Returns: m - (M*Nx1) Mean of the training database
% Eigenfaces - (M*Nx(P-1)) Eigen vectors of the covariance matrix of the training database
% A - (M*NxP) Matrix of centered image vectors
%
% See also: EIG
% Original version by Amir Hossein Omidvarnia, October 2007
% Email: aomidvar@ece.ut.ac.ir
%%%%%%%%%%%%%%%%%%%%%%%% Calculating the mean image
// 求訓練集合灰度照片矩陣的行均值
m = mean(T,2); % Computing the average face image m = (1/P)*sum(Tj's) (j = 1 : P)
Train_Number = size(T,2);
%%%%%%%%%%%%%%%%%%%%%%%% Calculating the deviation of each image from mean image
// 利用行均值求的訓練集合照片灰度矩陣的誤差值。獲得誤差矩陣
A = [];
for i = 1 : Train_Number
temp = double(T(:,i)) - m; % Computing the difference image for each image in the training set Ai = Ti - m
A = [A temp]; % Merging all centered images
% normal1 = reshape(temp,180,200);
% imwrite(normal1',[num2str(i),'_normal.jpg']);
end
%%%%%%%%%%%%%%%%%%%%%%%% Snapshot method of Eigenface methos
% We know from linear algebra theory that for a PxQ matrix, the maximum
% number of non-zero eigenvalues that the matrix can have is min(P-1,Q-1).
% Since the number of training images (P) is usually less than the number
% of pixels (M*N), the most non-zero eigenvalues that can be found are equal
% to P-1. So we can calculate eigenvalues of A'*A (a PxP matrix) instead of
% A*A' (a M*NxM*N matrix). It is clear that the dimensions of A*A' is much
% larger that A'*A. So the dimensionality will decrease.
// 求出誤差矩陣的相關矩陣,以及相關矩陣的特徵值D和特徵向量V
L = A'*A; % L is the surrogate of covariance matrix C=A*A'.
[V D] = eig(L); % Diagonal elements of D are the eigenvalues for both L=A'*A and C=A*A'.
% diag(D)
% V
%%%%%%%%%%%%%%%%%%%%%%%% Sorting and eliminating eigenvalues
% All eigenvalues of matrix L are sorted and those who are less than a
% specified threshold, are eliminated. So the number of non-zero
% eigenvectors may be less than (P-1).
// 選擇大於1的特徵值做爲主成份。提取對應的特徵向量,拼接爲特徵向量矩陣。
L_eig_vec = [];
for i = 1 : size(V,2)
if( D(i,i)>1 )
L_eig_vec = [L_eig_vec V(:,i)];
end
end
% L_eig_vec
%%%%%%%%%%%%%%%%%%%%%%%% Calculating the eigenvectors of covariance matrix 'C'
% Eigenvectors of covariance matrix C (or so-called "Eigenfaces")
% can be recovered from L's eiegnvectors.
// 特徵向量與訓練集合照片誤差矩陣相乘,獲得特徵臉核函數
Eigenfaces = A * L_eig_vec; % A: centered image vectors
% for i = 1 : 19
% temp = Eigenfaces(:,i); % Computing the difference image for each image in the training set Ai = Ti - m
% normal1 = reshape(temp,180,200);
% imwrite(normal1',[num2str(i),'_Eigenfaces.jpg']);
% end
Recognition.m
// 識別函數,輸入爲測試照片、均值向量、誤差矩陣和特徵臉核函數
function OutputName = Recognition(TestImage, m, A, Eigenfaces)
% Recognizing step....
%
% Description: This function compares two faces by projecting the images into facespace and
% measuring the Euclidean distance between them.
%
% Argument: TestImage - Path of the input test image
%
% m - (M*Nx1) Mean of the training
% database, which is output of 'EigenfaceCore' function.
%
% Eigenfaces - (M*Nx(P-1)) Eigen vectors of the
% covariance matrix of the training
% database, which is output of 'EigenfaceCore' function.
%
% A - (M*NxP) Matrix of centered image
% vectors, which is output of 'EigenfaceCore' function.
%
% Returns: OutputName - Name of the recognized image in the training database.
%
% See also: RESHAPE, STRCAT
% Original version by Amir Hossein Omidvarnia, October 2007
% Email: aomidvar@ece.ut.ac.ir
%%%%%%%%%%%%%%%%%%%%%%%% Projecting centered image vectors into facespace
% All centered images are projected into facespace by multiplying in
% Eigenface basis's. Projected vector of each face will be its corresponding
% feature vector.
// 將訓練集合照片映射到特徵臉空間
ProjectedImages = [];
Train_Number = size(Eigenfaces,2);
for i = 1 : Train_Number
temp = Eigenfaces'*A(:,i); % Projection of centered images into facespace
i
temp
ProjectedImages = [ProjectedImages temp];
end
size(ProjectedImages)
% xx = 1:19;
figure
mesh(ProjectedImages)
xlabel('Number of Face');
ylabel('Number of Eigen');
zlabel('value of Eigen');
%%%%%%%%%%%%%%%%%%%%%%%% Extracting the PCA features from test image
// 映射測試照片到特徵臉空間
InputImage = imread(TestImage);
temp = InputImage(:,:,1);
[irow icol] = size(temp);
InImage = reshape(temp',irow*icol,1);
Difference = double(InImage)-m; % Centered test image
ProjectedTestImage = Eigenfaces'*Difference; % Test image feature vector
size(ProjectedTestImage)
figure
plot(ProjectedTestImage)
xlabel('number of eigen')
ylabel('value of eigen')
%%%%%%%%%%%%%%%%%%%%%%%% Calculating Euclidean distances
% Euclidean distances between the projected test image and the projection
% of all centered training images are calculated. Test image is
% supposed to have minimum distance with its corresponding image in the
% training database.
// 求測試照片與訓練集合照片的方差
Euc_dist = [];
figure
for i = 1 : Train_Number
q = ProjectedImages(:,i);
temp = ( norm( ProjectedTestImage - q ) )^2;
Euc_dist = [Euc_dist temp];
end
figure
plot(Euc_dist)
xlabel('number of face')
ylabel('value of variance')
// 方差最小的訓練集合照片就是鑑別結果
[Euc_dist_min , Recognized_index] = min(Euc_dist);OutputName = strcat(int2str(Recognized_index),'.jpg');