How do you reconstruct a test image from eigenfaces generated from Matlab pca function

24 ビュー (過去 30 日間)
Hi All, I have been trying to reconstruct a test image from the eigenvectors generated from the pca function, however the reconstructed image is different from the test image (see figure). The test image is simply one of the images used in the training set. I also tried obtaining the eigenvectors using the cov and eig functions but I still end up with the same problem. I need to use the pca function and will appreciate any help on how to obtain the eigenvectors from its output.
Find the code below. I have also attached a zip file containing the matlab code and images I used. Thanks in anticipation.
M = 10; % number of images
for n=1:M
im = imread(strcat(num2str(n),'.jpg')); %read image
im = im2double(rgb2gray(im)); % convert image to gray scale and then to double precision
[r,c] = size(im); % get number of rows and columns in image
I(:,n) = im(:); % convert image to vector and store as column in matrix I
end
% calculate mean image
I_mean = mean(I,2);
% subtract mean image from the set of images
I_shifted = I-repmat(I_mean,1,M);
%perform PCA. Matrix I was used as input instead of I_shifted because Matlab documentation states that pca function centers the data
[coeff,score,latent,~,explained,mu] = pca(I);
%calculate eigenfaces
eigFaces = I_shifted*coeff;
% put eigenface in array and display
ef = [];
for n = 1:M
temp = reshape(eigFaces(:,n),r,c);
temp = histeq(temp,255);
ef = [ef temp];
end
figure;
imshow(ef,'Initialmagnification','fit');
title('Eigenfaces');
% load one of the training images to test reconstruction
im = im2double(rgb2gray(imread('1.jpg'))); % convert to gray and then to double
I_test = im(:); % convert image to vector
I_test = I_test-I_mean; % subtract mean images
%calculate weights of test image
I_test_weights = zeros(M,1);
for jj = 1:M
I_test_weights(jj,1) = dot(I_test,eigFaces(:,jj));
end
% reconstruct test image
I_recon = I_mean + eigFaces*I_test_weights;
%reshape reconstructed test image
I_recon = reshape(I_recon, r,c);
%display original and reconstructed test image
figure
subplot(1,2,1);
imshow(im);
title('Original test image');
subplot(1,2,2)
imshow(I_recon);
title('Reconstructed test image');
  1 件のコメント
Ala Harb
Ala Harb 2022 年 2 月 3 日
編集済み: Ala Harb 2022 年 2 月 3 日
You need to convert "I_recon" from "double" to "unit8" .. You can use "mat2gray()" function, which will scale your image values to the range (0-255).
Try out this line before displaying the reconstructed test image !
I_recon = uint8(255 * mat2gray(I_recon));

サインインしてコメントする。

採用された回答

Faiz Gouri
Faiz Gouri 2017 年 8 月 17 日
See this Wikipedia page for finding the eignevalues and vectors from the covariance matrix
Also, check out the blog here that perform image reconstruction using pca which uses the steps and formula used from the above link.
There is one MATLAB file exchange program too that recognizes a face from a database of human faces using PCA. You can find the link here
  1 件のコメント
Iktech
Iktech 2017 年 8 月 19 日
編集済み: Iktech 2017 年 8 月 19 日
Hi Faiz, Thanks for the links they were really helpful but I have some few questions. The MATLAB program from the blog you mentioned and that from MATLAB file exchange give different sets of eigenfaces for the same set of images. The program from the blog used MATLAB princomp function while that from the file exchange used covariance matrix. However, only the eigenfaces from the blog MATLAB code was able to reconstruct the test image. Does this mean that the set of eigenfaces generated from the covariance matrix cannot be used to reconstruct a test image or is the file exchange program wrongly written?

サインインしてコメントする。

その他の回答 (2 件)

William MacTurk
William MacTurk 2018 年 12 月 10 日
I'm working on an assignment for using pca/eigenfaces to reconstruct images, and I have it working. It can reconstruct both test and train images. I recognize the problem with your image - it took me a while to figure it out. In my case, what did the trick was just converting the image array to uint8 type (instead of double) before displaying the image. My input images were all .pgm format, though, so they were read in as uint8 arrays - not sure if that's also the case in your implementation. Anyway, give it a shot, hopefully it can help. Just add the lines
I_recon = uint8(I_recon);
im = uint8(im);
right before your first figure command.
  2 件のコメント
Iktech
Iktech 2018 年 12 月 22 日
Hi William,
Thanks for your suggestion but I tried it and it didn't work.
Ala Harb
Ala Harb 2022 年 2 月 3 日
Try this one !
I_recon = uint8(255 * mat2gray(I_recon));

サインインしてコメントする。


ABHILASH SINGH
ABHILASH SINGH 2019 年 11 月 8 日

カテゴリ

Help Center および File ExchangeDimensionality Reduction and Feature Extraction についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by