% svdDemo: Using the SVD for encoding images.
%
% This file needs the mat-file wbarb.mat, which is included on the CS
% department's Matlab installations, but I don't know whether it is included
% with student versions.  Alternatively, you can substitute any other
% reasonably sized (eg ~256^2) black & white image that has not had previous
% compression applied (eg tiff or png formats, not jpg or gif).

% Ian Mitchell for CPSC 532M, 3/18/08.

% Load the image file.  If you don't have access to wbarb.mat, then load
% your image into variable X and the appropriate colormap into variable
% map.
load wbarb

% Show the original image.
figure;
image(X);  
colormap(map);  
axis image; 
title('Original');

% SVD decomposition.  For larger images, this may take a lot of time.
[ u, s, v ] = svd(X);

% Get the singular values in a vector.
ds = diag(s);
% Look at them.  Notice how quickly they decline in magnitude.
figure;
plot(ds);
axis tight;
title('Singular values');
xlabel('Index');
ylabel('Singular value');

% How many singular values do you wish to look at?
d = 50;

% Now let's look compressing the image by taking only the leading
% singular values.  In practice, if you wish to compress you will keep
% only the appropriate columns of u and v as well.
figure;
for i = 1 : d
  clf;
  image(u(:,1:i) * diag(ds(1:i)) * v(:,1:i)');
  colormap(map);
  axis image
  title([ 'Keeping only ' num2str(i) ' leading singular values' ]);
  pause;
end


% Finally, let's look at the basis functions associated with those singular
% values.  We'll normalize all basis functions by multiplying by the largest
% singular value.
figure;
for i = 1 : d
  clf;
  image(u(:,i) * ds(1) * v(:,i)');
  colormap(map);
  axis image;
  title([ 'Basis function for singular value ' num2str(i) ]);
  pause;
end

