PCA for dimensionality reduction
An example using PCA for dimensionality reduction while maintaining an amount of variance.
This program demonstrates how to use OpenCV PCA with a specified amount of variance to retain.
The program takes as input a list of images. The author recommends using the first 15 faces of the AT&T face data set: http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html
Sources:
Contents
Input images
get the list of images
dname = fullfile(mexopencv.root(), 'test', 'att_faces'); if isdir(dname) % NOTE: run facerec_demo.m to download dataset imgList = arrayfun(@(i) fullfile(['s' int2str(i)], '1.pgm'), 1:15, ... 'UniformOutput',false); else dname = fullfile(mexopencv.root(), 'test'); imgList = dir(fullfile(dname, 'left*.jpg')); imgList = {imgList.name}; end imgList = cellfun(@(f) fullfile(dname, f), imgList(:), 'UniformOutput',false); display(imgList)
imgList = 15×1 cell array 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s1\1.pgm' 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s2\1.pgm' 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s3\1.pgm' 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s4\1.pgm' 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s5\1.pgm' 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s6\1.pgm' 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s7\1.pgm' 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s8\1.pgm' 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s9\1.pgm' 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s10\1.pgm' 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s11\1.pgm' 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s12\1.pgm' 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s13\1.pgm' 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s14\1.pgm' 'C:\Users\Amro\Desktop\mexopencv\test\att_faces\s15\1.pgm'
read in the data
images = cellfun(@imread, imgList, 'UniformOutput',false); sz = size(images{1}); assert(numel(images) >= 2, ... ['This demo needs at least 2 images to work. ' ... 'Please add more images to your data set!']); assert(ndims(sz) == 2, 'Expects grayscale images');
preview images
if mexopencv.require('images') montage(cat(4, images{:})); end
PCA
Reshape and stack images into a row Matrix
data = zeros(numel(images), prod(sz)); for i=1:numel(images) data(i,:) = double(images{i}(:)) / 255; end whos data
Name Size Bytes Class Attributes data 15x10304 1236480 double
perform PCA
RET_VAR = 95; pca = cv.PCA(data, 'DataAs','Row', 'RetainedVariance',RET_VAR/100); display(pca)
pca = PCA with properties: id: 7 eigenvectors: [11×10304 double] eigenvalues: [11×1 double] mean: [1×10304 double]
display the "average image"
figure, imshow(reshape(pca.mean, sz), []), title('mean')
Demonstration of the effect of retainedVariance on the first image
% project into the eigenspace, thus the image becomes a "point" img1 = data(1,:); point = pca.project(img1); % re-create the image from the "point" img1R = pca.backProject(point); % reshape from a row vector into image shape img1R = reshape(img1R, sz); % re-scale for displaying purposes if true img1R = cv.normalize(img1R, ... 'NormType','MinMax', 'Alpha',0, 'Beta',255, 'DType','uint8'); else img1R = (img1R - min(img1R(:))) ./ (max(img1R(:)) - min(img1R(:))); img1R = uint8(img1R * 255); end % display result figure subplot(121), imshow(reshape(img1,sz)), title('Image') subplot(122), imshow(img1R), title('Reconstruction') xlabel({sprintf('Retained Variance: %d%%',RET_VAR); sprintf('# of PCs: %d', size(pca.eigenvectors,1))})